prettyprint

2015年10月17日 星期六

ImageView Demo


1. 新增專案

2. 將照片丟入 Assets.xcassets 資料夾
3. 找尋 Image View 這 UI 元件
4. 將 Image View 拖曳至 View 中,並在 UI 屬性 Image View 中 Image 設定 Default 影像
5. 增加 2 個 Button 按鈕
6. 將 UI Image 元件與 Code 程式連接
7. 將 UI Button 元件與 Code 程式連接
8. 完整程式

//
//  ViewController.swift
//  ImageViewDemo
//
//  Created by Elvis Meng on 2015/10/17.
//  Copyright © 2015年 Elvis Meng. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    
    var arrayNames = ["人間失格","改變成真","Steve Jobs"]
    var imageIndex = 0
    var count = 0
    
    @IBOutlet weak var ImageNow: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        ImageNow.image = UIImage(named: "人間失格")
        count = arrayNames.count
    }

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

    @IBAction func prevClick(sender: UIButton) {
        
        if  --imageIndex < 0 {
            imageIndex = count - 1
        }
        ImageNow.image = UIImage(named: arrayNames[imageIndex])
    }

    @IBAction func nextClick(sender: UIButton) {
        
        if ++imageIndex == count {
            imageIndex = 0
        }
        ImageNow.image = UIImage(named: arrayNames[imageIndex])
    }
}

9. 測試
注意: 測試時,若要使用 iPhone 5s 這模擬器測試,需不勾選
此外,模擬器要勾選設定

2015年10月15日 星期四

以 Object Oriented 觀點看 2 個畫面如何傳遞參數


畫面切換,彼此間要傳遞參數這是常碰到的。在此我以物件導向 Object Oriented 的觀點,來看參數如何在 2 個畫面間傳遞。

既然是兩個畫面 View,每個UI 的 View 就會對應到一個 View Controller。所謂 "對應",就是 UI 的 View 會有屬性 ID 設定,指定這 View 屬於那一個類別 Class。

既然是類別,那就是談到 Code 的實作。Swift 大大改進 Objective-C,將類別的宣告 header file 與 類別的實作都放在同一個檔案 .swift 裏。

定義好 UI View 的類別,那 2 個 View 之間的變數又該如何傳遞 ? Apple 提供一個函式 prepardForSegue:sender , 即在前一個 View Controller 的類別中,我們呼叫此函式,將變數傳遞到下一個 View Controller。 

我們以一個範例來說明。

首先,我們會有兩個 View。 View 1 指定為 FirstViwController, View 2 指定為 SecondViewController。 這兩個類別都是繼承 UIViewController。 雖然它們的父類別 Parent Class 都繼承相同類別,但,由於 FirstViewController 與 SecondViewController 的"長相"不同,所以需設定 2 個不同的類別。這裡所謂"長相",即它們各自的屬性 Property 與能提供的功能 Function (或 Method) 都不相同,當然要設計成 2 個不同的類別。每個類別將 Property 與 Method 封裝 Encapsulate 起來,這是 Object Oriented 最基本的概念。

假設我們設定 FirstViewController 有屬性 senderVar 被宣告如下:


import UIKit
class FirstViewController:UIViewController {
   override fun viewDidLoad() {
      var senderVar:String = "test"
   }
   ...
}
而在 SecondViewController 有屬性 receiverVar 被宣告如下:

import UIKit
class SecondViewController:UIViewController {
     var receiverVar:String
     println("Receive Var : \(receiverVar)")
}
現在我們也知道 Apple 提供 prepardForSegue:sender 這函式,但,該如何使用呼叫 ? 同樣我們以 code 來說明。

