初識iOS APP開發(fā)####
在iOS APP開發(fā)中, main函數(shù)仍是程序的入口和出口, 但main函數(shù)不需要程序員手動去實現(xiàn), 系統(tǒng)已經(jīng)自動實現(xiàn)页衙。接下來介紹關于main.m文件中的一些知識:
首先導入 UIKit/UIKit.h 和 AppDelegate.h
UIKit是系統(tǒng)的一個框架, 里面包含了iOS應用開發(fā)中幾乎所有的視圖控件相關的類和其他的一些常用的類; 也包含了Foundation庫; AppDelegate.h遵守UIApplicationDelegate協(xié)議的類-
main函數(shù)中調(diào)用UIApplicationMain函數(shù)
UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
1> 第一個和第二個參數(shù): 系統(tǒng)參數(shù)2> 第三個參數(shù): 需要傳入一個UIApplication的子類, 在UIApplicationMain中會創(chuàng)建這個類的對象, 用來檢測應用程序的狀態(tài), 用來檢測應用程序的狀態(tài)的改變; 如果傳入nil, 那么UIApplicationMain中就會創(chuàng)建一個UIApplication的對象用來檢測應用程序狀態(tài)發(fā)生改變后, 通知UIApplication的代理來處理這些事件的改變
3> 第四個參數(shù): 遵守UIApplicationDelegate協(xié)議的類, 作用是用來處理應用程序狀態(tài)發(fā)生改變的事件。 UIApplication的對象用來檢測應用程序的狀態(tài)發(fā)生改變。NSStringFromClass(類): 講一個類轉(zhuǎn)換成字符串
iOS應用程序?qū)嵸|(zhì)是一個死循環(huán), iOS編程的實質(zhì)就是實現(xiàn)UIApplicationDelegate協(xié)議的協(xié)議方法
AppDelegate常見的協(xié)議方法####
- 方法1: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
- 作用: 這個方法是應用程序啟動成功后調(diào)用, 可以看做是iOS程序真正的入口, 在這個方法中實現(xiàn)應用程序的所有功能(包括數(shù)據(jù)下載刷喜、數(shù)據(jù)解析鳞青、數(shù)據(jù)顯示)
- 參數(shù)1: 當前應用程序?qū)ο?委托)
- 參數(shù)2: 加載選項
- 方法2: - (void)applicationWillResignActive:(UIApplication *)application;
- 作用: 應用程序?qū)⒁兂煞腔钴S狀態(tài)的時候調(diào)用這個方法(按home鍵/來電)
- 在這個方法中一般關閉定時器跌宛、暫停游戲骡尽、暫停視頻播放等
- 方法3: - (void)applicationDidEnterBackground:(UIApplication *)application;
- 作用: 應用程序已經(jīng)進入后臺的時候會調(diào)用這個方法
- 方法4: - (void)applicationWillEnterForeground:(UIApplication *)application;
- 作用: 應用程序?qū)⒁M入前臺的時候會調(diào)用這個方法(從后臺進入應用程序的時候)
- 方法5: - (void)applicationDidBecomeActive:(UIApplication *)application;
- 應用程序已經(jīng)變成活躍狀態(tài)的時候調(diào)用這個方法(應用程序顯示在界面的那一刻)
- 方法6: - (void)applicationWillTerminate:(UIApplication *)application;
- 應用程序?qū)⒁K止的時候調(diào)用這個方法(關閉不再運行)
不讓應用程序在后臺運行: 設置info.plist文件 添加 Application does not run in background 鍵, 設置值為YES。
UIWindow和UIView####
UIWindow
UIWindow是一個UNKit; UIWindow繼承自UIView, UIView擁有的屬性和方法, UIWindow都擁有; 而UIView是iOS中所有視圖(控件)直接或者間接的父類竹祷。
??UIWindow的作用: 一個應用程序至少有一個窗口, iOS應用程序中一般只有一個(一個應用程序想要展示在硬件設備上, 必須有窗口)
- 創(chuàng)建window對象, 設置frame坐標是(0, 0), 大小是自定義
// 應用程序啟動后成功調(diào)用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 如果不在這個方法中創(chuàng)建界面, 那么程序會自動加載main.storyboard來創(chuàng)建見面(自動回去創(chuàng)建UIWindow)
// 1.創(chuàng)建UIWindow對象
_window = [[UIWindow alloc] init];
// 2.設置frame屬性(默認: x和y是0, 寬和高是0) - 從UIView繼承下來
// 所有視圖想要顯示在界面上, 必須設置它的位置(坐標-x和y確定)和大小(寬和高確定), 告訴系統(tǒng)當前這個視圖是怎么顯示
// iOS中, 坐標計算采用iOS坐標系(原點在左上角)
// struct CGRect {
// CGPoint origin;
// CGSize size;
// };
// 使用c語言方式創(chuàng)建結構體變量
// 坐標
CGPoint point = {0, 0};
// 大小
CGSize size = {375, 667};
// frame是由坐標和大小組成的
CGRect rect = {point, size};
[_window setFrame:rect];
// 3.設置背景顏色
_window.backgroundColor = [UIColor lightGrayColor];
// 4.讓window成為主窗口并且顯示出來
[_window makeKeyAndVisible];
return YES;
}
1. 創(chuàng)建UIWindow對象
2. 設置frame屬性(默認: x和y是0, 寬和高是0)
3. 設置背景顏色
4. 讓window成為主窗口并且顯示出來
- 創(chuàng)建window, 設置frame坐標是(0, 0), 大小是屏幕大小
//創(chuàng)建window, 設置frame坐標是(0, 0), 大小是屏幕大小
// [UIScreen mainScreen]獲取當前手機的屏幕
// [UIScreen mainScreen].bounds : bounds的類型是CGRect, x和y值是0, 并且wight和height是屏幕的寬度和屏幕的高度
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIView
UIView是所有視圖類直接或者間接的父類, UIView所有的屬性和方法其它視圖類都擁有.
- UIView的創(chuàng)建
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 1. 創(chuàng)建window, 設置frame坐標是(0, 0), 大小是屏幕大小
// [UIScreen mainScreen]獲取當前手機的屏幕
// [UIScreen mainScreen].bounds : bounds的類型是CGRect, x和y值是0, 并且wight和height是屏幕的寬度和屏幕的高度
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// 2.設置背景顏色
self.window.backgroundColor = [UIColor lightTextColor];
// 在這兒來創(chuàng)建界面
// =========== UIView ============
// 創(chuàng)建一個UIView對象
UIView *view1 = [[UIView alloc] init];
// (2) frame屬性
// 視圖想要顯示在界面上, 必須設置frame屬性告訴系統(tǒng)顯示的坐標和大小
// frame屬性中的坐標是相對坐標, 將當前視圖添加到哪個視圖上, 那么這個坐標就是相對于誰的
// OC中所有的結構體都對應一個make方法, 來快速的創(chuàng)建結構體變量
[view1 setFrame:CGRectMake(100, 100, 175, 102)];
// (3)設置背景顏色
// clearColor 透明
// 通過類方法創(chuàng)建顏色
view1.backgroundColor = [UIColor whiteColor];
// 設置tag值
[view1 setTag:20];
// (4)將視圖對象添加到指定的視圖上
// 將一個視圖添加到另外一個視圖上
[_window addSubview:view1];
// ============ 第二個UIView ===========
// (1)創(chuàng)建一個UIView對象, 并且設置其frame
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 20, 50, 50)];
// (2)設置背景顏色
view2.backgroundColor = [UIColor blackColor];
// (3)將視圖對象添加到另外一個視圖上
// window就是view2的父視圖, view2就是window的子視圖
[_window addSubview:view2];
// [view1 addSubview:view2];
// (4)設置tag值(如果不設置, 默認都是0)
// 作用:父視圖可以通過tag值獲取到指定的值
[view2 setTag:10];
// 3.設置為主窗口, 并且顯示
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// 1.通過tag值去獲取當前視圖上的子視圖
UIView *view = [self.window viewWithTag:10];
view.backgroundColor = [UIColor greenColor];
// 2.獲取當前視圖上所有的子視圖
NSArray *viewArray = [_window subviews];
NSLog(@"%@", viewArray);
// 遍歷數(shù)組中所有的視圖
for (UIView *view2 in viewArray) {
if (view2.tag == 20) {
view2.backgroundColor = [UIColor purpleColor];
}
else if (view2.tag == 10){
view2.backgroundColor = [UIColor cyanColor];
}
}
}
UIView坐標相關屬性及方法####
// 創(chuàng)建視圖對象
UIView * view1 = [[UIView alloc] init];
// 顯示在界面上
[self.window addSubview:view1];
// 設置背景顏色
view1.backgroundColor = [UIColor lightGrayColor];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
view2.backgroundColor = [UIColor blackColor];
[view1 addSubview:view2];
-
1> frame
- 每個想要顯示在界面上的控件都需要通過frame屬性來確定坐標和大小
view1.frame = CGRectMake(10, 30, 100, 100);
- 每個想要顯示在界面上的控件都需要通過frame屬性來確定坐標和大小
-
2> center
-
center是當前view視圖的中心點的坐標, 確定了視圖的frame谈跛,視圖的center就會被確定
設置視圖的中心點, 視圖的frame也會隨著中心點的變化而變化
CGPoint center = view1.center; NSLog(@"center:%@", NSStringFromCGPoint(center)); // center:(100,100) // 設置中心點, 會改變frame的坐標 view1.center = CGPointMake(200, 200); // center:(200,200)
-
-
3> bounds
- 視圖一旦確定了frame, 就確定了bounds的值, bounds的坐標是(0,0), 大小是frame的size
CGRect rect = view1.bounds;
// (0,0,100,100) - 改變bounds的坐標不會影響視圖的frame的坐標; 但是會影響當前這個子視圖坐標原點(一般不會去設置bounds的值, 只是通過bounds快速獲取坐標是(0,0)大小是當前視圖大小的frame值)
view1.bounds = CGRectMake(10, 10, 100, 100);
// view1視圖不變 - 改變bounds的size會影響frame的size, 也會影響frame的坐標, 但是視圖的中心點不會變
view1.bounds = CGRectMake(0, 0, 200, 200);
// (200,200)
- 視圖一旦確定了frame, 就確定了bounds的值, bounds的坐標是(0,0), 大小是frame的size
-
4> 形變
旋轉(zhuǎn)、縮放塑陵、平移都是對視圖的同一個屬性進行設置, 后設置的屬性會覆蓋之前設置的屬性
- 旋轉(zhuǎn)(當前視圖的子視圖也會跟著一起旋轉(zhuǎn))
// 參數(shù): 角度(pi對應的角度)
[view1 setTransform:CGAffineTransformMakeRotation(M_PI_2)]; - 縮放(當前視圖的子視圖也會跟著縮放)
// 參數(shù)1: x方向的縮放比例
// 參數(shù)2: y方向的縮放比例
[view1 setTransform:CGAffineTransformMakeScale(0.5, 0.4)]; - 平移
// 參數(shù)1: 在x方向平移單位(+右移 -左移)
// 參數(shù)2: 在y方向平移單位(+下移 -上移)
[view1 setTransform:CGAffineTransformMakeTranslation(0, 0)];
- 旋轉(zhuǎn)(當前視圖的子視圖也會跟著一起旋轉(zhuǎn))
旋轉(zhuǎn)小動畫
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
_window.backgroundColor = [UIColor whiteColor];
// 創(chuàng)建視圖對象
UIView * view1 = [[UIView alloc] init];
// 顯示在界面上
[self.window addSubview:view1];
// 設置背景顏色
view1.backgroundColor = [UIColor lightGrayColor];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
view2.backgroundColor = [UIColor blackColor];
[view1 addSubview:view2];
view1.tag = 10;
// 添加一個定時器
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(yhTransform) userInfo:nil repeats:YES];
[view1 setTransform:CGAffineTransformMakeRotation(0)];
[_window makeKeyAndVisible];
return YES;
}
- (void) yhTransform {
// 獲取旋轉(zhuǎn)的視圖
UIView *view = [_window viewWithTag:10];
// ================== 時時旋轉(zhuǎn) ===============
// 使用靜態(tài)變量存儲上一次結束的時候視圖的旋轉(zhuǎn)的角度
static CGFloat angle = M_PI/8;
// 每0.1秒讓視圖的旋轉(zhuǎn)角度增加pi/10
[view setTransform:CGAffineTransformMakeRotation(angle)];
// 保存當前的旋轉(zhuǎn)角度
angle = angle + M_PI/8;
}
- 自由縮放小動畫
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
_window.backgroundColor = [UIColor whiteColor];
// 創(chuàng)建視圖對象
UIView * view1 = [[UIView alloc] init];
// 顯示在界面上
[self.window addSubview:view1];
// 設置背景顏色
view1.backgroundColor = [UIColor lightGrayColor];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
view2.backgroundColor = [UIColor blackColor];
[view1 addSubview:view2];
view1.tag = 10;
// 添加一個定時器
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(yhTransform) userInfo:nil repeats:YES];
[view1 setTransform:CGAffineTransformMakeRotation(0)];
[_window makeKeyAndVisible];
return YES;
}
- (void) yhTransform {
// 獲取旋轉(zhuǎn)的視圖
UIView *view = [_window viewWithTag:10];
// 隨機縮放比例
NSInteger arc = arc4random() % 100 + 1;
CGFloat prop = arc / 50.0;
[view setTransform:CGAffineTransformMakeScale(prop, prop)];
}
- 時時平移小動畫
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
_window.backgroundColor = [UIColor whiteColor];
// 創(chuàng)建視圖對象
UIView * view1 = [[UIView alloc] init];
// 顯示在界面上
[self.window addSubview:view1];
// 設置背景顏色
view1.backgroundColor = [UIColor lightGrayColor];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
view2.backgroundColor = [UIColor blackColor];
[view1 addSubview:view2];
view1.tag = 10;
// 添加一個定時器
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(yhTransform) userInfo:nil repeats:YES];
[view1 setTransform:CGAffineTransformMakeRotation(0)];
[_window makeKeyAndVisible];
return YES;
}
- (void) yhTransform {
// 獲取旋轉(zhuǎn)的視圖
UIView *view = [_window viewWithTag:10];
static float translation = 0;
static float translationValue = 1;
[view setTransform:CGAffineTransformMakeTranslation(translation + 5 * translationValue, 0)];
// 跟新平移距離
translation += 5*translationValue;
if (view.frame.origin.x <= 0) {
translationValue = 1;
}
if (view.frame.origin.x >= _window.frame.size.width - view.frame.size.width)
{
translationValue = -1;
}
}
父子視圖關系的屬性和方法####
一個視圖只能有一個父視圖; 一個視圖可以有多個子視圖; 一個視圖被多次添加到其他視圖上, 最后一次添加有效
- 獲取一個視圖的父視圖
UIView * greenSuper = [greenView superview]; - 獲取視圖上得所有子視圖
NSArray * array = _window.subviews;
>注意: 有時會獲取到一些意料之外的視圖
- 獲取window
前提: 獲取window的時候, 已經(jīng)顯示出來
應用程序中, 程序啟動后界面上所有的視圖都是直接或者間接的添加到window, 所以可以通過界面上所有的視圖拿到當前應用的window
UIView * window = [redView window]; - 將視圖從父視圖上移除
UIButton * button = [[UIButton alloc] initWithFrame:CGRectMake(300, 400, 60, 40)];
button.backgroundColor = [UIColor blackColor];
[button addTarget:self action:@selector(onclick:) forControlEvents:UIControlEventTouchDragInside];
[self.window addSubview:button];
[greenView removeFromSuperview];// 移除
>一旦視圖從父視圖上移除, 那么父視圖就不能通過viewWithTag:和subViews來獲取當前的視圖
>已經(jīng)從父視圖上移除的視圖, 在內(nèi)存中還是存在的; 移除只是不讓這個視圖顯示在父視圖上而已
同父視圖的子視圖的層次關系####
如果多個視圖添加到同一個父視圖上, 公共部分后添加的會覆蓋先添加的
// 創(chuàng)建紅色視圖
UIView * redView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
redView.backgroundColor = [UIColor redColor];
redView.tag = 10;
[_window addSubview:redView];
// 創(chuàng)建黃色視圖
UIView * yellowView = [[UIView alloc] initWithFrame:CGRectMake(80, 80, 100, 100)];
yellowView.backgroundColor = [UIColor yellowColor];
yellowView.tag = 20;
[self.window addSubview:yellowView];
// 創(chuàng)建綠色視圖
UIView * greenView = [[UIView alloc] initWithFrame:CGRectMake(110, 110, 100, 100)];
greenView.backgroundColor = [UIColor greenColor];
greenView.tag = 30;
[_window addSubview:greenView];
- 將一個視圖的層次設置成最上面
[_window bringSubviewToFront:redView]; - 將一個視圖的層次設置成最下面
[_window sendSubviewToBack:yellowView]; - 插入視圖(如果被插入的視圖已經(jīng)顯示在界面上, 那么通過插入方法只是改變它的層次關系; 如果被插入的視圖沒有添加到界面上, 通過插入方法可以將視圖添加到界面上, 并且改變層次關系)
- 將某個視圖插入到指定的視圖上面
[_window insertSubview:greenView aboveSubview:redView]; - 將某個視圖插入到指定的視圖下面
[_window insertSubview:greenView belowSubview:yellowView];
- 將某個視圖插入到指定的視圖上面
層次與事件接收####
- 父視圖不能接收事件, 則子視圖無法接收事件
如果本來可以接收事件的視圖, 添加到了不能接收事件的視圖上, 那么本來可以接收事件的視圖也接收不到事件了
- 子視圖超出父視圖的部分, 不能接收事件
- 同一個父視圖下, 最上面的視圖, 首先遭遇事件, 如果能夠接收, 就不向下傳遞事件感憾。 如果不能接收, 事件向下傳遞。
- 設置控件是否可以接收事件
imageView.userInteractionEnabled = YES;
不能接收事件: 感受不到手指的觸摸
能接收事件: 能感受到手指的觸摸
并不是能夠接收事件就可以響應事件, 但是能響應事件的前提是能接收事件
默認情況下: UIWindow令花、UIView和UIButton等可以接收事件, UILabel和UIImageView等不可以接收事件
UIView動畫####
上面提到一種動畫方式, 通過形變(旋轉(zhuǎn)阻桅、縮放、平移)對當前的視圖進行時時的更改, 達到動畫效果, 但是在很多時候, 通過UIView的形變產(chǎn)生的動畫并不能滿足動畫的要求, 但是UIView還有一種動畫效果, 可以動態(tài)的改變視圖的frame彭则、形變鳍刷、顏色占遥、透明度, 實現(xiàn)動畫
- 第一種: + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations;
- 功能: 動態(tài)的改變視圖的frame俯抖、形變、顏色瓦胎、透明度
- 參數(shù)1: 動畫時間(單位/s)
- 參數(shù)2: block, 用來實現(xiàn)動畫結果的代碼段
[UIView animateWithDuration:3 animations:^{
// 使用動畫效果改變視圖的frame
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y + 400, 200, 200);
// 使用動畫效果改變視圖的背景顏色
view.backgroundColor = [UIColor greenColor];
// 使用動畫效果改變視圖的透明度
// 改變父視圖的透明度, 子視圖的透明度會跟著改變; 如果只想改變父視圖的透明度, 就改變父視圖背景顏色的透明度
view.alpha = 0.3;
// view.backgroundColor = [UIColor colorWithRed:123/255.0 green:231/255.0 blue:145/255.0 alpha:0.3];
// 使用動畫效果改變視圖的形變
view.transform = CGAffineTransformMakeScale(0.5, 0.5);
}];
- 第二種: + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;
- 功能: 動態(tài)的改變視圖的frame、形變、顏色捻悯、透明度
- 參數(shù)1: 動畫時間(單位/s)
- 參數(shù)2: block, 用來實現(xiàn)動畫的結果的代碼段
- 參數(shù)3: block, 動畫結束后需要執(zhí)行的代碼段
[UIView animateWithDuration:2 animations:^{
// 動畫結果
view.transform = CGAffineTransformMakeScale(0.5, 0.5);
} completion:^(BOOL finished) {
// 動畫結束后移除
//[view removeFromSuperview];
}];
- 第一種與第二種動畫進行嵌套使用
[UIView animateWithDuration:2 animations:^{
// 縮小一倍
view.transform = CGAffineTransformMakeScale(0.5, 0.5);
} completion:^(BOOL finished) {
// 變小后的動畫, 再變回去
[UIView animateWithDuration:2 animations:^{
// 動畫結果
view.transform = CGAffineTransformMakeScale(1, 1);
}];
}];