第十六章宅粥、UIKit簡(jiǎn)介

UIKit簡(jiǎn)介

  • 之前我們學(xué)習(xí)了如何在OS X平臺(tái)(即Mac操作系統(tǒng))編寫應(yīng)用程序闽寡。
  • 接下來我們學(xué)習(xí)iOS平臺(tái)編寫應(yīng)用程序。
  • Mac應(yīng)用程序使用的是AppKit框架相味,而iOS應(yīng)用程序使用的是UIKit框架拾积,它包含了所有的UI組件和構(gòu)成iOS應(yīng)用程序的資源。

iOS和OS X的不同

  • iOS沒有命令行使權(quán)丰涉,所以我們無法像在OS X上一樣創(chuàng)建命令工具程序
  • iOS沒有shell和控制臺(tái)
  • iOS應(yīng)用程序在Mac電腦的模擬器中運(yùn)行
  • iOS無法支持一些無UI界面的API

源代碼及程序鏈接:https://pan.baidu.com/s/16g1nQ0WGW9LtEIMuvs-D3Q 密碼:xkex

重新構(gòu)建CaseTool

創(chuàng)建項(xiàng)目:

  1. 打開Xcode,選擇iOS下的Single View App拓巧。
  2. 輸入工程名稱,并選擇Next一死。
  3. 產(chǎn)生的界面

Single View Application圖標(biāo)肛度,顧名思義就是這個(gè)程序只顯示一個(gè)視圖。這種類型的應(yīng)用程序通常非常簡(jiǎn)單投慈,用戶界面也很簡(jiǎn)單贤斜。

其它模板的介紹

  • Master-Detail應(yīng)用程序:用一個(gè)導(dǎo)航控制器和一個(gè)表視圖來顯示項(xiàng)目列表以及項(xiàng)目的詳細(xì)信息。
  • Game:用來創(chuàng)建打發(fā)時(shí)間的絕妙游戲逛裤。
  • Page-Based:創(chuàng)建一個(gè)類似書本的應(yīng)用程序瘩绒,它擁有翻頁動(dòng)畫效果(只支持iPad)。
  • Tabbed:用來創(chuàng)建多視圖應(yīng)用程序带族,就像你在iPhone上見到的底部有一個(gè)標(biāo)簽欄并且每個(gè)標(biāo)簽都與一個(gè)視圖有關(guān)聯(lián)的那種應(yīng)用程序锁荔。
  • Utility應(yīng)用程序模板:擁有一個(gè)主視圖,與Single View Application中的相似蝙砌,但是還多出一個(gè)翻轉(zhuǎn)視圖阳堕。
  • Empty應(yīng)用程序是一個(gè)高級(jí)選項(xiàng)跋理,如果沒有合適的模板,或是你非常了解如何構(gòu)建你的應(yīng)用程序恬总,那么可以選擇使用這個(gè)模板前普。

代碼介紹

//AppDelegate.h
#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end
//AppDelegate.m
#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    // Override point for customization after application launch.
    return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}


- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}


@end
  • 我們來看一下應(yīng)用程序委托的頭文件。首先是我們的老朋友#import壹堰,因?yàn)槲覀兪褂玫氖荱IKit框架而不是AppKit框架拭卿,所以iOS界面元素都是以UI為前綴的。
  • 我們還導(dǎo)入了Foundation框架贱纠,它在iOS平臺(tái)上的工作原理與在OS X上的工作原理相似峻厚。因此,像NSString這樣的類在iOS上是有效的谆焊,且使用方式與在OS X平臺(tái)上相似惠桃。
  • 實(shí)現(xiàn)文件的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions系統(tǒng)默認(rèn)提供了一個(gè)窗口對(duì)象和視圖控制器。我們也可以在其中自定義辖试。
  • 如果你是自己定義的辜王,那么你的自定義代碼在窗口創(chuàng)建時(shí)便會(huì)調(diào)用,所有的應(yīng)用程序都是在主窗口內(nèi)運(yùn)行的罐孝。接下來還要?jiǎng)?chuàng)建視圖控制器誓禁。如果使用系統(tǒng)默認(rèn)的,會(huì)有創(chuàng)建好的視圖控制器文件肾档。

