Tuesday, September 8, 2015

UINavigationController() - Embed the view controller in a navigation controller programmatically

Update: July 8, 2017 (Swift 3.1 + Xcode 8.3.3)
Original Post: September 15, 2015

This post shows how to embed the view controller in a navigation controller.

Update: July 8, 2017 (Swift 3.1 + Xcode 8.3.3)

1. Modify func application(_ application: UIApplicationdidFinishLaunchingWithOptions...) in AppDelegate.swift:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        
        let nav = UINavigationController()
        let mainWiew = ViewController(nibName: nil, bundle: nil)
        nav.viewControllers = [mainWiew]
        nav.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
        
        UINavigationBar.appearance().barTintColor = UIColor.blue
        UINavigationBar.appearance().tintColor = UIColor.white
        
        //White status font
        UINavigationBar.appearance().barStyle = UIBarStyle.blackTranslucent
        
        self.window!.rootViewController = nav
        self.window?.makeKeyAndVisible()
        
        //Black status background
        let statusBar = UIView()
        statusBar.frame = CGRect(x: 0, y: 0, width: 320, height: 20)
        statusBar.backgroundColor = UIColor.black
        self.window?.rootViewController?.view.addSubview(statusBar)
        
        return true

    }

2. Modify
 ViewController.swift:

import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.title = "My Title"
        
        let statusView = UIView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: 20))
        statusView.backgroundColor = UIColor.black
        view.addSubview(statusView)
        
        let myView = UIView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height))
        myView.backgroundColor = UIColor.white
        view.addSubview(myView)
        
        let barBtn = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.compose, target: self, action: #selector(pressed))
        self.navigationItem.setRightBarButton(barBtn, animated: true)
        
    }
    
    func pressed() {
        print("Pressed")
        
        let newVC = SecondViewController()
        self.navigationController?.pushViewController(newVC, animated: true)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

3. Create a new file called SecondViewController.swift by right-clicking and choosing New File -> iOS -> Cocoa Touch.



Choose the new class as a subclass of UIViewController and name it as . 
import UIKit

class SecondViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let myView = UIView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height))
        myView.backgroundColor = UIColor.white
        view.addSubview(myView)
        
        let myLabel = UILabel(frame: CGRect(x: 50, y: 100, width: 150, height: 20))
        myLabel.text = "Hello"
        view.addSubview(myLabel)
        
        navigationItem.title = "123"
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

The result:



//End of Update: July 8, 2017(Swift 3.1 + Xcode 8.3.3)

Original Post: September 15, 2015

1. Modify AppDelegate.swift:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponderUIApplicationDelegate {

    var window: UIWindow?
    func application(application: UIApplicationdidFinishLaunchingWithOptions launchOptions: [NSObjectAnyObject]?) -> Bool {
        
        var nav = UINavigationController()
        var mainWiew = ViewController(nibName: nil, bundle: nil)
        nav.viewControllers = [mainWiew]
        nav.navigationBar.titleTextAttributes = [NSForegroundColorAttributeNameUIColor.whiteColor()]

        UINavigationBar.appearance().barTintColor = UIColor.blueColor()
        UINavigationBar.appearance().tintColor = UIColor.whiteColor()
        
        //White status font
        UINavigationBar.appearance().barStyle = UIBarStyle.BlackTranslucent

        self.window!.rootViewController = nav
        self.window?.makeKeyAndVisible()
        
        //Black status background
        var statusBar = UIView()
        statusBar.frame = CGRectMake(0, 0, 320, 20)
        statusBar.backgroundColor = UIColor.blackColor()
        self.window?.rootViewController?.view.addSubview(statusBar)

        return true
    }

2. Modify ViewController.swift:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.title = "My Title"
        
        let statusView = UIView(frame: CGRectMake(0, 0, view.bounds.width, 20))
        statusView.backgroundColor = UIColor.blackColor()
        view.addSubview(statusView)
        
        var myView = UIView()
        myView.backgroundColor = UIColor.whiteColor()
        myView.frame = CGRectMake(0, 0, view.bounds.widthview.bounds.height)
        view.addSubview(myView)

        var barBtn = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Compose, target: self, action: "pressed:")
        self.navigationItem.setRightBarButtonItem(barBtn, animated: true)
        
    }
    
    func pressed(sender: UIButton) {
        println("Pressed")
        
        let newVC = SecondViewController()
        self.navigationController?.pushViewController(newVC, animated: true)
    }

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

3. Create a new file called SecondViewController.swift 

import UIKit

class SecondViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        var myView = UIView()
        myView.backgroundColor = UIColor.whiteColor()
        myView.frame = CGRectMake(0, 0, view.bounds.width, view.bounds.height)
        view.addSubview(myView)

        var myLabel = UILabel()
        myLabel.text = "Hello"
        myLabel.frame = CGRectMake(50, 100, 150, 20)
        view.addSubview(myLabel)
        
        navigationItem.title = "123"
    }

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

The result:



After clicking the 'Compose' button:


Sunday, September 6, 2015

Custom button to include both text and image as well as changing background color when selected

