iOS開發系列--IOS程序開發概覽

概覽

終於到了真正接觸IOS應用程序的時刻了,以前咱們花了不少時間去討論C語言、ObjC等知識,對於不少朋友而言開發IOS第一天就想直接看到成果,看到能夠運行的IOS程序。可是這裏我想強調一下,前面的知識是你往後開發IOS的基礎,沒有那些知識你開發IOS會很痛苦,如今不少開發人員作開發都是隻知其一;不知其二,程序質量確實使人擔心,因此仍是但願你們可以熟練掌握前面的內容,開發過程當中多思考,完全理解程序運行的原理、機制。好了言歸正傳,無論怎麼樣正式進入IOS開發仍是使人興奮的,今天的內容雖說是開發預覽,其實仍是有大量內容要說的:html

  1. 第一個iOS程序
  2. iOS程序運行過程
  3. 文件結構
  4. Storyboard
  5. 純代碼實現iOS開發
  6. 補充知識點

第一個iOS程序

首先打開Xcode—Create a new Xcode project—Single View Application--輸入項目名稱,同時選擇使用Objective-C語言,設備選擇iPhone--接下來系統默認生成一個IOS項目模板。項目目錄結構以下:ios

firstios

此時什麼也不用作,直接運行看一下(注意這裏已經切換模擬器爲iPhone5),沒錯咱們看到了一個iOS應用程序:json

firstIOS-iPhone5

程序的運行過程

在幾乎全部的程序開發中程序通常都是從main函數開始運行的,那麼IOS程序也不例外,在上圖中咱們能夠看到Xcode爲咱們生成了一個main.m文件:windows

//
//  main.m
//  FirstIOS
//
//  Created by Kenshin Cui on 14-2-23.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

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

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

這個默認的iOS程序就是從main函數開始執行的,可是在main函數中咱們其實只能看到一個方法,這個方法內部是一個消息循環(至關於一個死循環),所以運行到這個方法UIApplicationMain以後程序不會自動退出,而只有當用戶手動關閉程序這個循環才結束。這個方法有四個參數:微信

  • 第一個參數和第二個參數其實就是main函數的參數,分別表明:參數個數、參數內容;
  • 第三個參數表明UIApplication類(或子類)字符串,這個參數默認爲nil則表明默認爲UIApplication類,用戶能夠自定義一個類繼承於這個類;若是爲nil則等價於NSStringFromClass([UIApplication class]),你們能夠本身試驗,效果徹底同樣;UIApplication是單例模式,一個應用程序只有一個UIApplication對象或子對象;
  • 第四個參數是UIApplication的代理類字符串,默認生成的是AppDelegate類,這個類主要用於監聽整個應用程序生命週期的各個事件(其實相似於以前咱們文章中提到的事件監聽代理),當UIApplication運行過程當中引起了某個事件以後會調用代理中對應的方法;

小技巧:app

其實在Xcode中若是要看一些系統方法的解釋或者參數說明,能夠直接鼠標放到這個方法上,在Xcode右側面板中就會給出幫助提示,以下圖當咱們放到UIApplicationMain上以後:ide

quickHelp

也就是說當執行UIApplicationMain方法後這個方法會根據第三個參數建立對應的UIApplication對象,這個對象會根據第四個參數AppDelegate建立並指定此對象爲UIApplication的代理;同時UIApplication會開啓一個消息循環不斷監聽應用程序的各個活動,當應用程序生命週期發生改變UIApplication就會調用代理對應的方法。函數

既然應用程序UIApplication是經過代理和外部交互的,那麼咱們就有必要清楚AppDelegate的操做細節,下面是UIApplication詳細的代碼:工具

AppDelegate.h佈局

//
//  AppDelegate.h
//  
//
//  Created by Kenshin Cui on 14-2-23.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

AppDelegate.m

//
//  AppDelegate.m
//  
//
//  Created by Kenshin Cui on 14-2-23.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import "AppDelegate.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    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 throttle down OpenGL ES frame rates. 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 inactive 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

這個類中定義了應用程序生命週期中各個事件的執行方法:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;程序啓動以後執行,只有在第一次程序啓動後才執行,之後再也不執行;

