Sunday, October 11, 2015

Open the browser with a URL including Unicode characters 以瀏覽器開啟中文網址

The following example is written with Xcode 6.4. It converts a string with Unicode characters to the NSURL format.

Edit ViewController.swift as below:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let button = UIButton(frame: CGRectMake(100, 100, 100, 20))
        button.setTitle("Press", forState: UIControlState.Normal)
        button.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        button.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)//Set the title color while highlighted
        button.addTarget(self, action: "btnPressed:", forControlEvents: UIControlEvents.TouchUpInside)
        view.addSubview(button)
    }
    
    func btnPressed(sender: UIButton) {
        println("btnPressed")
        
        let string = "https://tw.news.yahoo.com/ios-9-0-1釋出-網友:滑臉書好快喔-083210396.html".stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
        
        let url = NSURL(string: string!)
        UIApplication.sharedApplication().openURL(url!)//Open the URL in the browser.
    }

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

}

After pressing the 'Press' button, the browser is opened with the  URL in Chinese.


Saturday, October 10, 2015

NSString rangeOfString - Search for matching characters in a string

Type these codes in the playground:


let theString = "Hello World$$1234567890" as NSString
let range = theString.rangeOfString("$$")
//The result is:
//range.location = 11
//range.length = 2

let string1 = theString.substringToIndex(range.location)

let string2 = theString.substringFromIndex(range.location+range.length)
//The result is:
//string1 = "Hello World"
//string2 = "1234567890"

Monday, October 5, 2015

UIAlertControllerStyle.ActionSheet - Action Sheet since iOS 8

UIActionSheet is deprecated in iOS 8. To use the ActionSheet, it is required to use UIAlertController with UIAlertControllerStyle.ActionSheet.

Now edit ViewController.swift as:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let myButton = UIButton(frame: CGRectMake(50, 50, 100, 30))
        myButton.setTitle("Press", forState: UIControlState.Normal)
        myButton.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        myButton.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)//Set the title color while highlighted
        myButton.addTarget(self, action: "btnPressed:", forControlEvents: UIControlEvents.TouchUpInside)
        view.addSubview(myButton)
    }
    
    func btnPressed(sender: UIButton) {
        println("btnPressed")
        
        let myController = UIAlertController(title: "My Title", message: "My Message", preferredStyle: UIAlertControllerStyle.ActionSheet)
        myController.addAction(UIAlertAction(title: "Option 1", style: UIAlertActionStyle.Default, handler: { action in
            println("Option 1")
        }))
        myController.addAction(UIAlertAction(title: "Option 2", style: UIAlertActionStyle.Default, handler: { action in
            println("Option 2")
        }))
        myController.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil))
        presentViewController(myController, animated: true, completion: nil)
    }

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

}

The result is:


Sunday, October 4, 2015

NSString substringToIndex - Truncate a string and add some characters

This is how to get the first n characters in a string and add extra "..." string to the output string:

import UIKit

let str = "Hello World This is a long string 1234567890."

var strTemp = str as NSString

//Keep the first 30 characters.
strTemp = strTemp.substringToIndex(30)

strTemp = (strTemp as String) + "..."


println(strTemp)

The result:

Hello World This is a long str...

Thursday, October 1, 2015

stringByReplacingOccurrencesOfString - Replace characters within a string by other characters

Type these codes in the playground:

import UIKit

let str = "Hello##World##123##!!"

var strTemp : String!

strTemp = str.stringByReplacingOccurrencesOfString("##", withString: "\n", options: NSStringCompareOptions.RegularExpressionSearch, range: nil)


println(strTemp)

The result:

Hello
World
123

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.