import UIKit
class FirstViewController:UIViewController {
   override func prepareForSeque(seque:UIStoryboardSeque, sender:AnyObject!) { 
      var secondViewController = seque.destinationViewController as SecondViewController
      secondViewController.receiverVar = senderVar
   }
   ...
}
看到沒? 我們在第一個類別 FirstViewController 透過呼叫 prepardForSegue:sender 這函式, 宣告一個 SecondViewController 物件為 secondViewController,然後將 FirstViewController 的變數 senderVar 指定給 SecondViewController 的變數 receiverVar,而在第二個 View 顯示出來。 在 Object Oriented 的觀念裡,外人的物件 Object 是無法直接使用,必須透過物件才可。 後記: 知道這設計的概念,對以後類似不同類別間的呼叫就能得心上手。 Code 只是表面,但 Code 裡面所包含的觀念若很清楚,寫程式就相對輕鬆多了。例如: Object Oriented 的設計與語法必須熟練,畢竟現在無論是 UI 或 Code 的設計,其中心觀念都圍繞在 Object Oriented。

2015年10月14日 星期三

Tab Bar Controller


Tab Bar 即是在 iPhone 下方的功能選項列表。有 2 個方式製作 Tab Bar: (1) 在 View Controller 上拖曳一個 Tab Bar Controller 元件 (2) 直接使用 Apple 已寫好的 Template, 即 Tabbed Application。

使用 Tab Bar 好處是無論 View 如何透過 Segue 切換,它都被顯示。 我們把 Tab Bar Controller 當成 Container,此 Container 已嵌入一個 Tab Bar 元件。所有被放在此 Container 的 View 屬於 Layer 1,但, Tab Bar 卻屬於 Layer 2。因此,View 無論如何切換,Tab Bar 永遠顯示在最上層。這概念與 Photoshop 的塗層 layer 概念相同。 Tab Bar Controller 是個非常特殊的 Container。若我們新增一個 View Controller 到此 Tab Bar Controller 中, 其嵌入的Tab Bar 元件就會新增一個 Button 與此 View Controller 呼應。也就是說,每個 Tab Bar 上的 Button 都會指向一個特定的 View Controller。 Tab Bar 上的 Button 的圖示 icon 可透過 Feature 這屬性客製化。 參考: 1. UITabBarController,https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITabBarController_Class/ 2. Tab Bar Controllers,https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/TabBarControllers.html

Navigator Controller Demo


新增專案:

新增 1 個 Navigator Controller 及 1 個 View Controller:
接下來將 Veiw 連結起來。此時,在第一個 View 新增 Button。之後,選此 Button, 按下 Control 鍵不放,將其拖曳到第二個 View,此時設定 Seque Action 選 Modal:
接著,在第三個 View 新增 Bar Button Item,之後,選此 Bar Button Item, 按下 Control 鍵不放,將其拖曳到第二個 View,此時設定 Seque Action 選 Push:
檢查 Bar Button Item 的放置位置:
測試: 1. 按下 Push 按鈕:
2. 按下 Item 按鈕:
3. 按下 Back 按鈕:
在 iPhone 6 會顯示 Root View Controller 按鈕 後記: Bar Button Item 拖曳擺放的位置要正確,若畫面上無法選取此 UI 元件,則在 UI Navigator 上點選此 UI 元件,然後點選 Triggered Seque,將此 UI 元件連結至第四個 View 即可,如下:
看起來一個很簡單的測試,卻帶出一個重要的概念。注意到沒?在 Storyboard 我們看到 4 個 View,但在測試時只看到 3 個 View。嚴格說,事實上第二個 UI 元件 Navigator Controller 不是 View,而是一個 View Container。所謂 View Container 就是它可以含有一個以上的 View。在這 Demo 只有含一個 View,即第三個 View。所以這個 Demo 無法真正看出 Navigator Controller 當初被設計出來的用意,即無法看到 View Container 與 View 之間的 Layer 關係。Apple 的 UI 元件一般在 View Controller 前有特定指名,都算是 View Container。例如:Table View Controller, Collection View Controller,Tab Bar Controller 等。

2015年10月13日 星期二

iPhone App 設計概念: MVC 設計模式

2015.10.12

