蘋果開發者中心網址:http://developer.apple.com
蘋果開元資源的網址:http://opensource.apple.com
蘋果開發者論壇網址:http://forums.developer.apple.com
第三方社區
stackoverflow、cocoachina、ourcoders、 v2ex 、github(搜awesome ios 會有很多有用的代碼)
App概率
和C語言一樣也是從main函數進入,main函數調用UIApplicationMain函數,再由UIApplicationMain函數的最后一個參數傳入AppDelegate類。
//int main(int argc, char* argv[]){
@autoreleasepool{
return UIApplicationMain(argc, argv , nil, NSStringFromClass([AppDelegate class]));
}
}
iOS App的運行環境是Sandbox(安全環境), 運行期目錄結構可以通過調用NSHomeDirectory()函數來得到。
每個iOS App都是一個目錄文件(Bundle),帶有:Info.plist的目錄。通過NSBundle類可以讀取目錄文件中的信息。resource bundle和framework都可以嵌在mainBundle里。
Button
界面與代碼分離
可以只用代碼來描繪見面及響應用戶操作,缺點是不直觀,調整麻煩。iOS編程使用的是界面與代碼分離解決的方案,用Interface Builder來編輯界面,保存到xib(xml版的nib)文件,用代碼來更新界面、響應用戶操作,保存在.m文件里。
使用界面代碼分離解決方案,我們需要關注兩個方面:1、界面操作怎么指定響應代碼。2、代碼怎么引用界面元素。
在開發時,代碼描述的是類,界面描述的是模板(xib)。等程序運行時,代碼的類形成類實例,界面形成的是界面對象。
Outlet
為了讓代碼能引用nib中的對象,需要代碼里有一個變量來引用界面對象(該變量會加上修飾<IBOutlet>),在界面創建后,給這個變量賦值(和一個nib object建立一個connection關系),這個變量就成了一個界面對象的referencing outlet。這個過程最好能自動完成。
Outlet Connection
存在xib里的是界面模板,運行時,類實例的代碼會觸發界面實例化。最終調用[UINib instantiateWithOwner:options:];再根據模板實例化其中的對象[owner-setValue:uiObj forKey:outlet.property]
Action Connection
界面事件:Interface Builder, Connection Inspector
響應代碼:IBAction標記的方法
關聯:界面對象.事件=>類實例.方法
在有關聯的類實例方法返回值設為IBAction讓編譯器知道這是一個響應事件的方法。//-(IBAction)greeting:(id)sender{}
Demo
在Interface Builder里制作界面(拖動所需的界面對象到Interface Builder界面里),給按鈕添加響應代碼(將Interface Builder界面里的對象按住control鍵向ViewController.m文件中聲明處拖動,將自動生成屬性聲明代碼),在響應代碼里訪問其他界面元素(將Interface Builder界面里的對象按住control鍵向ViewController.m文件中實現處拖動,將自動生成實現代碼的框架,后續再按實際需求補全代碼)。
UIButton樣式
UIButton的樣式
代碼創建UIButton
創建
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
定制
[btn setBackgroundImage:[UIImage imageNamed:@"okbtn"]forState:UIControlStateNormal];
[btn setTitle:@"OK"forState:UIControlStateNormal];
[btn setTitleColor:[UIColor redColor]forState:UIControlStateNormal];//將顯示的字設置為紅色
添加響應
[btn addTarget:self action:@selector(greeting:)forControlEvents:UIControlEventTouchUpInside]; //按鈕點擊后形成一個響應事件,調用了greeting方法
event mask:UIControlEventTouchUpInside | UIControlEventTouchUpOutside
Image
Assert Catalog
Assert Catalog是一個圖片管理器,針對不同的iOS設備,可視化管理不同的分辨率。在Xcode里面使用圖片,首先要將需要使用的圖片加到項目里面,定義圖片為項目里面的一個資源,如果圖片有邊框的,還要做圖片的邊框切片定義,好讓同一張圖片應對不同分辨路的縮放。
打開Xcode后選擇Assets.xcassets用來編輯圖片。在Interface Builder里面拖入一個Image View,在圖片屬性里嘗試各種功能對圖片的影響。
Assets.xcassets的編輯區里有Appicon,這個是程序顯示在設備上的圖標,由于iOS設備現在的不斷增加,有不同的分辨率,我們可以根據不同的分辨率配屬不同大小的圖片。
矢量圖:矢量圖是根據幾何特性來繪制圖形,矢量可以是一個點或一條線,矢量圖只能靠軟件生成,文件占用內在空間較小。最大的特點是可以無限放大,不變色、不模糊。
UIImageView
用UIImageView在Interface Builder顯示圖片,UIImageView有許多不同的屬性。Mode屬性對應UIImageView中圖片的顯示方式,有適應邊框填滿(Scale To Fill)、保持橫豎比例縮放(Aspect Fit)、保持橫豎比例填滿(Aspect Fill)等。
.image屬性是指關聯到UIImageView的圖片屬性。
圖片屬性可以根據不同大小或配置的設備指定不同的圖片,圖片的Render屬性是指圖片出現在ToolBar上時的表現,有默認、原始圖片和模板圖片三種屬性選項。
有邊框的圖片可以進行裁剪設置,保證圖片縮放時邊框比例保持不變。使用圖片的Silcing屬性進行編輯,也可以在圖片編輯區點擊右下角的Show Slicing設置。(注:縮放中心點最好和左上角的邊框點接近,拖動時圖片不容易超出邊框)
圖片在IB里選擇意味著圖片打包在mainBundle里,系統會自動緩存。
加載App bundle里的圖片
image = [UIImage imageNamed:@"mypic"]; //自動在App bundle里尋找名字為mypic的問題件。
image = [UIImage imageNamed:@"mypic" inBundle:nil compatibleWithTraitCollection:nil]; //如果是自己打包的resource bundle就用以上方法。
NSURL *url = [[NSBundle mainBundle] URLForResource:@"mypic"withExitension:@"png"];//得到mypic.png文件的文件路徑
UIImage *image = [UIImage imageWithContentsOfFile:url.path]; //通過以上的文件路徑創建圖片實例,這種方法比較好,不需要提前緩存
加載文件里的圖片
UIImage *image = [UIImage imageWithContentsOfFile:path]; //通過可以訪問到的文件加載圖片。
UIImage *image = [UIImage imageWithData:data]; //通過data來得到對象。
加載動畫
將一段連續的圖片加載到App bundle中,命名由相同名字+數字的方法。
這一課主要是實踐練習,熟悉圖片在Interface Builder里面的各種屬性和用法。在ViewController.h 文件中聲明一個UIImageView屬性:@property (weak, nonatomic) IBOutlet UIImageView *imageView;,并且在-(void)viewDidLoad方法實現中加入圖片加載代碼:
UIImage *image = [UIImage animatedImageNamed:@"動畫"duration:1.0]; //將名字為“動畫”的圖片打包成一個動畫
self.imageView.image = image; //把圖片“動畫”集加載到imageView屬性窗口中
第一個App
一個小游戲,猜城市。主要玩法:顯示一張城市的圖片,用戶輸入城市的名字,猜對得分。
在制作軟件之前除了基本的要求描述外,還需要做進一步的需求分析。大型軟件還需要做多次的用戶需求訪問,軟件架構分析及設計,開發組員討論交流等必要工作來確保開發軟件的準確性和高效性。上述的游戲還有不少細節我們需要了解。例如:城市圖片的展示順序,是順序展示還是隨機展示。 圖片的來源,是本地圖片還是從服務器下載。輸入框中是需要輸入中文還是英文。如果輸錯可否重試,可以重試幾次。游戲計分系統怎樣設置。游戲結束觸發條件等。要在需求收集盡可能完善的情況下再進行分析、設計。
根據需求分析設計,來設計整個程序的流程,設計時需要考慮一定的可擴展性 、跟合理性。通過程序流程設計再設計出合理的代碼結構。
改進鍵盤的顯示問題**
方案1:點擊鍵盤外的地方收起鍵盤,首先在storyboard,點擊背景View,將它的Custom Class設置為UIControl再將UIControl的Touch Down響應事件關聯到一個重新聚焦方法。 [UITextField resignFirstResponder];
方案2:輸入完成后點擊return關閉鍵盤, 選中一個UITextField控件將Did End on Exit事件響應關聯到一個重新聚焦方法。 [sender resignFirstResponder];
第六天視頻課程
演示了猜城市游戲的全部代碼,講解了代碼的設計結構和注意事項。 代碼在實現功能的前提下需要有條理的分類,保證整個程序的代碼結構合理性。控制界面刷新的ViewController不應該放入業務邏輯,只負責從頁面上拿信息和更新頁面的狀態。 應該另外新建一個Game類來描述游戲的邏輯。
pragma mark 預處理器文法用來方便查找和導航代碼用的,在代碼編輯器的導航欄插入我們想要的標題。
id和instancetype:
他們都可以作為方法的返回類型,instancetype可以返回和方法所在類型相同的對象,id只能返回未知類型的對象。instancetype只能作為返回值,不能像id那樣作為參數。
學會寫單元測試,Unit Test可以分塊測試,在編程的過程中只需要專注當前區塊的編寫就可以了。Xcode還有界面自動化測試(UI Test),可以幫助我們自動測試軟件。
為了做測試可能會需要訪問一些內部狀態,可以用一個類別吧內部狀態暴露出來。頭文件放在測試文件夾里只供測試使用。這樣既保證了代碼的安全,又可以順利的測試到內部狀態。