2015年9月9日 星期三

第 2 個程式:SimpleTableView


專案步驟:

1. UI TableView 元件製作:拖曳 UITableView Control 至 Storyboard
2. 設定 Table View 的 Attribute : prototype cell = 1 (原來的值是 0)
3. 設定 Table View 的 Cell Style : Basic
4. 設定 cell 的識別名稱 Identifier = cell
5. 試 Run
6. 在 code 中加入 Table View 需遵循的 protocol : 
   class ViewController : UIViewController, UITableViewDataSource, 
                          UITableViewDelegate
7. Data 準備 :提供 data
8. Protocol 實作 : delegate
9. 建立 UI 與 Code 的 connect : 將 TableView 此 control 拉至 Outline 的  ViewController
10. 試 Run
11. 刪除 Status Bar
12. 試 Run

開啟新專案:

1. UI TableView 元件製作:拖曳 UITableView Control 至 Storyboard
2. 設定 Table View 的 Attribute : prototype cell = 1 (原來的值是 0)
3. 設定 Table View 的 Cell Style : Basic
4. 設定 cell 的識別名稱 Identifier = cell
5. 試 Run
6. 在 code 中加入 Table View 需遵循的 protocol : class ViewController : UIViewController, UITableViewDataSource, UITableViewDelegate
7. Data 準備 :提供 data 8. Protocol 實作 : delegate
9. 建立 UI 與 Code 的 connect : 將 TableView 此元件拉至 Outline 的 ViewController
顯示 connect to data source 與 data delegate
10. 試 Run
11. 刪除 Status Bar
12. 試 Run
後記: 這程式使用 UITableView 元件,增加 protocol 協定的概念。當遵循此 protocol 時,其方法需實作。 參考: 1. UITableView, https://developer.apple.com/library/prerelease/ios/samplecode/TableMultiSelect/Introduction/Intro.html 2. UITableView Class Reference, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableView_Class/ 3. UITableViewDataSource Class Reference, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/index.html#//apple_ref/occ/intf/UITableViewDataSource
4. UITableViewDelegate Reference Class, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/index.html#//apple_ref/occ/intf/UITableViewDelegate

第 3 個程式: UITableViewController


這裡將 UITableView 改寫為 UITableViewController。此程式需要下列步驟:

1. 刪除 UI 元件 (ViewController)與其相關的 Code (ViewController.swift),這些都是新增 project 的 default 設定。將這些檔案 Move to Trash
2. 新增 UI 元件:拖曳 TableVewController 元件至 Storyboard
3. 指定初始的 Controller : 設定 Is Initial ViewController
4. 新增 Code : 新增一個自訂的 Class
5. 連接 UI 與 Code : 將 UI 的 View Controller 的屬性(Attribute) class 被指定此新的 class
6. 設定 UI 的 Attributes : style = Basic, Identifier = Cell
7. 新增 data source : 提供 Table View 要顯示的資料
8. 檢查 Child Class 除繼承 Parent Class 外,是否遵循 data source 與 delegate 協定
9. 覆寫 overwrite 此 data source 協定的 function
10. 試 Run

新增專案:

1. 刪除 UI 元件 (ViewController)與其相關的 Code (ViewController.swift),這些都是新增 project 的 default 設定。將這些檔案 Move to Trash
若新增一個 Storyboard,其 UI 編輯器沒有任何 UI 元件:
2. 新增 UI 元件:拖曳 TableVewController 元件至 Storyboard 為方便 UI 顯示,指定此專案針對 iPhone 開發,可先關掉 Use Size Class 選項。 即點選 View > Utilities > Show File Inspector , 然後不勾選 User Size Class:
接下來,搜尋 TableViewController:
接著拖曳 TableViewController 元件至 Storyboard:
3. 指定初始的 Controller : 設定 Is Initial ViewController
4. 新增 Code : 新增一個自訂的 TableViewController Class 新增 Cocoa Class 檔案:
設定此新增 Class 的屬性:
此時這新 Class 被新增:
5. 連接 UI 與 Code : 將 UI 的 View Controller 的屬性(Attribute) class 被指定此新的 class
6. 設定 UI 的 Attributes : style = Basic, Identifier = Cell
7. 新增 data source : 提供 Table View 要顯示的資料 8. 檢查 Child Class 除繼承 Parent Class 外,是否遵循 data source 與 delegate 協定
9. 覆寫 overwrite 此 data source 協定的 function 複寫 numberOfRowsInSection:
覆寫 cellForRowAtIndexPath:
覆寫 numberOfSectionsInTableView:
10. 試 Run
後記: Table View 可用 UITableView 實作,亦可用 UITableViewController 實作,兩者皆能製作出我們所要的結果。 iPhone App 的開發,除要熟習 Xcode 的操作之外,另外整個開發的 Flow 要清楚。例如:UI 的建立,Code 的建立,而這兩者之間又該如何建立關係等等。學開發先不求快,但要把每行程式都看懂,看得透徹,明白為何有這行 Code,那將來在開發時,就能得心應手,應用自如了。