視圖控制器

  • 之前說過,Cocoa主要使用的是MVC(Model-View-Controller)模式辫继。確實(shí)怒见,我們?cè)趹?yīng)用程序擁有一個(gè)視圖,一個(gè)控制器以及一組數(shù)據(jù)姑宽。
  • 我們是從nib文件中獲取視圖的遣耍。這種方式非常便利,因?yàn)橥ㄟ^nib文件界面來設(shè)計(jì)和加載視圖要比手動(dòng)來做快得多炮车。
  • 我們的類ViewController是UIViewController的子類舵变。UIViewController知道如何管理視圖,比如將其放在屏幕上瘦穆,調(diào)整大小纪隙,旋轉(zhuǎn),等等扛或。如果想要管理視圖的話绵咱,創(chuàng)建這個(gè)類的子類是非常有必要的。
  • 那為什么不直接使用UIViewController類呢?因?yàn)槲覀冃枰蛞晥D添加一些內(nèi)容熙兔,而UIViewController并不知道有這些東西悲伶,所以我們需要?jiǎng)?chuàng)建它的子類并告訴子類如何處理我們新添加的內(nèi)容艾恼。

在Nib文件中添加控件

  • 打開Main.storyboard,你會(huì)看到以iPhone屏幕為尺寸顯示的應(yīng)用程序視圖麸锉。你會(huì)看到钠绍,庫對(duì)象面板中顯示的內(nèi)容都是針對(duì)iOS平臺(tái)的
  • 下面我們開始編輯nib文件。從右下角的對(duì)象面板中選擇一個(gè)TextField對(duì)象并將其拖動(dòng)到視圖中花沉。調(diào)整其大小以適應(yīng)屏幕寬度柳爽,調(diào)整大小時(shí)可以參考引導(dǎo)線。
  • 接下來主穗,我們將一個(gè)label對(duì)象拖出并放入視圖中泻拦,然后調(diào)整其大小。
  • 下一步是添加一個(gè)按鈕忽媒。在對(duì)象面板中選擇Button圖標(biāo)争拐,并將其拖動(dòng)到視圖中文本框和標(biāo)簽的下面。按鈕完成以后晦雨,調(diào)整按鈕大小使其能夠匹配文本框的寬度架曹。雙擊圓角按鈕并給它命名,我們可以叫它UpperCase闹瞧。
  • 同樣的绑雄,我們繼續(xù)添加一個(gè)按鈕,并將其放在第一個(gè)按鈕的下方奥邮,調(diào)整其大小使它看上去與第一個(gè)按鈕相似万牺,并給它命名為LowerCase。

創(chuàng)建連接

  • 在頭文件的@interface和@end之間的位置放開鼠標(biāo)洽腺,Xcode就會(huì)彈出這樣的窗口脚粟。
  • 窗口要求你填入輸出口的名稱。不過在這之前蘸朋,請(qǐng)注意Object旁邊的文字是File's Owner核无。這是什么意思呢?其實(shí)在你加載nib文件的時(shí)候,會(huì)有一個(gè)控制器作為它的擁有者藕坯。
  • 當(dāng)通過模板自動(dòng)創(chuàng)建nib文件和控制器時(shí)团南,它會(huì)讓控制器成為nib文件的擁有者。如果你需要的話炼彪,可以在nib文件中選擇File's Owner圖標(biāo)并更改它的類吐根。

1連接輸出口(IBOutlet)

  • Xcode窗口的右上角有三個(gè)標(biāo)記為Editor的按鈕,點(diǎn)擊中間的按鈕辐马,就會(huì)將編輯器從中間垂直分成兩部分佑惠,這就是輔助編輯器。
  • 接下來,按住Control鍵并將光標(biāo)拖動(dòng)到頭文件膜楷,出現(xiàn)“Insert Outlet or Action”提示消息再松手旭咽。松開鼠標(biāo)會(huì)彈出如上圖的一個(gè)對(duì)話框崔挖。
  • 對(duì)話框第一項(xiàng)是選擇Outlet還是Action礁竞,第二項(xiàng)是Name文本框,我們輸入“textField”,并點(diǎn)擊Connect按鈕嘶朱。這樣做會(huì)在頭文件中創(chuàng)建“textField”屬性特愿。
  • 接下來對(duì)標(biāo)簽(label)重復(fù)之前的連接步驟并將其命名為“resultField”仲墨。

2連接操作(IBAction)

  • 現(xiàn)在,我們將代碼連接到操作揍障,這樣按下按鈕就會(huì)觸發(fā)代碼
  • 按住Control鍵并拖動(dòng)鼠標(biāo)到頭文件目养,連接對(duì)話框會(huì)再次彈出。這次毒嫡,要將連接類型改成Action癌蚁。在Name文本框中輸入U(xiǎn)pperCase,并點(diǎn)擊Connect按鈕兜畸。
  • 上面的操作將會(huì)在頭文件中創(chuàng)建方法的聲明努释,并會(huì)在.m文件中創(chuàng)建方法的實(shí)現(xiàn)(內(nèi)容為空)。
  • 現(xiàn)在咬摇,只要單擊該按鈕伐蒂,UpperCase:消息就會(huì)如我們所想的那樣發(fā)送給ViewController。我們可以在其中UpperCase執(zhí)行任何想要的代碼肛鹏。
  • 最后連接LowerCase按鈕逸邦,按住Control鍵并拖動(dòng)鼠標(biāo)到頭文件,將連接類型改成Action在扰,連接名稱設(shè)為“LowerCase”