iPhone App 設計遵循 MVC 設計模式 Design Pattern。此 MVC 即 Model - View - Control 的縮寫。當 Ap 
變得複雜時,會將問題切割為較小單位來解決,此為 Divide and Conquer 方法。所以,MVC 模式也以 Divide 
and Conquer 的思維,將問題簡化,各司其職。 Model 負責 Data 資料的存取,View 負責資料的 Presentation
 呈現,而 Control 則是此模式的神經、管家,負責運算邏輯 Logic,作為處理 Model 與 View 之間的橋樑。
MVC 模式已被廣泛運用在 AP 的開發。 Apple 提供一個整合免費的開發環境,即 Xcode。 App 設計時,需考慮 
User 如何與裝置 device 互動,這互動是藉由 App 所提供的 UI 介面達成。 Xcode 內含 UI 開發工具 
Interface Builder,讓開發人員用“畫”的方式,將所需要呈現的 UI 元件拖曳到"畫面“ Screen 上,這 
“What You See Is What You Get 所見即所得”的直覺式設計 View 的方式,大大降低開發人員過去以文字 
Code 的輸入方式所耗的時間。

Apple 的 UI 設計,一般我們設計的 App 只會在一個 device 呈現,當我們要將 UI 元件"畫“上時, Apple 
已為我們準備一個唯一的 UI 容器 Container,這容器即是 Window。這 Window 就暫且把它看成 Storyboard。
由於這 Window 只是容器,沒有我們平常看到的像是按鈕等 UI 元件,所以只是個 UI 框架。但,UI 元件不能
"畫“在這 Window 框架中,只能畫在"視圖 View"上,所以在畫 UI 元件前,我們必須先準備好 View 這視圖。
既然 Window 是個大容器,它可以依據需要容納更多的視圖 View,而每個 View 與 View 之間並不是單獨存在
的,而是有關係的,這關係在 Xcode 工具中是用 Seque 的方式來連結。當所有的 View 都連結好後,這 App 
要提供給 User 什麼樣的功能就此完整呈現說明。所以 Apple 在 UI 設計上以 Storybord 故事分鏡的概念來
完成。當然,完成 Storyboard 之前,我們已經將每個 View 所需要的 UI 元件都“畫”到各自的 View 中。若
我們設計的 App 會在 2 個以上的裝置 device 顯現,此時 App 的 UI 就需要 2 個以上的 Window 容器,
每個 Window 容器各自對應到特定的顯示裝置。

當 UI 介面定稿,接下來我們要讓 App 能“動”。UI 視圖 View 上面這些元件大致上分為 2 類。一類只是顯示,
不需要任何動作。另一類 UI 元件則需要後續處理。對於後續需要處理的 UI 元件,我們就必須能識別,因此會
設定"變數“名稱命名。當 UI 元件與程式裡與其有關的識別名稱都準備好,此 2 者各自獨立,誰也不認識誰。
此時,Apple 提供一個 connect 的機制,將 UI 元件與其相關的識別名稱 variable 關聯起來, 而在此識別
名稱前加入一個特別的前綴詞 @outlet。另外,若這些元件是與 event 事件有關的元件,例如 Button 按鈕,
這時 Apple 提供另外一個 connect 機制,講此類 UI 元件與其相關的“動作 Action"關聯起來,而在此事件
名稱前加入一個特別的前綴詞 @action。 由於 iPhone 的 App 遵循 event driven 此 windows 模式架構,
所以當 User 按下 Button 安扭時,會觸發一個事件 event。當事件被觸發後,接下來程式就要決定接下來該
怎麼處理。若還需要進一步讀取資料庫,則讀取完畢後再處理資料,而將最後處理的結果回傳給 View,由 View 
將結果顯示出來。因此我們說 Control 這模組是負責運算邏輯 Logic,作為處理 Model 與 View 之間的橋樑。
要注意:每個 View 視圖的背後都會有一個,且是唯一的 ViewController 來控制這視圖 View 的 UI 元件,
以及其之間的 Logic 處理。

剛提到,若 Control 模組處理時,需要額外的資料,它會透過機制向 Model 模組要資料。這些資料可能是有關
 App 設定的 plist 檔案。若更複雜則使用小而美、有五臟俱全資料庫能能的 SQLite,或是使用 Apple 貼心的
設計 Core Data 機制。 Core Data 是將 data base 的複雜性封裝,而提供等同的資料庫存取介面,方便開發
者使用。有時 App 的質料必須連結至網路例如 iCloud 讀取。基本上 Apple 對資料的安全維護控管採用 
Sandbox 的概念,即每個 App 各自有屬於自己的資料庫,各自井水不犯河水。當然,這也有例外。Apple 也提供
讓不同的 App 共用存取資料的方式,例如 iPhone 的聯絡人資料。所以剛接觸 iPhone App 設計時,書本會要求
你不勾選 Core Data,就是說這測試學習用的 App 並不需要存取任何資料。

學習 iPhone App 的設計,熟習了解 MVC 設計模式是很重要的,如此我們才能將 App 的設計的實作部分由繁入
簡。 MVC 設計模式好比是森林,接下來我們要入林探訪,了解整個 App 設計概念的細節部分。這其中較常被忽略
的是 UIViewController 的 Life Cycle。 各 View 中的 UI 元件何時被建立,又何時被釋放,
這些觀念要釐清,我們才知道程式碼該放在那個函數 function 中。


後記:

對 iPhone App 入門者而言,這 MVC 設計模式,以及與 Xcode 工具之間的關係與運用,總要摸索一段時間。若
僅是跟著書本敲打,而只知其然,不知所以然,在往後開發一個 App,遇到困難點就會不知道如何除錯 debug。
在此將學習過程紀錄,有助於其他人學習。

參考:

1. File:MVC Diagram (Model-View-Controller).svg, https://commons.wikimedia.org/wiki/File:MVC_Diagram_(Model-View-Controller).svg



2015年10月2日 星期五

Apple Watch Test


1. Add new project:

First, you have to create an iOS Application.

Apple Watch App is an add-on to an existing iOS App. You first have to create an iOS application and then add a WatchKit application to it.

Select Universal for Devices.

2. Select Editor Function for Adding Apple Watch Target to Project: Then, you add a WatchKit application to the iOS Application.
3. Add Apple Watch Target to Project
4. Uncheck or Check Include Notification Scene. It is an option. Now we will implement nothing. This project is only for testing.
5. Activate this App's scheme.
6. Afterwards, this project contains 3 main folders: AppleWatchTest, AppleWatchTest WatchKit 1 Extension, and AppleWatchTest WatchKit 1 App A WatchKit application runs in the WatchKit app extension on the iPhone, not on the Apple Watch itself.
7. Review target property settings: General
8. Review target property settings: Build Setting
Test: 1. For the first time testing the setting shown below is optional.
2. Run the test:
3. For Apple Watch' app, you will see that this project will generate 2 running processes: Watch App and WatchKit Extension
Resources: 1. http://www.apress.com/9781484210260

2015年10月1日 星期四

如何學寫 iOS App

寫 iPhone App 相信應該是大多數程式師躍躍欲試的領域,而如果有天能寫出像 Angry Bird 那樣的軟體,那名利雙收不在話下。但,問題是:該從何開始?

首先你要有個開發環境。過去坊間有教人用黑蘋果來開發。黑蘋果顧名思義就是紅透發黑的蘋果,而這樣的蘋果能吃嗎?也就是在一般 Intel i5/i7 的 PC 上,先安裝 Mac OS,然後在安裝開發環境 Xcode。這工程非常浩大,縱然安裝好了,但 Apple 的 OS,Xcode 改新版本的數度超快。例如:今年才剛拿到的新書 Xcode 版本是 6.x,且以 Swift 開發,而目前 2015/9 月 Xcode 已進化到 7.0,且OS 更新為 iOS 9。以這樣的速度,紙本的書籍根本無法跟上 Apple 的野心。我就碰過照著書一字不漏敲打,就是無法編譯。後來追根究底才發現 Swift 演化到 Swift 2.0,在呼叫函數 function 時,新增加類似 Java 的 throws,這屬於 Exception 報錯誤訊息的功能。