製作 Image 的圖變成圓形


將 Image 的圖形由方塊變成圓形時,直覺上會認為由 UIImageView / UIImage,找到其相關的 Attribute 修改。但,事實上這 Attribute 已定義在其 Parent Class 父類別 UIView 中 [1]:

同樣,Image 的 layer 圖層這 Attribute 也被定義在父類別 UIView 中:
若我們要製作圓形的 Image,就要修改 CALayer [2] 這類別下的 cornerRadius 屬性:
由此知道, cornerRaidus 的資料型態 data type 被宣告為 CGFloat (浮點數),但若要製作 Image 為圓形,那其值又該如何設定? 此時理論上我們也會誤以為 Image 大小的屬性會在 UIImageView / UIImage 中宣告,但,這屬性亦在其父類別 UIView 中宣告:
而此 frame 屬性被宣告為:
接著我們往下查看 CGRect 這類別的定義:
再查看 CGSize [5] 的定義:
由此我們知道,要製作圓形的 Image,首先我們要指定 cornerRadius 的值,而這值是由我們現有 Image 的尺寸,由其中心點,畫成圓圈計算得來:

cell.myImage.layer.cornerRadius = cell.myImage.frame.size.width / 2
設定完之後,我們將邊角切掉:

cell.myImage.clipsToBounds = true
這樣圓形的 Image 就製作完成。 後記: 看來很簡單的製作,卻拉雜循序漸進寫了一堆! 若能舉一反三,碰到新的 UI Control 都能循著這思路,把 App 做出來。市面上的書大都只把這 2 行程式碼寫出,就算交代清楚,但怎麼來,對若是初入門的人而言,既使照書上做,頂多也只是學到打字。學 App 製作,不就是要學會如何釣魚,而不是只懂的吃魚嗎? 不過,每本書都各有其優點,都是作者辛苦的精華,在此僅做個補充。 參考: 1. UIView - ClipsToBounds , https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/occ/instp/UIView/clipsToBounds 2. CALayer, https://developer.apple.com/library/prerelease/ios/documentation/GraphicsImaging/Reference/CALayer_class/index.html#//apple_ref/swift/cl/c:objc(cs)CALayer 3. UIImageView, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIImageView_Class/ 4. CGRect, https://developer.apple.com/library/prerelease/ios/documentation/GraphicsImaging/Reference/CGGeometry/index.html#//apple_ref/swift/struct/c:@S@CGRect 5. CGSize, https://developer.apple.com/library/prerelease/ios/documentation/GraphicsImaging/Reference/CGGeometry/index.html#//apple_ref/c/tdef/CGRect

第 4 個程式:Table View 中 Cell 的選取


協定 UITableViewDelegate 關於選取Selection 的 被選 / 取消需要實作的函數包含下列:

例如: 假設當 User 點選 Table View 上的 Cell 之後,系統會有何反應? 我們可在 talbeView(_: didSelectionAtIndexPath:) 此函數內寫 code,實作我們要的功能。
即,我們接下來要針對以下定義,實作其內容:

option func tableView(_ tableView: UITableView, 
                         didSelectRowAtIndexPath indexPath: NSIndexPath)


    override func tableView(tableView: UITableView,
        didSelectRowAtIndexPath indexPath: NSIndexPath) {
            
            let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
            if cell.accessoryType == UITableViewCellAccessoryType.None {
                cell.accessoryType = UITableViewCellAccessoryType.Checkmark
            } else {
                cell.accessoryType = UITableViewCellAccessoryType.None
            }
            tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }

相反地,若我們希望取消選取呢?


    override func tableView(tableView: UITableView,
        didDeselectRowAtIndexPath indexPath: NSIndexPath) {
            let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
            if cell.accessoryType == UITableViewCellAccessoryType.None {
                cell.accessoryType = UITableViewCellAccessoryType.Checkmark
            } else {
                cell.accessoryType = UITableViewCellAccessoryType.None
            }
            tableView.deselectRowAtIndexPath(indexPath, animated: false)
    }
最後我來來驗證結果:
後記: 表格 Table View Cell 的選取與取消相當實用。很多書籍另設一個 Boolean 變數,來紀錄判別 Cell 的狀態,而不實作 tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath)。這樣有些缺乏 iOS 的精神。在反覆思考測試後,看到結果與自己預期,這喜悅難以言喻。 附註: 程式碼:MyTableViewController.swift

//
//  MyTableViewController.swift
//  SimpleTableViewControllerDemo
//
//  Created by Elvis Meng on 2015/9/6.
//  Copyright (c) 2015年 Elvis Meng. All rights reserved.
//

import UIKit

class MyTableViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {
    
    var vocabulary = ["book","pen","queen"]

    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
        
    }

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

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Potentially incomplete method implementation.
        // Return the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete method implementation.
        // Return the number of rows in the section.
        return self.vocabulary.count
    }
   
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        
        let cellIdentifier = "Cell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! UITableViewCell

        // Configure the cell...
        cell.textLabel?.text = vocabulary[indexPath.row]
        
        return cell
    }

    override func tableView(tableView: UITableView,
        didSelectRowAtIndexPath indexPath: NSIndexPath) {
            
            let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
            if cell.accessoryType == UITableViewCellAccessoryType.None {
                cell.accessoryType = UITableViewCellAccessoryType.Checkmark
            } else {
                cell.accessoryType = UITableViewCellAccessoryType.None
            }
            tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }
    
    override func tableView(tableView: UITableView,
        didDeselectRowAtIndexPath indexPath: NSIndexPath) {
            let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
            if cell.accessoryType == UITableViewCellAccessoryType.None {
                cell.accessoryType = UITableViewCellAccessoryType.Checkmark
            } else {
                cell.accessoryType = UITableViewCellAccessoryType.None
            }
            tableView.deselectRowAtIndexPath(indexPath, animated: false)
    }

    /*
    // Override to support editing the table view.
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            // Delete the row from the data source
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        } else if editingStyle == .Insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }
    */

    /*
    // Override to support rearranging the table view.
    override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {

    }
    */

    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return NO if you do not want the item to be re-orderable.
        return true
    }
    */

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */

}
參考: 1. UITableViewDelegate, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/ 2. UITableViewCell, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableViewCell_Class/ 3. http://www.fanli7.net/a/bianchengyuyan/C__/20141215/491181.html 4. iOS Swift Tutorial - Building a Checklists App Part 1b, http://blog.mayankkapoor.com/post/89993926313/ios-swift-tutorial-building-a-checklists-app

第 5 個程式:Table View 中 Cell 的刪除 1


要刪除 Table View Cell 的資料,該如何做? 其執行步驟如下:

1. 開啟 Table View 的 Data Model 為 Edit 編輯模式
2. 在此模式下刪除資料
3. UI 畫面重整 Refresh

Table View Cell 的資料來源依據 MVC (Model-View-Controller) 這架構,其來源是由其協定 UITableViewDataSource 實作。參考 UITableViewDataSource [1] 文件,其提供下列方法:

