專案步驟: 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
“Those who are in love with practice without knowledge are like the sailor who gets into a ship without rudder or compass and who never can be certain [where] he is going. Practice must always be founded on sound theory.” by Leonardo da Vinci
2015年9月9日 星期三
第 2 個程式:SimpleTableView
第 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 書籍時,一邊被長長的敘述困擾,另一邊書本限於篇幅,又不能將專案的步驟以圖示來說明。學程式必須跟著做才能找到感覺,而後續還是要啃書本,讓自己更明暸細節部分。
訂閱:
文章 (Atom)