Saturday, September 19, 2015

CGAffineTransformMakeRotation - Create a horizontal table programmatically

This post has been updated with Xcode 7.3 (Swift 2.2) on April 6, 2016.

1. Edit ViewController.swift as:

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var tableView : UITableView!
    //Table cell background color
    let colorArray = [UIColor.lightGrayColor(), UIColor.darkGrayColor(), UIColor.yellowColor(), UIColor.cyanColor(), UIColor.purpleColor()]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let frame = CGRectMake(0, view.bounds.height/2, view.bounds.width, view.bounds.height/2)
        //A more correct way is to set the frame 
        //as CGRectMake(0, view.bounds.height/2, 
        //view.bounds.height/2view.bounds.width) here,
        //i.e. swap the width/height values
        //before rotation.
        tableView = UITableView(frame: frame)
        tableView.delegate = self
        tableView.dataSource = self
        
        //Remove gaps at margins #1
        if tableView.respondsToSelector(Selector("separatorInset")) {
            tableView.separatorInset = UIEdgeInsetsZero;
        }
        
        if tableView.respondsToSelector(Selector("layoutMargins")) {
            tableView.layoutMargins = UIEdgeInsetsZero;

        }
        
        tableView.transform = CGAffineTransformMakeRotation(-CGFloat(M_PI_2))

        //Set the frame size again after rotation.
        tableView.frame = frame
        view.addSubview(tableView)
    }
    
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "myIdentifier")
        
        cell.textLabel?.text = "Cell #\(indexPath.row)"
        cell.detailTextLabel?.text = "Subtitle"
        cell.backgroundColor = colorArray[indexPath.row]
        cell.contentView.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2))
        
        //Remove gaps at margins #2
        if cell.respondsToSelector(Selector("separatorInset")) {
            cell.separatorInset = UIEdgeInsetsZero;
        }
        
        if cell.respondsToSelector(Selector("preservesSuperviewLayoutMargins")) {
            cell.preservesSuperviewLayoutMargins = false;
        }
        
        if cell.respondsToSelector(Selector("layoutMargins")) {
            cell.layoutMargins = UIEdgeInsetsZero;
        }
        
        return cell

    }
    
    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat{
        return view.bounds.width/3
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

2. Run the iOS simulator to get the result:


Thursday, September 17, 2015

Pass parameters / strings between view controllers programmatically (without using storyboard segues)

1. Create a new file called MyClass.swift as:

class MyClass {
    var string1 : String = ""
    var string2 : String = ""
    static let myInstance = MyClass()

}

2. Modify ViewController.swift as:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = UIColor.cyanColor()
        
        let myLabel = UILabel(frame: CGRectMake(50, 100, 300, 20))
        myLabel.text = "ViewController"
        view.addSubview(myLabel)
        
        let myButton = UIButton(frame: CGRectMake(50, 200, 100, 20))
        myButton.addTarget(self, action: "btnPressed:", forControlEvents: UIControlEvents.TouchUpInside)
        myButton.setTitle("Button", forState: UIControlState.Normal)
        myButton.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        view.addSubview(myButton)
    }
    
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        
        let myLabelFrom = UILabel(frame: CGRectMake(50, 150, 300, 20))
        myLabelFrom.text = "From 2nd VC:\(MyClass.myInstance.string2)"
        myLabelFrom.tag = 50
        view.addSubview(myLabelFrom)
    }
    
    func btnPressed(sender: UIButton){
        //Remove myLabelFrom label because it will be drawn again in viewWillAppear()
        view.viewWithTag(50)?.removeFromSuperview()
        
        //Set the string to be passed to the second view controller.
        MyClass.myInstance.string1 = "String from VC"
        
        let secondVC = SecondViewController()
        
        //Set view controller transition animation style
        secondVC.modalTransitionStyle = UIModalTransitionStyle.CoverVertical
        self.presentViewController(secondVC, animated: true, completion: nil)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

3. Create a new file called SecondViewController.swift as:

import UIKit

class SecondViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = UIColor.yellowColor()
        
        let myLabelSecond = UILabel(frame: CGRectMake(70, 150, 300, 20))
        myLabelSecond.text = "SecondViewController:"
        view.addSubview(myLabelSecond)
        let myLabelSecondFrom = UILabel(frame: CGRectMake(70, 200, 300, 20))
        myLabelSecondFrom.text = "From VC:\(MyClass.myInstance.string1)"
        view.addSubview(myLabelSecondFrom)
        
        let myButtonSecond = UIButton(frame: CGRectMake(70, 250, 100, 20))
        myButtonSecond.addTarget(self, action: "btnPressedSecond:", forControlEvents: UIControlEvents.TouchUpInside)
        myButtonSecond.setTitle("Back", forState: UIControlState.Normal)
        myButtonSecond.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        view.addSubview(myButtonSecond)
    }

    func btnPressedSecond(sender: UIButton){
        //Set the string to be passed to the original view controller.
        MyClass.myInstance.string2 = "String from 2nd VC"
        dismissViewControllerAnimated(true, completion: nil)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

Run the iOS simulator and the first view controller is shown as:


Press 'Button' and the second view controller with yellow background is shown as:


 After pressing the 'Back' button, the screen returns to the first view controller. The string from the second VC is now displayed.


Tuesday, September 15, 2015

UITextField - Create a textfield programmatically

Update - July 12, 2017 -  Xcode 8.3.3 & Swift 3.1
Update - October 13, 2015
1. Change the background color for various conditions.
2. Hide the keyboard while touching outside the text field.

Edit the ViewController.swift file as:


Update - July 12, 2017 -  Xcode 8.3.3 & Swift 3.1

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {
    
    var textField : UITextField!
    var label : UILabel!
    let str : String = "You have entered: "
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Color #1 - Initial color
        view.backgroundColor = UIColor.yellow
        
        let placeholder = NSAttributedString(string: "Enter here", attributes: [NSForegroundColorAttributeName: UIColor.lightGray])
        
        textField = UITextField(frame: CGRect(x: 50, y: 100, width: 200, height: 20))
        
        textField.attributedPlaceholder = placeholder
        textField.textColor = UIColor.black
        textField.delegate = self
        textField.borderStyle = UITextBorderStyle.roundedRect
        textField.clearsOnBeginEditing = true
        view.addSubview(textField)
        
        label = UILabel(frame: CGRect(x: 50, y: 200, width: 200, height: 20))
        label.text = str
        view.addSubview(label)
    }
    
    func textFieldDidBeginEditing(_ textField: UITextField) {
        //Color #2 - While selecting the text field
        view.backgroundColor = UIColor.purple
    }
    
    func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        
        //Color #3 - While touching outside the textField.
        view.backgroundColor = UIColor.cyan
        
        //Hide the keyboard
        textField.resignFirstResponder()
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        
        //Display the result.
        label.text = str+textField.text!
        
        //Color #4 - After pressing the return button
        view.backgroundColor = UIColor.orange
        textField.resignFirstResponder() //Hide the keyboard
        return true
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

Update - October 13, 2015

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    var textField : UITextField!
    var label : UILabel!
    let str : String = "You have entered:"
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Color #1 - Initial color
        view.backgroundColor = UIColor.yellowColor()
        
        let placeholder = NSAttributedString(string: "Enter here", attributes: [NSForegroundColorAttributeName: UIColor.lightGrayColor()])
        
        textField = UITextField(frame: CGRectMake(50, 100, 200, 20))

        textField.attributedPlaceholder = placeholder
        textField.textColor = UIColor.blackColor()
        textField.delegate = self
        textField.borderStyle = UITextBorderStyle.RoundedRect
        textField.clearsOnBeginEditing = true
        view.addSubview(textField)
        
        label = UILabel(frame: CGRectMake(50, 200, 200, 20))
        label.text = str
        view.addSubview(label)
    }
    
    func textFieldDidBeginEditing(textField: UITextField) {
        
        //Color #2 - While selecting the text field
        view.backgroundColorUIColor.purpleColor()
    }
    
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        
        //Color #3 - While touching outside the textField.
        view.backgroundColor = UIColor.cyanColor()
        
        //Hide the keyboard
        textField.resignFirstResponder()
    }

    func textFieldShouldReturn(textField: UITextField) -> Bool {
        
        //Display the result.
        label.text = str+textField.text
        
        //Color #4 - After pressing the return button
        view.backgroundColorUIColor.orangeColor()
        
        textField.resignFirstResponder() //Hide the keyboard
        return true
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

While editing the text field:



The result after hitting the return key:


UITableViewCell - Create Custom Prototype Table Cell in UITableView Programmatically (without using the Storyboard)

Update: July 13, 2017 - Xcode 8.3.3 + Swift 3.1
Original Post: September 15, 2015
===============

Update: July 13, 2017 - Xcode 8.3.3 + Swift 3.1

1. Create a new file called MyTableViewCell.swift as:


import UIKit

class MyTableViewCell: UITableViewCell {
    
    var myLabel1: UILabel!
    var myLabel2: UILabel!
    var myButton1 : UIButton!
    var myButton2 : UIButton!
    
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:)")
    }
    
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        let gap : CGFloat = 10
        let labelHeight: CGFloat = 30
        let labelWidth: CGFloat = 150
        let lineGap : CGFloat = 5
        let label2Y : CGFloat = gap + labelHeight + lineGap
        let imageSize : CGFloat = 30
        
        myLabel1 = UILabel()
        myLabel1.frame = CGRect(x: gap, y: gap, width: labelWidth, height: labelHeight)
        myLabel1.textColor = UIColor.black
        contentView.addSubview(myLabel1)
        
        myLabel2 = UILabel()
        myLabel2.frame = CGRect(x: gap, y: label2Y, width: labelWidth, height: labelHeight)
        myLabel2.textColor = UIColor.black
        contentView.addSubview(myLabel2)
        
        myButton1 = UIButton()
        myButton1.frame = CGRect(x: bounds.width-imageSize - gap, y: gap, width: imageSize, height: imageSize)
        myButton1.setImage(UIImage(named: "browser.png"), for: UIControlState.normal)
        contentView.addSubview(myButton1)
        
        myButton2 = UIButton()
        myButton2.frame = CGRect(x: bounds.width-imageSize - gap, y: label2Y, width: imageSize, height: imageSize)
        myButton2.setImage(UIImage(named: "telephone.png"), for: UIControlState.normal)
        contentView.addSubview(myButton2)
    }

}