方法 tableView(_:commitEditingStyle:forRowAtIndexPath:) 會將此 Data Model 切換成 Edit 編輯模式,讓我們可以修改資料,此方法詳細內容如下:
由以上說明得知: 當開啟此 Edit 編輯模式之後,除 insertion (green plus) control 外,亦提供 deletion (red minus) control 用來刪除 Cell 上的資料。 我們使用 func tableView(_ tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 這方法來開啟成 Edit 模式。然後,在此模式下實作我們要刪除的資料。

    override func tableView(tableView: UITableView,
        commitEditingStyle editingStyle: UITableViewCellEditingStyle,
        forRowAtIndexPath indexPath: NSIndexPath) {
            
            if editingStyle == .Delete {
                self.vocabulary.removeAtIndex(indexPath.row)
            }
    }
當資料刪除後,我們必須讓 UI 畫面重整 Refresh。UITableView 提供一個方法 reloadData() 來 refresh UI:

    override func tableView(tableView: UITableView,
        commitEditingStyle editingStyle: UITableViewCellEditingStyle,
        forRowAtIndexPath indexPath: NSIndexPath) {
            
            if editingStyle == .Delete {
                self.vocabulary.removeAtIndex(indexPath.row)
                self.tableView.reloadData()
            }
    }

驗證: 在模擬器上,選取一行資料 Cell,然後左滑:
此時這行的右邊會顯示 Delete 刪除這按鈕。當我們點選這按鈕後,這行會被刪除嗎?
Yeah! 這行真的被刪除了!這下可以鬆口氣! 後記: 這整個步驟是參考書中的練習,以及 Apple 的網站,先由一個該怎麼做的概念去進行,把該有的 code 準備好後,才發現原來 TableViewController 這 Template 很貼心幫我們準備好 code 如下,但貼上自己寫的,整個觀念會更清楚。

  /*
    // Override to support editing the table view.
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            // Delete the row from the data source
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        } else if editingStyle == .Insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }
   */
附記: 程式碼:

//
//  MyTableViewController.swift
//  SimpleTableViewControllerDemo
//
//  Created by Elvis Meng on 2015/9/6.
//  Copyright (c) 2015年 Elvis Meng. All rights reserved.
//

import UIKit

class MyTableViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {
    
    var vocabulary = ["book","pen","queen","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"]

    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
        
    }

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

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Potentially incomplete method implementation.
        // Return the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete method implementation.
        // Return the number of rows in the section.
        return self.vocabulary.count
    }
   
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        
        let cellIdentifier = "Cell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! UITableViewCell

        // Configure the cell...
        cell.textLabel?.text = vocabulary[indexPath.row]
        
        return cell
    }

    override func tableView(tableView: UITableView,
        didSelectRowAtIndexPath indexPath: NSIndexPath) {
            
            let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
            if cell.accessoryType == UITableViewCellAccessoryType.None {
                cell.accessoryType = UITableViewCellAccessoryType.Checkmark
            } else {
                cell.accessoryType = UITableViewCellAccessoryType.None
            }
            tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }
    
    override func tableView(tableView: UITableView,
        didDeselectRowAtIndexPath indexPath: NSIndexPath) {
            let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
            if cell.accessoryType == UITableViewCellAccessoryType.None {
                cell.accessoryType = UITableViewCellAccessoryType.Checkmark
            } else {
                cell.accessoryType = UITableViewCellAccessoryType.None
            }
            tableView.deselectRowAtIndexPath(indexPath, animated: false)
    }

    override func tableView(tableView: UITableView,
        commitEditingStyle editingStyle: UITableViewCellEditingStyle,
        forRowAtIndexPath indexPath: NSIndexPath) {
            
            if editingStyle == .Delete {
                self.vocabulary.removeAtIndex(indexPath.row)
                self.tableView.reloadData()
            }
    }

  /*
    // Override to support editing the table view.
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            // Delete the row from the data source
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        } else if editingStyle == .Insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }
   */

    /*
    // Override to support rearranging the table view.
    override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {

    }
    */

    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return NO if you do not want the item to be re-orderable.
        return true
    }
    */

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */

}

參考: 1. UITableViewDataSource Protocol Reference, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/ 2. UITableView Class Reference, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableView_Class/index.html#//apple_ref/occ/cl/UITableView

2015年9月3日 星期四

第一個程式:UIAlertController 製作 (2)

Apple 將 Alert Window 視為 ViewController, 而不是一個 View 的概念,所以以此取代 UIActionSheet 與 UIAlertView 類別。市面上若有 Swift 的書,Alert Dialog 的製作仍沿用 UIAlertView 為早期用法。

製作 Alert Dialog 的步驟如下:

1. 建立 Alert Dialog 物件 : UIAlertController
2. 建立 Alert Action 物件 : UIAlertAction
3. 將新建的 Alert Action 物件加入 Alert Dialog 物件清單 : UIAlertController.addAction
4. 顯示 Alert Dialog 物件 : UIViewController.presentViewController