- (void)applicationWillResignActive:(UIApplication *)application;程序將要被激活時(得到焦點)執行,程序激活用戶才能操做;

- (void)applicationDidEnterBackground:(UIApplication *)application;程序進入後臺後執行,注意進入後臺時會先失去焦點再進入後臺;

- (void)applicationWillEnterForeground:(UIApplication *)application;程序將要進入前臺時執行;

- (void)applicationDidBecomeActive:(UIApplication *)application;程序被激活(得到焦點)後執行,注意程序被激活時會先進入前臺再被激活;

- (void)applicationWillTerminate:(UIApplication *)application;程序在終止時執行,包括正常終止或異常終止,例如說一個應用程序在後太運行(例如音樂播放軟件、社交軟件等)佔用太多內存這時會意外終止調用此方法;

爲了演示程序的生命週期,不妨在每一個事件中都輸出一段內容,簡單調整上面的代碼:

AppDelegate.m

//
//  AppDelegate.m
//  FirstIOS
//
//  Created by Kenshin Cui on 14-2-23.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate
            

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    NSLog(@"程序已經啓動...");
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {
    NSLog(@"程序將要失去焦點...");
    // 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 throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    NSLog(@"程序已經進入後臺...");
    // 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 {
    NSLog(@"程序將要進入前臺...");
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    NSLog(@"程序已經得到焦點...");
    // 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 {
    NSLog(@"程序將要終止...");
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application{
    
}

@end

下面是各個不一樣操做的運行結果:

runProgress

相信經過上面運行過程你們會對整個運行週期有個大概瞭解。比較容易混淆的地方就是應用程序進入前臺、激活、失去焦點、進入後臺,這幾個方法你們要清楚。若是一個應用程序失去焦點那麼意味着用戶當前沒法進行交互操做,所以通常會先失去焦點再進入後臺防止進入後臺過程當中用戶誤操做;若是一個應用程序進入前臺也是相似的,會先進入前臺再得到焦點,這樣進入前臺過程當中未徹底準備好的狀況下用戶沒法操做。另一般若是應用程序要保存用戶數據會在註銷激活中進行(而不是在進入後臺方法中進行),由於若是用戶雙擊Home不會進入後臺只會註銷激活;若是用戶恢復應用狀態通常在進入激活狀態時處理(而不是在進入前臺方法中進行),由於用戶多是從任務欄直接返回應用,此時不會執行進入前臺操做。

固然,上面的事件並非全部AppDelegate事件,而是最經常使用的一些事件,其餘事件你們能夠查閱官方文檔,例如-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application;用於在內存佔用過多發出內存警告時調用並通知對應的ViewController調用其內存回收方法。這裏簡單以圖形方式描述一下應用程序的調用過程:

 image

文件結構

這裏對於Xcode默認爲咱們生產的項目結果文件作一下簡單介紹:

  1. AppDelegate(.h/.m):應用程序代理,主要用於監聽整個應用程序生命週期中各個階段的事件;
  2. ViewController(.h/.m):視圖控制器,主要負責管理UIView的生命週期、負責UIView之間的切換、對UIView事件進行監聽等;
  3. Main.storyboard:界面佈局文件,承載對應UIView的視圖控件;
  4. Images.xcassets:應用程序圖像資源文件;
  5. Info.plist:應用程序配置文件;
  6. main.m:應用程序入口函數文件;
  7. xxx-prefix.pch:項目公共頭文件,此文件中的導入語句在編譯時會應用到全部的類文件中,至關於公共引入文件(注意在Xcode6中沒有提供此文件)

Images.xcassets

關於AppDelegate、main.m前面已經介紹過了,ViewController和Main.storyboard在後面介紹,這裏先說一下Image.xcassets文件。在Xcode中打開這個文件會發現裏面有兩個設置項:AppIcon和LaunchImage

AppIcon

AppIcon

在AppIcon中能夠看到三個圖標設置,當咱們勾選了右側ios6.1 and Prior Sizes或者其餘選項這個圖標會自動增多,也就是說能夠設計的圖標跟應用程序準備支持的設備系統有關,這裏咱們就以默認的ios7爲例(如今基本上設備都升級到ios7了):

a.iPhone Spotlight-iOS5,6 Settings-iOS 5-7 29pt:用於設置iOS5或者iOS6的搜索圖標以及iOS五、iOS六、iOS7的設置圖標,大小是58*58。

iOS搜索圖標:

 Spotlight

iOS設置圖標:

settingicon

b.iPhone Spootlight iOS 7 40pt:設置iOS7的搜索圖標,大小是80*80。具體參見上圖。

c.iPhone App iOS7 60pt:設置iOS7的應用圖標,大小是120*120。

iOS應用圖標:

 IconSettings

LaunchImage

在LaunchImage中兩個圖標設計主要用於豎屏啓動圖

LaunchImage

a.iPhone Portraint iOS7 2x:大小爲640*1136的啓動圖片;

b.iPhone Portraint iOS7 R4:大小爲640*960的啓動圖片;

其實上面的圖片並非全部圖片都必須設置,具體要求能夠直接查看蘋果官方要求,例如這裏咱們設置應用圖標和R4啓動圖片後具體效果以下(這裏使用的圖標取材來自微信):

appico

launch

上面咱們添加了一個應用圖標和一個啓動圖片,在Images.xcassets上右鍵在Fiddler中查看文件內容並進入Images.xcassets文件夾,能夠看到兩個子文件夾:AppIcon.appiconset和LaunchImage.launchimage,以下圖:

ImagesXcassets

兩個文件夾中分別存放了咱們前面設置的圖片資源,除此以外還各有一個Contents.json文件,在這個文件中記錄的資源信息,例如AppIcon.appiconset文件夾中的Contents.json內容以下,這裏記錄了每一個圖標的大小名稱等信息:

ContentsJson 

Info.plist

Info.plist文件記錄了應用程序的配置信息,以下圖:

InfoPlist

其實這些信息咱們能夠在項目屬性中進行配置,效果和編輯這個文檔是同樣的,你們能夠對照查看:

GeneralSetting 

Storyboard

到目前爲止咱們尚未解釋咱們的程序是如何顯示默認視圖界面的。作過WinForm程序的朋友都知道每一個Window窗口界面都有一個設計器(對應一個設計文件),其實在IOS中也能夠經過設計工具設計界面不用編寫代碼,這個工具就是Interface Builder。用Interface Builder編輯的文件在iOS5以前是一個「.xib」文件,從IOS5開始進行了改進,使用「.storyboard」文件進行設計。其實在上面咱們已經看到這個文件,這裏重點說明一下Storyboard文件的使用。

首先咱們打開Main.storyboard,此時能夠看到一個Interface Builder界面設計器出如今咱們眼前:

storyboard

在這個界面中整個核心就是右側視圖控制器ViewController,在ViewController中有一個視圖UIView,這個視圖用來放置其餘用戶操做控件。視圖控制器左側的箭頭表示這個視圖控制器是個主視圖控制器,程序啓動以後默認就會直接顯示這個視圖控制器的視圖。咱們能夠在項目屬性中經過修改「Main Interface」屬性來修改主視圖控制器。

這裏咱們不妨從Xcode右側工具欄Object Library中拖放一些組件在上面簡單完成一個登陸佈局。

layout

要實現這個登陸,那麼接下來就是事件和屬性綁定的問題,你們應該能夠猜到登陸的邏輯代碼確定在ViewController.m中編寫,那麼storyboard文件是如何關聯到這個類的呢?若是咱們在storyboard界面選中ViewController在Xcode右側切換到Identity Inspector視圖就會發現裏面當前設置的是ViewController類,經過這個設置Main.storyboard和ViewController關聯在一塊兒。

那麼如何在代碼中讀取兩個TextField的值並經過點擊按鈕觸發相關事件驗證登陸合法性呢?要想在代碼中使用UITextField,而且添加按鈕點擊事件,則必須在ViewController.h中定義兩個UITextField屬性和一個登陸方法。

ViewController

上面代碼咱們須要解釋一下IBOutlet、IBAction,其他代碼和咱們以前寫的ObjC沒有任何區別。

  • IBOutlet:IBOutlet沒有作任何操做,它的惟一做用就是告訴Interface Builder這個屬性能夠被關聯到其中某個控件(在代碼中能夠看到代碼前面多了空心圓點)。
  • IBAction:其實就是void,只是當你定義爲IBAction在Interface Builder中能夠關聯到某個控件的事件方法(後面的關聯操做將會看到,並且咱們在代碼中也能夠看到代碼前面多了空心圓點);

下面看一下storyboard中的控件和代碼中定義的屬性和事件如何關聯。Xcode爲咱們提供了幾種方式來實現代碼和storyboard控件的關聯:

1.拖拽控件到代碼中(首先點擊Xcode右上方「Show the Assistant editor」切換對應視圖,而後在代碼中打開.h文件,同時打開Interface Builder,按住ctrl鍵拖拽控件到代碼中相應的位置進行關聯),關聯後屬性或方法前的空心圓變成實心表示已經關聯到具體控件(注意:事實上,從控件拖拽到代碼時若是代碼中沒有定義對應的屬性和方法Interface Builder會自動生成代碼)。

controlToCode

2.從控件場景中拖拽控件到代碼,關聯後屬性或方法前的空心圓變成實心表示已經關聯到具體控件。(在Interface Builder中點擊左下角「Show Document outline」顯示控件結構樹,選中相應的控件按住Ctrl鍵拖拽到代碼中的屬性或方法上)

controlSceneToCode

3. 在控件上右鍵找到對應的屬性或方法關聯到代碼中對應的屬性或方法便可,關聯後屬性或方法前的空心圓變成實心表示已經關聯到具體控件。

propertyToCode.gif

4.與方法3相似,再也不截圖,只是經過View Control Scene中的控件右鍵來關聯,關聯後屬性或方法前的空心圓變成實心表示已經關聯到具體控件。(在Interface Builder中點擊左下角Show Document outline顯示控件結構樹,選中相應的控件右鍵拖拽到代碼中的屬性或方法上)

5.對於前面幾種方法其實咱們還能夠直接從代碼拖拽到控件上面,這裏簡單演示一種,其餘狀況你們能夠本身試驗。

codeToControl.gif

 

若是要刪除關聯,能夠採用第3、第四種方式在控件上右鍵,在關聯菜單中找到對應的關聯刪除便可。此外須要注意對於一個控件而言可能有多個事件,當咱們使用第三種或第四種方式直接選擇具體某個事件關聯到login:方法天然沒有問題,可是第1、第2、第五種方式沒有提示咱們關聯到哪一個事件而是使用一個控件的默認事件(對於UIButton就是Touch Up Inside事件)。

既然控件和代碼屬性或方法已經作了關聯,這裏咱們看一下具體效果,這裏簡單修改一下ViewController.m

//
//  ViewController.m
//  FirstIOS
//
//  Created by Kenshin Cui on 14-2-23.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
            
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)login:(UIButton *)btn{
    if ([_phoneNumber.text isEqual:@"123"]&&[_password.text isEqual:@"456"]) {
        NSLog(@"登陸成功!");
    }
}

@end

這裏實現了login:方法模擬登陸的過程,能夠發現當在手機號碼中輸入「123」,在密碼中輸入「456」點擊登陸會輸出」登陸成功!「。

純代碼實現iOS開發

storyboard進行界面設計當然不錯,特別是對於初學者常常會使用設計器進行界面設計,可是實際開發過程當中咱們不少狀況下會直接使用代碼進行界面佈局,特別是對於複雜的界面佈局更是如此。下面咱們就從一個空項目創建一個相似於前面的登陸界面。

直接在Xcode中建立「Empty Application」(注意在Xcode6中這個選項已經沒有了,這裏採用Xcode5.1),此時會發現已經沒有ViewController和storyboard文件,咱們須要手動建立一個視圖控制器(在項目中右鍵選擇Objective-c class,默認繼承自UIViewController,輸入類名:KCMainViewController便可)。

新建的視圖控制器默認狀況下是沒法加載到程序運行界面上的,此時須要在應用程序代理的程序加載完畢事件中手動加載並顯示咱們的視圖。修改以前KCAppDelegate.m代碼以下:

//  KCAppDelegate.m
//  IOSByCode
//
//  Created by Kenshin Cui on 14-2-23.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import "KCAppDelegate.h"

@implementation KCAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    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 throttle down OpenGL ES frame rates. 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 inactive 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

咱們修改上面- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions的代碼以下:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //設置window屬性(在KCAppDelegate中定義的window屬性),初始化windows的大小和位置
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    //設置window的背景
    self.window.backgroundColor = [UIColor whiteColor];
    
    //初始化KCMainViewController
    KCMainViewController *mainController=[[KCMainViewController alloc]init];
    //設置自定義控制器的大小和window相同,位置爲(0,0)
    mainController.view.frame=self.window.bounds;
    //設置此控制器爲window的根控制器
    self.window.rootViewController=mainController;
    
    //設置window爲應用程序主窗口並設爲可見
    [self.window makeKeyAndVisible];
    return YES;
}

而後在咱們自定義的KCMainViewController.m中添加一個UIImageView、兩個控件UITextField和一個UIButton控件,而且實現具體的登陸方法。

KCMainViewController.h

//
//  KCMainViewController.h
//  IOSByCode
//
//  Created by Kenshin Cui on 14-2-23.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface KCMainViewController : UIViewController

#pragma mark logo
@property (nonatomic,strong) UIImageView *logo;
#pragma mark 手機號碼
@property (nonatomic,strong) UITextField *phoneNumber;
#pragma mark 密碼
@property (nonatomic,strong) UITextField *password;
#pragma mark 登陸按鈕
@property (nonatomic,strong) UIButton *loginButton;

#pragma mark 點擊事件
-(void)login:(UIButton *)btn;

@end

KCMainViewController.m

//
//  KCMainViewController.m
//  IOSByCode
//
//  Created by Kenshin Cui on 14-2-23.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import "KCMainViewController.h"

@interface KCMainViewController ()

@end

@implementation KCMainViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //self.view.backgroundColor=[UIColor redColor];
    
    //添加圖片
    CGRect logoRect=CGRectMake(100, 50, 100, 200);
    _logo=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"LoginBackground.png"]];//設置圖片
    _logo.contentMode=UIViewContentModeScaleAspectFit;//設置內容填充模式
    _logo.frame=logoRect;//設置控件大小和位置(相對於父控件的位置)
    [self.view addSubview:_logo];//添加到KCMainViewController的View中
    
    //添加手機號碼輸入框
    CGRect phoneNumberRect=CGRectMake(20, 320, 280, 30);
    _phoneNumber=[[UITextField alloc]initWithFrame:phoneNumberRect];
    _phoneNumber.borderStyle=UITextBorderStyleRoundedRect;//設置文本框的邊框樣式
    [self.view addSubview:_phoneNumber];
    
    //添加密碼輸入框
    CGRect passwordRect=CGRectMake(20, 380, 280, 30);
    _password=[[UITextField alloc]initWithFrame:passwordRect];
    _password.borderStyle=UITextBorderStyleRoundedRect;
    [self.view addSubview:_password];
    
    //添加登陸按鈕
    CGRect loginButtonRect=CGRectMake(10, 440, 300, 25);
    _loginButton=[[UIButton alloc]initWithFrame:loginButtonRect];
    [_loginButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];//設置標題內容顏色
    [_loginButton setTitle:@"登陸" forState:UIControlStateNormal];//設置按鈕標題
    [_loginButton addTarget:self action:@selector(login:) forControlEvents:UIControlEventTouchUpInside];//添加點擊事件
    [self.view addSubview:_loginButton];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)login:(UIButton *)btn{
    if ([_phoneNumber.text isEqual:@"123"]&&[_password.text isEqual:@"456"]) {
        NSLog(@"登陸成功!");
    }else{
        NSLog(@"登陸失敗!");
    }
}


@end

運行效果以下,與以前使用storyboard建立的界面相似,同時也能點擊登陸:

runUI

UIView

在這裏咱們須要對上面的代碼同樣解釋,在弄清上面的代碼以前咱們不得不熟悉一個UIKit中最重要的類UIView。

  1. UIView就是指界面可見的控件元素,全部的控件最終都繼承自UIView,UIView中還能夠添加其餘UIView(經過addSubView方法);
  2. 在一個iOS應用中必須有一個主窗口UIWindow(理論上也能夠有多個UIWindow可是隻有一個是主Window,並且只有主Window能夠和用戶交互),UIWindow也是繼承自UIView,它擁有UIView的全部屬性、方法;
  3. 在UIWindow中必須有一個根控制器,這個控制器距離UIWindow是最近的;設置一個控制器爲根控制器和直接經過addSubView添加控制器的視圖(view屬性)到window並不徹底同樣(例如若是僅僅添加控制器視圖那麼應用雖然能夠顯示可是不支持旋轉);
  4. UIViewController是視圖控制器,主要用來控制UIView,在UIViewController內部有一個UIView(view屬性);

在上面的代碼中咱們首先在應用程序加載完畢以後加載一個UIWindow對象,同時把咱們的視圖控制器KCMainController設置爲UIWindow的根視圖控制器,而後設置這個UIWindow爲主窗口並可見。當主窗口設置爲可見過程當中會調用視圖控制器的loadView方法來加載視圖(注意視圖控制器的loadView方法是延遲加載的,第一次調用視圖控制器的view屬性纔會調用此方法;因爲makeKeyAndVisible方法中會使用視圖控制器的view屬性因此此時會調用視圖控制器的loadView方法),視圖加載完以後調用viewDidLoad方法,在這個方法中咱們添加登陸相關控件並將這些控件加載到視圖控制器KCMainViewController的視圖view中。

下面咱們看一下應用程序最終的佈局,相信經過這張圖你們對於iOS的佈局會有一個大體瞭解:

iOSLayout

補充知識點

1.iOS尺寸設置--在iOS中尺寸的單位是點不是像素,在retina屏幕中一個點有兩個像素。此外在retina屏幕中圖片通常採用」xxx@2x.png」命名,在代碼中使用時只須要寫成「xxx.png」程序會自動根據屏幕類型在retain屏幕下使用」xxx@2x.png」圖片,在非retain屏幕下采用」xxx.png」圖片。                                                   

ScreenSize

2.應用程序圖像資源尺寸--其實關於圖片尺寸規定咱們能夠直接查看Xcode自帶幫助文檔,例如能夠查看「Icon and Image Sizes」一節得到圖片大小說明:

IconSize

關於iOS圖標命名這裏再也不贅述,蘋果官方也給出了具體的代碼示例:Application Icons and Launch Images for iOS

3.模擬器文件存儲的位置--模擬器中爲何能夠運行咱們的程序,程序到底在什麼位置?

這些文件其實在Mac中 OS X中是隱藏的,首先經過「defaults write com.apple.finder AppleShowAllFiles -bool true」命令顯示隱藏文件(關閉隱藏文件顯示經過「defaults write com.apple.finder AppleShowAllFiles -bool false」命令),而後到「/Users/kenshincui/Library/Application Support/iPhone Simulator/7.1/Applications」文件夾中會看到不少GUID命名的文件夾,只要一個一個查看就能夠找到咱們的程序。模擬器運行時會加載這個文件夾中的應用程序包顯示到模擬器中。

bundle

能夠看到在上圖中有一個IOSByCode的應用程序包,咱們能夠經過「顯示包內容」查看具體程序資源:

bundleContent

4.UIApplication--前面一直提到UIApplication對象,這個對象在iOS中是一個單例,咱們經過[UIApplication sharedApplication]得到(注意在iOS開發中通常以shared開頭的對象都是單例)。這裏列舉一些UIApplication的經常使用方法:

UIApplicationMethods

例如調用applicationIconBadgeNumber方法以後效果以下:

badgeNumber

5.組織標示--前面咱們在新建項目中有一個「Organization Identifier」是作什麼的呢?它是組織惟一標示,通常咱們會使用公司的域名形式(這個域名通常會倒序書寫,例如公司域名爲:www.cmjstudio.com,咱們這裏就寫成com.cmjstudio),和項目名稱共同組成一個程序的惟一標示「Bundle Identifier」,這個標示在整個App Store中是惟一的,若是兩個應用程序標示徹底同樣,那麼安裝時會先卸載前面的程序再安裝新程序。

相關文章
相關標籤/搜索