Thursday 10 July 2014

UIPickerView and UIDatePicker demo using Swift

Hi All, hope everyone is exploring/learning Swift. I have created a sample application which uses UIPickerView and UIDatePicker. I thought of sharing with you. Lets see what I did.

I have created a empty project and added a new swift file called "UIPickerViewDemoController" and a xib file "UIPickerViewDemo.xib".


I am going to add two text fields one for picker view and one for date picker.

    @IBOutlet var textField:UITextField

    @IBOutlet var dateTextField:UITextField

Added a Picker View and Date Picker and created outlets for them.

    @IBOutlet var pickerView:UIPickerView

    @IBOutlet var datePicker:UIDatePicker

Have assigned pickers to inputView property of text fields

        textField.inputView = pickerView

        dateTextField.inputView = datePicker

 Corresponding picker will be shown based up on the first responder status. 

Here is how XIB look like :



Here is the complete initialisation code in viewDidLoad method :

    @IBOutlet var pickerView:UIPickerView
    @IBOutlet var textField:UITextField
    
    @IBOutlet var datePicker:UIDatePicker
    @IBOutlet var dateTextField:UITextField
    
    var elements:Array<String>?

    override func viewDidLoad()
    {
        super.viewDidLoad()
        
        self.edgesForExtendedLayout = UIRectEdge.None
        
        self.title = "Picker View"
        
        textField.inputView = pickerView
        
        elements = ["One","Two","Three","Five","Six","Seven","Eight","Nine","Ten"]
        
        dateTextField.inputView = datePicker

    }

Following are the delegate and datasource implementation for picker view :

    func numberOfComponentsInPickerView(pickerView: UIPickerView!) -> Int
    {
        return 1;
    }
    
    func pickerView(pickerView: UIPickerView!, numberOfRowsInComponent component: Int) -> Int
    {
        return elements!.count;
    }
    
    func pickerView(pickerView: UIPickerView!, titleForRow row: Int, forComponent component: Int) -> String
    {
        return elements![row]
    }
    
    func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int)
    {
        textField.text = elements![row]
    }


Following is the valueChanged selector for date picker :

@IBAction func dateValueChanged(sender:UIDatePicker)
    {
        dateTextField.text = sender.date.description
    }

Here is the output :




You can download source code here

Wednesday 11 June 2014

UITableView Demo using Swift

Hi All,  Apple has introduced new programming language called "Swift" and iOS 8. Hope all of you know about this. I have downloaded XCode 6.0 beta from "developer.apple.com" and started playing with it. I have created a UITableView demo and thought of sharing it with you.

I have created a empty application and created new UIViewController subclass "TableViewController" and corresponding xib file called "TableView".


Added code in AppDelegate.swift to create a new navigation controller with TableViewController as root view controller :

        var tableVC : TableViewController = TableViewController(nibName: "TableView", bundle: NSBundle.mainBundle())
        var navVC : UINavigationController = UINavigationController(rootViewController: tableVC)
        

        self.window!.rootViewController = navVC

now, func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool of AppDelegate class will look like below :

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        
        var tableVC : TableViewController = TableViewController(nibName: "TableView", bundle: NSBundle.mainBundle())
        var navVC : UINavigationController = UINavigationController(rootViewController: tableVC)
        
        self.window!.rootViewController = navVC
        self.window!.backgroundColor = UIColor.whiteColor()
        self.window!.makeKeyAndVisible()
        
        return true
    }

In TableViewController class, I took elements as an optional array and implemented UITableViewDatasource methods :

    import UIKit

class TableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
{
    var elements : Array<AnyObject>?
    
    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    override func viewDidLoad()
    {
        super.viewDidLoad()
        
        self.title = "Table View"
        
        elements = ["One","Two","Three","Five","Six","Seven","Eight","Nine","Ten"]
    }
    
    func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int
    {
        return elements!.count;
    }
    
    func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
    {
        var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell!
        
        if cell == nil
        {
            cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
        }
        
        cell.textLabel.text = elements![indexPath.row] as String
        
        return cell
    }
}

Here is the output :



Here is the Source Code.

Tuesday 21 January 2014

Customising or adding subviews to UIAlertView in iOS 7

Hi All, hope everybody is doing good. Today I am planning to discuss about customising alert views in iOS 7. In earlier versions of iOS, we can subclass UIAlertView and add subviews to it by passing addSubview: message. But, in iOS 7 we can't add a sub view to UIAlertView by passing addSubview: message. Even if send message addSubview: message to UIAlertView, there wont be any effect.

I explored different ways to add subviews to UIAlertView in iOS 7 and finally came up with a solution. I have created a single view application and created a subclass of UIAlertView MLKLoadingAlertView.

Added a custom init method as shown below :

Header File :


@interface MLKLoadingAlertView : UIAlertView

- (id)initWithTitle:(NSString *)title;

@end

init method in Implementation File :

- (id)initWithTitle:(NSString *)title
{
    if ( self = [super init] )
    {
        self.title = title;
        self.message = @"\n\n";
        
        [self setDelegate:self];
    }
    
    return self;
}

If you observer initWithTitle method, I have made UIAlertView subclass itself as delegate of UIAlertView. I have implemented following delegate method of UIAlertViewDelegate in MLKLoadingAlertView :


// You can Customise this based on your requirement by adding subviews.
- (void)didPresentAlertView:(UIAlertView *)alertView
{
    NSArray *subviews = [UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController.view.subviews;
    
    if( subviews.count > 1 )
    {
        // iOS while presenting an alertview uses a presening view controller. That controller's view has several subviews. I have picked one
        // subview from it which has frame similar to the alertview frame.
        UIView *presentedView = [subviews objectAtIndex:1];
        
         UIActivityIndicatorView *customActivityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
        [customActivityIndicator startAnimating];
        customActivityIndicator.center = ACTIVITY_INDICATOR_CENTER;
        
        [presentedView addSubview:customActivityIndicator];
    }
}

What I did is, when alert view is presented, I am trying to access alert view via subviews of presentedViewController's view in following way :

[UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController.view.subviews

After getting access to UIAlertView instance, I am adding subviews to it.





I have created an example to demonstrate this and placed code in github. You can download source code form Here

Hope this tutorial helps who ever looking for customising UIAlertView in iOS 7 by adding subviews.

Please feel free to add your comments.