以下依此步驟及Apple 的官方文件,逐步說明如何製作 Alert Dialog:


1. Declaration: UIAlertController
SWIFT
convenience init(title title: String?,
         message message: String?,
  preferredStyle preferredStyle: UIAlertControllerStyle)
寫成: let alertController = UIAlertController(title : "My First App", message : "Hello,World!", preferredStyle : UIAlertControllerStyle.Alert)

2.Declaration: UIAlertAction 
SWIFT
convenience init(title title: String?,
           style style: UIAlertActionStyle,
         handler handler: ((UIAlertAction) -> Void)?)
寫成: let alertAction = UIAlertAction(title : "OK", style : UIAlertActionStyle.Default, handler : nil )

3. Declaration: UIAlertController.addAction 
SWIFT
func addAction(_ action: UIAlertAction)
寫成: alertController.addAction(alertAction)

4. Declaration: UIViewController.presentViewController
func presentViewController(_ viewControllerToPresent: UIViewController,
                  animated flag: Bool,
                completion completion: (() -> Void)?)
寫成: self.presentViewController(alertController, animated : true, completion : nil) 所以,一個簡單的 Alert Dialog 完整的程式如下:


let alertController = UIAlertController(title : "My First App",
                       message : "Hello,World!",
                       preferredStyle : UIAlertControllerStyle.Alert)

let alertAction = UIAlertAction(title : "OK",
                                style : UIAlertActionStyle.Default,
                                handler : nil )

alertController.addAction(alertAction)

self.presentViewController(alertController,
                  animated : true,
                completion : nil)

後記: 很多書籍在解釋 iPhone 的程式時會逐條解釋,但當下似乎只知道說明的部分,至於該怎麼寫還是很虛。我試著由概念出發,即程式不是重點,而是我到底想開發什麼,然後試著去找相關對應的工具。每個工具在 Apple 的 Developer 網站都有詳細的說明。依據這思維,開發 iPhone 就變得相當容易些。 Refernce: 1. UIAlertController, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIAlertController_class/#//apple_ref/swift/enum/c:@E@UIAlertControllerStyle 2. UIAlertAction, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIAlertAction_Class/ 3. UIViewController, https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/instm/UIViewController/presentViewController:animated:completion:

第一個程式:UIAlertController 製作 (1)


首先,開啟一個新的專案,在此我們用 Swift 這語言來開發:

輸入 UIButton 搜尋 Button 物件:
拖曳此 Button 至 iPhone 畫面:
將 Button 的文字改為 “Hello, World"
打開顯示 Assistant Editor,此時 UI 與其相關 Code 像是孤島,各自獨立
要讓 UI 與 Code 彼此建立關係,先按下 Control 鍵不放開,然後點選 Button,按下右鍵,拖曳至程式編輯區:
此時設定此連結關係為 Action,輸入完畢後,按下 Connect 按鈕,此時程式編輯區顯示如下:
注意到沒?系統藉由 @IBAction 這關鍵字,將 UI 與 Code 連接 connect 起來。即當你按下 Hello,World 這按鈕後,系統會執行 @IBAction 所連接的動作。在此,我們按下 Button,iPhone 會顯示 Alert Dialog 視窗。所以,我們要預先在此區塊中寫入程式:
完成後,我們要驗證所寫的程式是否是與我們的期望相同?我們可按下向右按鈕來編譯與執行:
接下來是最緊張的時刻!我們來看執行後的結果:
在 iPhone 的模擬器中,我們看到畫面上有個 Hello, World 按鈕,我們點選此按鈕,看是否會出現 Alert Dialog:
Bingo ! 我們寫的程式執行結果正如我們預期! 所以,學 iPhone / iPad 程式會很難嗎? 這不好說,但至少我們已經跨越了第一步! 後記: 希望自己能以幾張簡單的圖,引領讀者激發學習寫 iPhone 程式的興趣。很多希望入門者應該與我有相同的苦惱,閱讀 iPhone 書籍時,一邊被長長的敘述困擾,另一邊書本限於篇幅,又不能將專案的步驟以圖示來說明。學程式必須跟著做才能找到感覺,而後續還是要啃書本,讓自己更明暸細節部分。
prettyPrint();