既然書籍還沒上架就註定會滯銷 (?),那有心成為 iPhone App 的開發者不得不養成耐性,將 Apple Dedeveloper 的開發者網站當成尋寶迷宮。這網站要什麼有什麼 (廢話),但由於是五臟俱全,所以開發者頭髮還沒有變白,那寶物依然安然躺在雲深不知處。這種焦慮對從未開發程式的初學者更明顯。初學者必須藉由書本,良師的指引才能登堂入室。然而,既使 Swift 與 Objective-C 相較之下,已降低相當的學習門檻,但不可諱言 Swift 的彈性與豐富簡約的語法的功能,常會令開發老手歎為觀止,更別提新手了。最著名的範例就是 Closure 閉包。有誰會想到以 { $0 > $1 } 來表示兩個變數的比較?這概念非要有歷經 Unix / Dos 使用命令式 command line 處理資料,才能有感覺與想像。

學習好 Swift 這 Apple 去年才發表的新程式語言之後,你可能會沾沾自喜,認為自己可以拜別師父,自立門戶了。然而,等下了山才發現即將面對的是成堆的 類別 Class 組成的程式庫 Library。這 Library 從物件導向的觀念來看,就把它們當成工具箱,等需要時再拿出適當工具。我們不會拿蓋房子的磚塊去煮飯吧?!煮飯自己有自己的工具。這工具 Library 若以 Apple 的術語,就叫做 Framework。這 Framework 換湯不換藥,就是很貼心早已為我們準備套裝的工具,然後為我們建立一個粗毛胚,好讓我們不必從頭由無到有建立一個 App。它好比量販店賣的微波食品,有快炒,有湯點,各有各的配料。接下來,開發員整日在這堆 Framework 鑽來鑽去,而這是不得不然啊!剛才說過,Apple 更新開發程式的環境如此快速,新的功能只會在 Apple 的開發者網站找得到,其他免談。乍聽之下,有野心的開發者更是見獵心喜,但苦的是,在鑽入這大黑洞後,開發者除了了解 Frameworks 所提供的功能外,也必須像是做實驗般,不斷地 try and error,有時不僅 App 要能動,若力求美感,還要講求程式碼 Code 的可讀性,效率,預留方便除錯等。

拉雜寫了一堆,會不會玻璃心就如此碎了?有時更糟糕的是你得面對殘酷的現實,就是寫程式的人並非人人是口袋滿滿,尤其在台灣這個只會講究做麵包,不注重食譜的短視近利企業心態。所以適合寫程式的人仔細觀察真有那人格特質,即能夠做得住,捱得住,既使荷包不比業務,但能從寫程式的除錯過程中“享受”那唯我獨一的快樂。這樣的人很適合寫程式,也足夠強壯去接受 Apple 層出不窮翻新的挑戰。但,繞了一大圈,我們又該如何買入門票呢? 我個人認為先要有寫程式的整體概念,再來寫程式就相對容易些。例如:若不知道物件導向 Object-Oriented,能把 App 寫的精妙,那我也很佩服。問題是:可能嗎?有了程式的概念,再去猜猜怎麼寫,要找什麼樣的工具,這樣建構一個 App 就容易些,不會像是大海撈針。對毫無經驗的初學者而言,雄心壯志固然重要,但好的師傅,好的武功祕笈更能讓你早點練好九陽神功,早日下山除害啊!

PS. 以上這些對想入門 iOS App 的人有幫助嗎?個人學淺,僅就個人的經驗提出看法,希望能拋“柱”引玉,獲得更多的迴響,好讓百家爭鳴,那有福的是苦思無法入寶山的慕道者啊!一笑!


prettyPrint();