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()
    }
}

Tuesday, August 4, 2015

registerNib - Create UITableView programmatically with a custom XIB file as the prototype cell

1.  Add a new file. Select UITableViewCell as subclass. Select 'Also create XIB file'.

2. Edit the XIB file as the prototype cell.

3. Control-drag the labels to the MyTableViewCell.swift:

import UIKit

class MyTableViewCell: UITableViewCell {

    @IBOutlet weak var myString1: UILabel!
    
    @IBOutlet weak var myString2: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
    

}


4. Complete the file ViewController.swift as below:

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        var myTableView = UITableView(frame: self.view.bounds, style: UITableViewStyle.Plain)
        myTableView.dataSource = self
        myTableView.delegate = self
        
        myTableView.backgroundColor = UIColor.whiteColor()
        
        myTableView.frame = CGRectMake(20, 50, 250, 400)//Optional for table size
        
        myTableView.registerNib(UINib(nibName: "MyTableViewCell", bundle: nil), forCellReuseIdentifier: "myIdentifier")
        
        self.view.addSubview(myTableView)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let myCell = tableView.dequeueReusableCellWithIdentifier("myIdentifier") as! MyTableViewCell
        myCell.myString1.text = "Row \(indexPath.row)"
        myCell.myString2.text = "String \(indexPath.row)"
        return myCell
    }
    

}

5. Run the app and get this result:


Thursday, July 30, 2015

UIActivityIndicatorView - Show an Activity Indicator Programmatically

Update: July 8, 2017 (Swift 3.1 + Xcode 8.3.3)
Original Post: July 30, 2015 (Swift 1 + Xcode 6.4)

Complete the code as below:

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

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let myActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
        myActivityIndicator.center = view.center
        myActivityIndicator.startAnimating()
        view.addSubview(myActivityIndicator)
    }

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

}

Original Post: July 30, 2015 (Swift 1 + Xcode 6.4)

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        var myActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
        myActivityIndicator.center = view.center
        myActivityIndicator.startAnimating()
        view.addSubview(myActivityIndicator)
    }

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

}

The result:

Saturday, July 4, 2015

Create an app with three tabs using the storyboard

This tutorial shows how to create tab bar items with custom icons using the storyboard.

1. Create a new project and select iOS/Application/Tabbed Application template:



2. Create a new file named ThirdViewController.swift and change the content as:

import UIKit

class ThirdViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
    }

}

3. Drag a ViewController to the storyboard. Select the new ViewController and make it as a ThirdViewController class in the Identity Inspector.


4. Drag a label to ThirdViewController in the storyboard. Drag it to the center. Select 'Align' at the bottom right of the interface builder, click for both horizontal and vertical center in container, and select Add 2 Constraints.


5. Control-drag from the Tab Bar Controller to the Third View Controller. Select Relationship Segue/view controllers.


6. Now the Third View Controller is renamed as Item. Select it. Change  Attributes Inspector/View Controller/Title as Third.


7. Select Item under Third/View and change Attributes Inspector/Bar Item/Title as Third.


8. Select 'Preview' as a tool to make three icons with transparent background. Make the size of the icons as 25x25 with BatchImageResizerLite. Drag the icons to the project:


9. Select Tab Bar Item under  First View Controller Scene/First View Controller/View and select an image under Attributes Inspector/Bar Item/Image.
Repeat this process for the Tab Bar Items inside the Second and Third Scenes.


10. Run the app. Try tap on 1, 2, and 3.



Wednesday, July 1, 2015

Display a web page with UIWebView and insert a JavaScript file using stringByEvaluatingJavaScriptFromString

This is a tutorial about inserting JavaScript code into the web page being read.

1. Select the storyboard and disable the Use Auto Layout and Use Size Classes option.


2. Drag a UIWebView to the storyboard.


3. Control-drag the UIWebView to ViewControl.swift

    @IBOutlet weak var myWebView: UIWebView!

4. Create an index.html file in the project:

<HTML>
    <HEAD>
        <TITLE>My Title</TITLE>
    </HEAD>
    <BODY>
        <H2><CENTER>Hello World</CENTER></H2>
    </BODY>
</HTML>

5. Create a JavaScript.js file in the project:


alert('JavaScript!');

6. Complete the ViewController.swift file as below:

import UIKit

class ViewController: UIViewController, UIWebViewDelegate {

    @IBOutlet weak var myWebView: UIWebView!
    override func viewDidLoad() {
        super.viewDidLoad()
        
        var myPath = NSBundle.mainBundle().pathForResource("index", ofType: "html")
        myWebView.delegate = self //For webViewDidFinishLoad to be called
        myWebView.loadRequest(NSURLRequest(URL: NSURL(string: myPath!)!))
    }
    
    func webViewDidFinishLoad(webView: UIWebView) {
        
        let jsPath = NSBundle.mainBundle().pathForResource("JavaScript", ofType: "js")
        let jsContent = NSString(contentsOfFile: jsPath!, encoding: NSUTF8StringEncoding, error: nil) as! String
        
        myWebView.stringByEvaluatingJavaScriptFromString(jsContent)
    }

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

}

7. The alert window:

The HTML file is displayed in UIWebView: