main程序入口
UIApplication里面做了哪些事情
- 1.創(chuàng)建
UIApplication對(duì)象
(UIApplication對(duì)象
的作用:1.打電話,發(fā)短信,打開網(wǎng)頁 2.設(shè)置應(yīng)用提醒數(shù)字 3.設(shè)置聯(lián)網(wǎng)狀態(tài) 4.控制器導(dǎo)航欄) - 2.創(chuàng)建
UIApplication代理對(duì)象
(UIApplication代理對(duì)象
作用:1.監(jiān)聽整個(gè)應(yīng)用程序的生命周期 2.處理內(nèi)存警告,清空?qǐng)D片緩存) - 3.開啟主運(yùn)行循環(huán),保證程序一直運(yùn)行,runloop(重要),每個(gè)線程都有一個(gè)runloop,主線程的runloop自動(dòng)開啟,其他線程的runloop需要手動(dòng)去開啟
- 4.加載
info.plist
文件,判斷是否指定了main
,如果指定了,就去加載- 加載
main.storyboard
的時(shí)候做的幾件事情- 創(chuàng)建窗口
- 創(chuàng)建窗口的根控制器
- 顯示窗口
- 加載
為什么要自定義類
- 誰的事情誰管理,方便以后改需求,迅速找到對(duì)應(yīng)的類做事情
- 系統(tǒng)的類不能滿足我們的要求
修改了控制器的返回按鈕,但是沒有點(diǎn)擊按鈕按鈕的時(shí)候按鈕也能做出響應(yīng),如何解決?
//設(shè)置按鈕的尺寸為自適應(yīng),此時(shí)按鈕的尺寸并不大,但是當(dāng)鼠標(biāo)點(diǎn)擊按鈕右側(cè)很遠(yuǎn)的位置的時(shí)候這個(gè)按鈕也會(huì)被點(diǎn)擊,為了解決這個(gè)問題,可以換用一個(gè)View將按鈕包裝起來,然后用item將View包裝起來
UIView *view = [[UIView alloc] initWithFrame:btn.bounds];
[view addSubview:btn];
return [[UIBarButtonItem alloc] initWithCustomView:view] ;
隱藏push出來的控制器的TabBar
- (void)setting
{
HMXSettingViewController *settingVc = [[HMXSettingViewController alloc] init];
// 一定要注意:在Push之前去設(shè)置這個(gè)屬性(通過方法名可以看出,是在push的時(shí)候有效)
settingVc.hidesBottomBarWhenPushed = YES;
// 跳轉(zhuǎn)到設(shè)置界面
[self.navigationController pushViewController:settingVc animated:YES];
}
UITabBarItem
和UINavigationItem
以及UIBarButtonItem
-
UITabBarItem
決定TabBar
上按鈕的內(nèi)容 -
UINavigationItem
決定導(dǎo)航條上左邊,中間,右邊的內(nèi)容 -
UIBarButtonItem
決定導(dǎo)航條上按鈕具體的內(nèi)容
利用KVC來替換系統(tǒng)的TabBar的底層實(shí)現(xiàn)
系統(tǒng)的
TabBar
為ReadOnly
,只能通過KVC,調(diào)用[self setValue:tabBar forKey:@"tabBar"]
方法去修改系統(tǒng)的TabBar
-
那么KVC底層是怎么樣實(shí)現(xiàn)的呢?
- 系統(tǒng)首先去查找類中有沒有
setTabBar
方法 - 查找有沒有
tabBar
屬性 - 查找有沒有
_tabBar
- 系統(tǒng)首先去查找類中有沒有
被
readOnly
修飾的屬性不會(huì)生成setter
方法,只會(huì)生成getter
方法
富文本屬性
- 如果想修改
NavigationBar
或者TabBar
上面按鈕文字的屬性,可以通過UITabBarItem
或者UINavigationBar
去設(shè)置titleTextAttributes
一個(gè)惡心的BUG
- 在獲取全局導(dǎo)航條的時(shí)候,如果
[UINavigationBar appearance]
去獲取整個(gè)應(yīng)用程序下的導(dǎo)航條,在iOS7的時(shí)候,如果將短信界面的導(dǎo)航條也改了就會(huì)使聯(lián)系人界面出現(xiàn)一片黑
系統(tǒng)自帶的側(cè)滑返回功能
系統(tǒng)有個(gè)自帶的側(cè)滑返回功能,就是一個(gè)導(dǎo)航控制器下的子控制器push出下的一個(gè)控制器之后,想返回上一個(gè)子控制器就可以在左側(cè)側(cè)滑返回,但是一旦重寫了系統(tǒng)的左側(cè)返回按鈕,那么該功能就會(huì)失效
-
推測(cè):兩種原因?qū)е聜?cè)滑返回功能失效:
- 1.系統(tǒng)的滑動(dòng)手勢(shì)不在了?(經(jīng)過驗(yàn)證,側(cè)滑手勢(shì)還在,進(jìn)入導(dǎo)航控制器,搜索gesture就可以找出側(cè)滑的手勢(shì)為
interactivePopGestureRecognizer
) - 2.是代理控制側(cè)滑手勢(shì)失效的嗎?驗(yàn)證:代理做了一些事情,使得側(cè)滑手勢(shì)失效
- 1.系統(tǒng)的滑動(dòng)手勢(shì)不在了?(經(jīng)過驗(yàn)證,側(cè)滑手勢(shì)還在,進(jìn)入導(dǎo)航控制器,搜索gesture就可以找出側(cè)滑的手勢(shì)為
系統(tǒng)的側(cè)滑功能底層實(shí)現(xiàn):如果在非根控制器,當(dāng)觸發(fā)側(cè)滑手勢(shì)的時(shí)候,手勢(shì)會(huì)通知它的代理
self.interactivePopGestureRecognizer.delegate
去讓Target
調(diào)用handleNavigationTransition:
方法,實(shí)現(xiàn)側(cè)滑,而通過打印驗(yàn)證,這個(gè)Target
正是self.interactivePopGestureRecognizer.delegate
本身,如果在根控制器觸發(fā)手勢(shì),那么,系統(tǒng)去做一些控制不去讓代理調(diào)用這個(gè)方法目前的需求:又想要系統(tǒng)的側(cè)滑返回,又要自定義返回按鈕
解決方案:
- (void)viewDidLoad {
[super viewDidLoad];
// Bug:假死狀態(tài):程序一直在跑,但是界面死了
//自己的理解:
//在根控制器,系統(tǒng)原本的做法是會(huì)讓代理做一些控制,即使用戶觸發(fā)了側(cè)滑手勢(shì),也不實(shí)現(xiàn)側(cè)滑,由于這里根控制器的左側(cè)返回按鈕沒有重寫,所以它的代理還是有效的,在沒有push出下一個(gè)控制器之前,在根控制器上觸發(fā)側(cè)滑手勢(shì),代理會(huì)去做一些控制
//我們這里的做法是將系統(tǒng)側(cè)滑手勢(shì)的代理給換了,如果用戶在根控制器觸發(fā)側(cè)滑手勢(shì),這個(gè)手勢(shì)將找不到原來的代理去做一些控制,因此出現(xiàn)了假死的現(xiàn)象
//因此我們要禁止在根控制器觸發(fā)側(cè)滑手勢(shì),在手勢(shì)的代理方法中可以禁止掉
//在push出來的控制器上觸發(fā)側(cè)滑,由于我們將系統(tǒng)自帶的側(cè)滑手勢(shì)的代理給換了,系統(tǒng)原本的做法是如果自定義了左側(cè)的返回按鈕,那么這個(gè)側(cè)滑返回功能會(huì)失效,這個(gè)是通過它原本的代理做的一些控制,但是我們將它的代理給換掉了,它找不到原本的代理做控制,因此,側(cè)滑功能海還會(huì)保留
// 清空手勢(shì)代理,恢復(fù)滑動(dòng)返回功能
self.interactivePopGestureRecognizer.delegate = self;
}
#pragma mark - UIGestureRecognizerDelegate
// 是否觸發(fā)手勢(shì)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
// 在根控制器下 不要 觸發(fā)手勢(shì)
return self.childViewControllers.count > 1;
}
全屏側(cè)滑
- (void)viewDidLoad {
[super viewDidLoad];
// 全屏滑動(dòng)功能
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];
[self.view addGestureRecognizer:pan];
// 調(diào)用代理方法來控制手勢(shì)什么時(shí)候觸發(fā)(非根控制器的時(shí)候才觸發(fā))
pan.delegate = self;
// 讓系統(tǒng)的側(cè)滑手勢(shì)失效
self.interactivePopGestureRecognizer.enabled = NO;
}
#pragma mark - UIGestureRecognizerDelegate
// 是否觸發(fā)手勢(shì)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
// 在根控制器下 不要 觸發(fā)手勢(shì)
return self.childViewControllers.count > 1;
}
占位視圖的實(shí)現(xiàn)
- 當(dāng)一個(gè)界面,層次結(jié)構(gòu)已經(jīng)清晰,但是中間某一層位置或者尺寸不確定,可以采用占位視圖
如何修改一個(gè)第三方框架的配置文件
- 打開工程文件 --->搜索"plug"--->找到一個(gè)圖標(biāo)是藍(lán)色工程文件開頭的文件,點(diǎn)擊之后進(jìn)去找到路徑,然后按照相應(yīng)的路徑去查找,右擊顯示包內(nèi)容