2. Modify ViewController.swift as:


import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    var myArray = ["AAA", "BBB", "CCC", "DDD"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let tableView = UITableView(frame: view.bounds, style: UITableViewStyle.grouped)
        tableView.delegate = self
        tableView.dataSource = self
        view.addSubview(tableView)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 85
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myArray.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = MyTableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "myIdentifier")
        cell.myLabel1.text = myArray[indexPath.row]
        cell.myLabel2.text = "\(indexPath.row)"
        cell.myButton1.addTarget(self, action: #selector(pressedBrowser(sender: )), for: UIControlEvents.touchUpInside)
        cell.myButton2.addTarget(self, action: #selector(pressedTelephone(sender: )), for: UIControlEvents.touchUpInside)
        return cell
    }
    
    func pressedBrowser(sender: UIButton) {
        print("pressedBrowser")
    }
    
    func pressedTelephone(sender: UIButton) {
        print("pressedTelephone")
    }
}
3. The result is:



Original Post: September 15, 2015


1. Create a new file called MyTableViewCell.swift as:

import UIKit

class MyTableViewCell: UITableViewCell {

    var myLabel1: UILabel!
    var myLabel2: UILabel!
    var myButton1 : UIButton!
    var myButton2 : UIButton!
    
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:)")
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        let gap : CGFloat = 10
        let labelHeight: CGFloat = 30
        let labelWidth: CGFloat = 150
        let lineGap : CGFloat = 5
        let label2Y : CGFloat = gap + labelHeight + lineGap
        let imageSize : CGFloat = 30
        
        myLabel1 = UILabel()
        myLabel1.frame = CGRectMake(gap, gap, labelWidth, labelHeight)
        myLabel1.textColor = UIColor.blackColor()
        contentView.addSubview(myLabel1)
        
        myLabel2 = UILabel()
        myLabel2.frame = CGRectMake(gap, label2Y, labelWidth, labelHeight)
        myLabel2.textColor = UIColor.blackColor()
        contentView.addSubview(myLabel2)
        
        myButton1 = UIButton()
        myButton1.frame = CGRectMake(bounds.width-imageSize - gap, gap, imageSize, imageSize)
        myButton1.setImage(UIImage(named: "browser.png"), forState: UIControlState.Normal)
        contentView.addSubview(myButton1)
        
        myButton2 = UIButton()
        myButton2.frame = CGRectMake(bounds.width-imageSize - gap, label2Y, imageSize, imageSize)
        myButton2.setImage(UIImage(named: "telephone.png"), forState: UIControlState.Normal)
        contentView.addSubview(myButton2)
    }

}

2. Modify ViewController.swift as:

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    var myArray = ["AAA", "BBB", "CCC", "DDD"]

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let tableView = UITableView(frame: view.bounds, style: UITableViewStyle.Grouped)
        tableView.delegate = self
        tableView.dataSource = self
        view.addSubview(tableView)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return 85
    }
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myArray.count
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        var cell = MyTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "myIdentifier")
        cell.myLabel1.text = myArray[indexPath.row]
        cell.myLabel2.text = "\(indexPath.row)"
        cell.myButton1.addTarget(self, action: "pressedBrowser:", forControlEvents: UIControlEvents.TouchUpInside)
        cell.myButton2.addTarget(self, action: "pressedTelephone:", forControlEvents: UIControlEvents.TouchUpInside)
        return cell
    }

    func pressedBrowser(sender: UIButton) {
        println("pressedBrowser")
    }
    
    func pressedTelephone(sender: UIButton) {
        println("pressedTelephone")
    }
}

3. The result is:


========================================