Update - September 29, 2016 - Xcode 8.0 and Swift 3.0
Original post - September 6, 2015 - Xcode 6.4 and Swift 1.2

This post is going to create a button with the following features:

1. A button including an image an text.
2. A rounded border around the button.
3. Change the background color when selected.

The result of the button created is:

When the button is selected:

Firstly, create a file called MyClass.swift to change the button background color:

Xcode 8.0 (Swift 3.0)

import UIKit

class MyClass: NSObject {
    
    class myButton : UIButton {
        override var isHighlighted: Bool {
            didSet {
                if (isHighlighted) {
                    self.backgroundColor = UIColor.blue
                } else {
                    self.backgroundColor = UIColor.white
                }
            }
        }
    }

}

=======

Xcode 6.4 (Swift 1.2)

import UIKit

class MyClass: NSObject {
    
    class myButton : UIButton {
        override var highlighted: Bool {
            didSet {
                if (highlighted) {
                    self.backgroundColor = UIColor.blueColor()
                } else {
                    self.backgroundColor = UIColor.whiteColor()
                }
            }
        }
    }

}

Then edit ViewController.swift as below:

Xcode 8.0 (Swift 3.0)

import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let imageSize : CGFloat = 100
        let gap : CGFloat = 10
        let borderSize : CGFloat = 10
        let textHeight : CGFloat = 20
        let buttonWidth : CGFloat = borderSize * 2 + gap * 2 + imageSize
        let buttonHeight : CGFloat = borderSize * 2 + gap * 3 + imageSize + textHeight
        let imageOrigin : CGFloat = borderSize + gap
        let textTop : CGFloat = imageOrigin + imageSize + gap
        let textBottom : CGFloat = borderSize + gap
        let imageBottom : CGFloat = textBottom + textHeight + gap
        
        let myButton = MyClass.myButton()
        myButton.frame = CGRect(x: 0, y: 0, width: buttonWidth, height: buttonHeight)
        myButton.center = view.center
        myButton.addTarget(self, action: #selector(btnPressed), for: UIControlEvents.touchUpInside)
        
        //Border
        myButton.layer.borderColor = UIColor.blue.cgColor
        myButton.layer.borderWidth = borderSize
        myButton.layer.cornerRadius = 20
        
        //Image
        let myImage = UIImage(named: "telephone_blue.png")
        myButton.setImage(myImage, for: UIControlState.normal)
        myButton.setImage(UIImage(named: "telephone_white.png"), for: UIControlState.highlighted)
        myButton.imageEdgeInsets = UIEdgeInsets(top: imageOrigin, left: imageOrigin, bottom: imageBottom, right: imageOrigin)
        
        //Text
        myButton.setTitle("Telephone", for: UIControlState.normal)
        myButton.setTitleColor(UIColor.blue, for: UIControlState.normal)
        myButton.setTitleColor(UIColor.white, for: UIControlState.highlighted)
        myButton.titleEdgeInsets = UIEdgeInsets(top: textTop, left: -myImage!.size.width, bottom: textBottom, right: 0.0)
        
        view.addSubview(myButton)
    }
    
    func btnPressed() {
        print("button pressed!")
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

=======

Xcode 6.4 (Swift 1.2)

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let orignX : CGFloat = 70
        let orignY : CGFloat = 70
        let imageSize : CGFloat = 100
        let gap : CGFloat = 10
        let borderSize : CGFloat = 10
        let textHeight : CGFloat = 20
        let buttonWidth : CGFloat = borderSize * 2 + gap * 2 + imageSize
        let buttonHeight : CGFloat = borderSize * 2 + gap * 3 + imageSize + textHeight
        let imageOrigin : CGFloat = borderSize + gap
        let textTop : CGFloat = imageOrigin + imageSize + gap
        let textBottom : CGFloat = borderSize + gap
        let imageBottom : CGFloat = textBottom + textHeight + gap
        
        let myButton = MyClass.myButton()
        myButton.frame = CGRectMake(orignX, orignY, buttonWidth, buttonHeight)
        myButton.addTarget(self, action: "btnPressed:", forControlEvents: UIControlEvents.TouchUpInside)
        
        //Border
        myButton.layer.borderColor = UIColor.blueColor().CGColor
        myButton.layer.borderWidth = borderSize
        myButton.layer.cornerRadius = 20

        //Image
        let myImage = UIImage(named: "telephone_blue.png")
        myButton.setImage(myImage, forState: UIControlState.Normal)
        myButton.setImage(UIImage(named: "telephone_white.png"), forState: UIControlState.Highlighted)
        myButton.imageEdgeInsets = UIEdgeInsets(top: imageOrigin, left: imageOrigin, bottom: imageBottom, right: imageOrigin)
        
        //Text
        myButton.setTitle("Telephone", forState: UIControlState.Normal)
        myButton.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        myButton.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Highlighted)
        myButton.titleEdgeInsets = UIEdgeInsets(top: textTop, left: -myImage!.size.width, bottom: textBottom, right: 0.0)

        view.addSubview(myButton)
    }
    
    func btnPressed(sender: UIButton!) {
        println("button pressed!")
    }

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