Connection對(duì)話框中各項(xiàng)的信息

  • Name(名稱):該項(xiàng)包含了我們正在創(chuàng)建的操作的名稱缕减。
  • Type(類型):操作方法參數(shù)的類名稱。默認(rèn)情況下這個(gè)值是id(泛型類)健田,不過你可以將其改成發(fā)送消息給操作的任何類。在我們這個(gè)例子中佛纫,發(fā)送消息給操作的是一個(gè)UIButton類妓局。
  • Event(事件):在OS X和iOS平臺(tái)之間有很大的不同,在iOS中有非常多的事件類型呈宇,都是由于觸摸界面引起的好爬。在這個(gè)例子中,我們打算使用Touch Up Inside事件甥啄。這意味著存炮,當(dāng)手指還在按鈕上時(shí)停止屏幕觸摸,便會(huì)調(diào)用按鈕的操作方法
  • Arguements(參數(shù)):在OS X應(yīng)用程序中,沒有Arguements選項(xiàng)穆桂,因?yàn)樗械牟僮鞫贾挥幸粋€(gè)參數(shù)宫盔。在iOS環(huán)境下,我們有三種參數(shù)可以選擇:None享完,Sender(OS X上的默認(rèn)選項(xiàng))和Event(包含一個(gè)UIEvent參數(shù)灼芭,你可以通過它來決定應(yīng)該做什么)。我們將為操作選擇None般又。

手動(dòng)添加代碼

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (nil != self) {
        NSLog(@"init: text %@/ result %@",_textField,_resultsField);
    }
    return self;
}

- (void)awakeFromNib{
    [super awakeFromNib];
    NSLog(@"awake: text %@/ result %@",_textField,_resultsField);
}
  • - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil這個(gè)方法是父類的方法彼绷,因此,我們不需要去實(shí)現(xiàn)它茴迁。我們調(diào)用這個(gè)代碼以加載nib文件來訪問輸出口寄悯。
  • 視圖控制器會(huì)在nib文件加載和對(duì)象初始化完成后調(diào)用viewDidLoad方法。一些較早版本的iOS系統(tǒng)還會(huì)調(diào)用awakeFromNib方法堕义,不過在iOS 5中猜旬,已經(jīng)不再調(diào)用了。

主要代碼實(shí)現(xiàn)

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    //更改背景
    self.view.backgroundColor = [UIColor greenColor];
    //初始化文本數(shù)據(jù)
    [_textField setPlaceholder:@"Enter text here"];
    _resultsField.text = @"Results";
}
  • 我們將為viewDidLoad方法添加一些簡(jiǎn)單的實(shí)現(xiàn)胳螟。通常它們都是用來修改輸出口和設(shè)置其它UI用的昔馋,當(dāng)viewDidLoad方法調(diào)用了,你便能確定你的nib文件已經(jīng)加完畢了糖耸。我們打算使用這個(gè)方法來設(shè)置一些文本框的默認(rèn)值秘遏。
  • 這段代碼設(shè)定了textField文本框的占位符,它是在用戶向文本框輸入內(nèi)容前顯示的灰色文本嘉竟。我們還要設(shè)置標(biāo)簽的默認(rèn)值邦危,以便用戶知道這里將能看到轉(zhuǎn)化后的結(jié)果。
  • 在代碼的后面舍扰,你將會(huì)看到viewDidLoad方法倦蚪。視圖從視圖層級(jí)中移除后會(huì)調(diào)用這個(gè)方法。為什么要在意這些細(xì)節(jié)呢边苹?為了保護(hù)內(nèi)存不被泄露陵且。
  • iOS不支持虛擬內(nèi)存。應(yīng)用程序只能使用設(shè)備中可用的內(nèi)存个束。此外如果使用了太多的內(nèi)存慕购,iOS將會(huì)強(qiáng)行退出應(yīng)用程序以示抗議。我們通過viewDidLoad方法在事后清理內(nèi)存茬底。
  • 在iOS(尤其是iPhone)應(yīng)用程序中沪悲,大多數(shù)情況下,一個(gè)視圖離開后另一個(gè)視圖會(huì)來填滿屏幕阱表。這時(shí)殿如,先前的那個(gè)視圖便看不到了贡珊,因此就不需要再保留它了。
  • iOS需要卸載視圖來節(jié)約內(nèi)存涉馁,所以viewDidLoad方法可以幫我們移除視圖上的各項(xiàng)內(nèi)容以節(jié)約一些內(nèi)存门岔,在這個(gè)示例中,我們移除了textField和resultsField控件谨胞。這兩個(gè)方法(viewDidLoad和viewDidUnLoad)在視圖的聲明周期內(nèi)只會(huì)調(diào)用到一次固歪。
  • 還有四個(gè)方法(viewWillAppear:、viewDidAppear:胯努、viewWillDisAppear:牢裳、viewDidDisAppear:)也會(huì)在視圖離開或出現(xiàn)的時(shí)候得到調(diào)用。每當(dāng)條件合適的時(shí)候他們就會(huì)被調(diào)用叶沛,即便視圖沒有被卸載蒲讯。
//實(shí)際執(zhí)行大小寫轉(zhuǎn)化的代碼
- (IBAction)uppercase:(id)sender {
    //獲取
    NSString *original = _textField.text;
    //改變
    NSString *uppercase = [original uppercaseString];
    //傳遞
    _resultsField.text = uppercase;
}

- (IBAction)lowercase:(id)sender {
    //獲取
    NSString *original = _textField.text;
    //改變
    NSString *lowercase = [original lowercaseString];
    //傳遞
    _resultsField.text = lowercase;
}
  • 對(duì)于iOS的文本框,我們使用一個(gè)NSString方法來轉(zhuǎn)換它的文本灰署,將標(biāo)簽的文本值設(shè)置為修改后的字符串判帮。就像在OS X上的那個(gè)應(yīng)用一樣,我們?cè)谶@個(gè)例子中使用了stringValue和setStringValue:方法溉箕。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末晦墙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子肴茄,更是在濱河造成了極大的恐慌晌畅,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寡痰,死亡現(xiàn)場(chǎng)離奇詭異抗楔,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)拦坠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門连躏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贞滨,你說我怎么就攤上這事入热。” “怎么了晓铆?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵勺良,是天一觀的道長。 經(jīng)常有香客問我尤蒿,道長郑气,這世上最難降的妖魔是什么幅垮? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任腰池,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘示弓。我一直安慰自己讳侨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布奏属。 她就那樣靜靜地躺著跨跨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪囱皿。 梳的紋絲不亂的頭發(fā)上勇婴,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音嘱腥,去河邊找鬼耕渴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛齿兔,可吹牛的內(nèi)容都是我干的橱脸。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼分苇,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼添诉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起医寿,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤栏赴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后糟红,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體艾帐,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年盆偿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了柒爸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡事扭,死狀恐怖捎稚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情求橄,我是刑警寧澤今野,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站罐农,受9級(jí)特大地震影響条霜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜涵亏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一宰睡、第九天 我趴在偏房一處隱蔽的房頂上張望蒲凶。 院中可真熱鬧,春花似錦拆内、人聲如沸旋圆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灵巧。三九已至,卻和暖如春抹沪,著一層夾襖步出監(jiān)牢的瞬間刻肄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來泰國打工融欧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留肄方,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓蹬癌,卻偏偏與公主長得像权她,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子逝薪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 關(guān)于資源 適用于計(jì)算機(jī)程序的資源是與程序可執(zhí)行代碼相關(guān)的數(shù)據(jù)文件隅要。資源可以通過將代碼之外的復(fù)雜數(shù)據(jù)集或圖形內(nèi)容創(chuàng)建...
    nicedayCoco閱讀 640評(píng)論 0 0
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件董济、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,123評(píng)論 4 61
  • 譯者注:本文是對(duì) Apple 官方文檔的翻譯步清,原文地址為:https://developer.apple.com/...
    ampire_dan閱讀 7,443評(píng)論 0 13
  • 一只會(huì)說話的小狗錢錢教一個(gè)12歲的女孩理財(cái)方法,小女孩不僅學(xué)會(huì)了與錢打交道的方法而且也幫助父母擺脫了財(cái)務(wù)危機(jī)虏肾。 一...
    筆墨傳情閱讀 233評(píng)論 0 1
  • 路由對(duì)象$router 路由跳轉(zhuǎn)方法:push() 語法:$router.push('url') 分寫與合寫方式的...
    xlayzheng閱讀 5,618評(píng)論 0 0