viewWillAppear:視圖即將可見時調用。默認狀況下不執行任何操做css
viewDidAppear:視圖已徹底過渡到屏幕上時調用java
viewWillDisappear:視圖被駁回時調用,覆蓋或以其餘方式隱藏。默認狀況下不執行任何操做ios
viewDidDisappear:視圖被駁回後調用,覆蓋或以其餘方式隱藏。默認狀況下不執行任何操做loadView; .這是當他們沒有正在使用nib視圖頁面,子類將會建立本身的自定義視圖層。毫不能直接調用。web
viewDidLoad:在視圖加載後被調用,若是是在代碼中建立的視圖加載器,他將會在loadView方法後被調用,若是是從nib視圖頁面輸出,他將會在視圖設置好後後被調用。面試
「initWithNibName: bundle:」載入nib檔案來初始化「loadView」載入視圖「viewDidLoad」在載入視圖至內存後會呼叫的方法「viewDidUnload」在視圖從內存中釋放後會呼叫的方法 (當內存太低,釋放一些不須要的視圖時調用)算法
「viewWillAppear」當收到視圖在視窗將可見時的通知會呼叫的方法編程
「viewDidAppear」當收到視圖在視窗已可見時的通知會呼叫的方法數組
「viewWillDisappear」當收到視圖將去除、被覆蓋或隱藏於視窗時的通知會呼叫的方法瀏覽器
「viewDidDisappear」當收到視圖已去除、被覆蓋或隱藏於視窗時的通知會呼叫的方法緩存
「didReceiveMemoryWarning」收到系統傳來的內存警告通知後會執行的方法
「shouldAutorotateToInterfaceOrientation」是否支持不一樣方向的旋轉視圖
「willAnimateRotationToInterfaceOrientation」在進行旋轉視圖前的會執行的方法(用於調整旋轉視圖之用)
代碼的執行順序
一、 alloc 建立對象,分配空間
二、init (initWithNibName) 初始化對象,初始化數據
三、loadView 從nib載入視圖 ,一般這一步不須要去幹涉。除非你沒有使用xib文件建立視圖
四、viewDidLoad 載入完成,能夠進行自定義數據以及動態建立其餘控件
五、viewWillAppear 視圖將出如今屏幕以前,立刻這個視圖就會被展示在屏幕上了
六、viewDidAppear 視圖已在屏幕上渲染完成當一個視圖被移除屏幕而且銷燬的時候的執行順序,這個順序差很少和上面的相反
一、viewWillDisappear 視圖將被從屏幕上移除以前執行
二、viewDidDisappear 視圖已經被從屏幕上移除,用戶看不到這個視圖了
三、dealloc 視圖被銷燬,此處須要對你在init和viewDidLoad中建立的對象進行釋放
- 先添加所需子控件 - 再接收模型數據根據模型數據設置子控件數據和位置 - 簡而言之, 本身的事情本身作, 把不須要暴露出去的封裝起來
程序啓動分爲兩類:1.有storyboard 2.沒有storyboard 有storyboard狀況下: 1.main函數 2.UIApplicationMain * 建立UIApplication對象 * 建立UIApplication的delegate對象 3.根據Info.plist得到Main.storyboard的文件名,加載Main.storyboard(有storyboard) * 建立UIWindow * 建立和設置UIWindow的rootViewController * 顯示窗口 沒有storyboard狀況下: 1.main函數 2.UIApplicationMain * 建立UIApplication對象 * 建立UIApplication的delegate對象 3.delegate對象開始處理(監聽)系統事件(沒有storyboard) * 程序啓動完畢的時候, 就會調用代理的application:didFinishLaunchingWithOptions:方法 * 在application:didFinishLaunchingWithOptions:中建立UIWindow * 建立和設置UIWindow的rootViewController * 顯示窗口
iOS中不存在緩存池滿的狀況,由於一般咱們ios中開發,對象都是在須要的時候纔會建立,有種經常使用的說話叫作懶加載,還有在UITableView中通常只會建立剛開始出如今屏幕中的cell,以後都是從緩存池裏取,不會在建立新對象。緩存池裏最多也就一兩個對象,緩存池滿的這種狀況通常在開發java中比較常見,java中通常把最近最少使用的對象先釋放。
繼承結構,屬於內部的子控件結構
UIButton爲:UIButton > UIControl > UIView > UIResponder > NSObject
UITableView爲:UITableView > UIScrollView > UIView > UIResponder > NSObject
通常狀況下能夠設置在viewDidLoad中,但在autolayout下,系統會在viewDidAppear以前根據subview的constraint從新計算scrollview的contentsize。 這就是爲何,在viewdidload裏面手動設置了contentsize沒用。由於在後面,會再從新計算一次,前面手動設置的值會被覆蓋掉。
解決辦法就是:
去除autolayout選項,本身手動設置contentsize
若是要使用autolayout,要麼本身設置完subview的constraint,而後讓系統自動根據constraint計算出contentsize。要麼就在viewDidAppear裏面本身手動設置contentsize。
UIView: 屬於UIkit.framework框架,負責渲染矩形區域的內容,爲矩形區域添加動畫,響應區域的觸摸事件,佈局和管理一個或多個子視圖
UIWindow:屬於UIKit.framework框架,是一種特殊的UIView,一般在一個程序中只會有一個UIWindow,但能夠手動建立多個UIWindow,同時加到程序裏面。UIWindow在程序中主要起到三個做用:
做爲容器,包含app所要顯示的全部視圖
傳遞觸摸消息到程序中view和其餘對象
與UIViewController協同工做,方便完成設備方向旋轉的支持
CAlayer:屬於QuartzCore.framework,是用來繪製內容的,對內容進行動畫處理依賴與UIView來進行顯示,不能處理用戶事件。
UIView和CALayer是相互依賴的,UIView依賴CALayer提供內容,CALayer依賴UIView的容器顯示繪製內容。
frame指的是:該view在父view座標系統中的位置和大小(參照點是父親的座標系統)
bounds指的是:該view在自己座標系統中的位置和大小(參照點是自己座標系統)
屬性傳值:A頁面設置屬性 NSString *paramString,在跳轉B頁面的時候初始化paramString。 //A頁面.h文件 @property (nonatomic, copy)NSString *paramString; //A頁面.m文件 NextViewController *nextVC = [[NextViewController alloc] init]; nextVC.paramString = @"參數傳質"; [self presentViewController:nextVC animated:YES completion:nil]; 委託delegate傳值:在B頁面定義delegate,而且設置delegate屬性,在A頁面實現delegate協議 通知notification傳值:在B頁面中發送通知,在A頁面註冊觀察者而且在不用的時候移除觀察者。 //B頁面發送通知 [[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeNameNotification" object:self userInfo:@{@"name":self.nameTextField.text}]; [self dismissViewControllerAnimated:YES completion:nil]; //A頁面註冊觀察者 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ChangeNameNotification:) name:@"ChangeNameNotification" object:nil]; } //觀察到通知時候的處理方法 -(void)ChangeNameNotification:(NSNotification*)notification{ NSDictionary *nameDictionary = [notification userInfo]; self.nameLabel.text = [nameDictionary objectForKey:@"name"]; } //通知不使用的時候移除觀察者 [[NSNotificationCenter defaultCenter] removeObserver:self]; block傳值:在B頁面定義一個block類型的變量,在B頁面跳轉A的時候調用這個block。在A頁面跳轉到B頁面的時候對B頁面的block賦值。 //B頁面定義block,並設置block類型的變量 typedef void (^ablock)(NSString *str); @property (nonatomic, copy) ablock block; //B頁面跳轉到A頁面調用這個block self.block(self.nameTextField.text); [self dismissViewControllerAnimated:YES completion:nil]; //A頁面跳轉到B頁面的時候對B頁面的block賦值,這樣在B頁面跳轉的時候就會回調這個block函數 [self presentViewController:second animated:YES completion:nil]; second.block = ^(NSString *str){ self.nameLabel.text = str; }; kvo傳值:在A頁面設置B頁面的變量second,而且對這個變量進行觀察 - (void)addObserver:(NSObject * _Nonnull)anObserver forKeyPath:(NSString * _Nonnull)keyPath options:(NSKeyValueObservingOptions)options context:(void * _Nullable)context 並在A頁面實現 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context方法。 在B頁面對變量keyPath進行設置,在A頁面都會觀察的到。 @property (nonatomic, strong) SecondViewController *second; //在A視圖跳轉到B視圖的地方添加以下代碼 self.second = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; [self.second addObserver:self forKeyPath:@"userName" options:NSKeyValueObservingOptionNew context:nil]; [self presentViewController:self.second animated:YES completion:nil]; //實現這個觀察對象的方法 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context //在B頁面對userName進行設置,在A頁面均可以間聽到 單例模式傳值:經過全局的方式保存 對於通知代理面試常問, 代理和通知分別在什麼狀況下使用? 區別? 各自優勢?
首先判斷控制器是否有視圖,若是沒有就調用loadView方法建立:經過storyboard或者代碼;
隨後調用viewDidLoad,能夠進行下一步的初始化操做;只會被調用一次;
在視圖顯示以前調用viewWillAppear;該函數能夠屢次調用;
視圖viewDidAppear
在視圖顯示以前調用viewWillDisappear;該函數能夠屢次調用;如須要);
在佈局變化先後,調用viewWill/DidLayoutSubviews處理相關信息;
視圖生命週期圖
事件響應鏈。包括點擊事件,畫面刷新事件等。在視圖棧內從上至下,或者從下之上傳播. 能夠說點事件的分發,傳遞以及處理。具體能夠去看下touch事件這塊。
首先解釋響應者鏈的概念
UIResponder類,是UIKIT中一個用於處理事件響應的基類。窗口上的全部事件觸發,都由該類響應(即事件處理入口)。因此,窗口上的View及控制器都是派生於該類的,例如UIView、UIViewController等。
調用UIResponder類提供的方法或屬性,咱們就能夠捕捉到窗口上的全部響應事件,並進行處理。
響應者鏈條是由多個響應者對象鏈接起來的鏈條,其中響應者對象是能處理事件的對象,全部的View和ViewController都是響應者對象,利用響應者鏈條能讓多個控件處理同一個觸摸事件.
事件傳遞機制
若是當前view不能處理當前事件,那麼事件將會沿着響應者鏈(Responder Chain)進行傳遞,知道遇到能處理該事件的響應者(Responsder Object)。
- 接收事件的initial view若是不能處理該事件而且她不是頂層的View,則事件會往它的父View進行傳遞。 - initial view的父View獲取事件後若是仍不能處理,則繼續往上傳遞,循環這個過程。若是頂層的View仍是不能處理這個事件的話,則會將事件傳遞給它們的ViewController, - 若是ViewController也不能處理,則傳遞給Window(UIWindow),此時Window不能處理的話就將事件傳遞UIApplication,最後若是連Application也不能處理,則廢棄該事件
viewDidLoad在view從nib文件初始化時調用,
loadView在controller的view爲nil時調用。
此方法在編程實現view時調用, view控制器默認會註冊memory warning notification,當viewcontroller的任何view沒有用的時候,viewDidUnload會被調用,在這裏實現將retain的view release,若是是retain的IBOutlet view屬性則不要在這裏release,IBOutlet會負責release。
查看UITableView頭文件,會找到NSMutableArray visiableCells,和NSMutableArrayreusableTableCells兩個結構。
visiableCells內保存當前顯示的cells,reusableTableCells保存可重用的cells。
TableView顯示之初,reusableTableCells爲空,那麼
[tableView dequeueReusableCellWithIdentifier:CellIdentifier]返回nil。
開始的cell都是經過 [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] 來建立,並且cellForRowAtIndexPath只是調用最大顯示cell數的次數。 好比:有100條數據,iPhone一屏最多顯示10個cell。
程序最開始顯示TableView的狀況是:
用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]建立10次cell,並給cell指定一樣的重用標識(固然,能夠爲不一樣顯示類型的cell指定不一樣的標識)。而且10個cell所有都加入到visiableCells數組,reusableTableCells爲空。
向下拖動tableView,當cell1徹底移出屏幕,而且cell11(它也是alloc出來的,緣由同上)徹底顯示出來的時候。cell11加入到visiableCells,cell1移出visiableCells,cell1加入到reusableTableCells。
接着向下拖動tableView,由於reusableTableCells中已經有值,因此,當須要顯示新的cell, cellForRowAtIndexPath再次被調用的時候,[tableView dequeueReusableCellWithIdentifier:CellIdentifier],返回cell1。 cell1加入到visiableCells,cell1 移出reusableTableCells;cell2移出 visiableCells,cell2加入到reusableTableCells。以後再須要顯示的Cell就可 以正常重用了.
注意:配置Cell的時候必定要注意,對取出的重用的cell作從新賦值,不要遺留老數據。
實際上針對性地優化一下就能夠解決tableView滑動的時候卡頓的問題:
使用不透明視圖。不透明的視圖能夠提升渲染的速度。能夠將cell及其子視圖的opaque屬性設爲YES(默認值)。
不要重複建立沒必要要的cell。UITableView只須要一屏幕的UITableViewCell對象便可。所以在cell不可見時,能夠將其緩存起來,而在須要時繼續使用它便可。注意:cell被重用時,須要調用setNeedsDisplayInRect:或setNeedsDisplay方法重繪cell。
減小動畫效果的使用,最好不要使用insertRowsAtIndexPaths:withRowAnimation:方法,而是直接調用reloadData方法。
減小視圖的數目。Cell包含了textLabel、detailTextLabel和imageView等view,而你還能夠自定義一些視圖放在它的contentView裏,建立它會消耗較多資源,而且也影響渲染的性能。
cell包含圖片,且數目較多,使用自定義的cell速度會比使用默認的要快。繼承UITableViewCell,重寫drawRect方法:- (void)drawRect:(CGRect)rect { if (image) { [image drawAtPoint:imagePoint]; self.image = nil; } else { [placeHolder drawAtPoint:imagePoint]; } [text drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeTailTruncation]; }
不過這樣一來,你會發現選中一行後,這個cell就變藍了,其中的內容就被擋住了。最簡單的方法就是將cell的selectionStyle屬性設爲UITableViewCellSelectionStyleNone,這樣就不會被高亮了。
-不須要與用戶交互時,使用CALayer,將內容繪製到layer上,而後對cell的contentView.layer調用addSublayer:方法。這個例子中,layer並不會顯著影響性能,但若是layer透明,或者有圓角、變形等效果,就會影響到繪製速度了。解決辦法可參見後面的預渲染圖像。
不要作多餘的繪製工做。在實現drawRect:的時候,它的rect參數就是須要繪製的區域,這個區域以外的不須要進行繪製。
預渲染圖像。你會發現即便作到了上述幾點,當新的圖像出現時,仍然會有短暫的停頓現象。解決的辦法就是在圖形上下文中畫,導出成UIImage對象,而後再繪製到屏幕。(頭像圓角,或者其餘變形的時候,用圖形上下文能提升性能。)異步繪製
不要阻塞主線程。tableview在更新數據時,整個界面卡住不動,徹底不響應用戶請求。常見的是網絡請求,等待時間長待數秒。
解決方案:使用多線程,讓子線程去執行這些函數或方法。
注意:當下載線程數超過2時,會顯著影響主線程的性能。因此在不須要響應用戶請求時,下載線程數能夠增長到5,不建議再加了,以加快下載速度。若是用戶正在交互,應把線程數量控制在2個之內。
提早計算並緩存好高度,由於heightforrowatindexpath調用很是頻繁
選擇正確的數據結構:學會選擇對業務場景最合適的數組結構是寫出高效代碼的基礎。好比,數組: 有序的一組值。使用索引來查詢很快,使用值查詢很慢,插入/刪除很慢。字典: 存儲鍵值對,用鍵來查找比較快。集合: 無序的一組值,用值來查找很快,插入/刪除很快。
思路同網易新聞相似,用自定義的繼承自UITableViewCell的類,在initWithFrame的構造方法中, 初始化自定義的繼承自UICollectionView的類
以tableView的上拉刷新爲例:
爲了進行無縫閱讀, 經過tableView的代理方法, willDisplayCell判斷是不是最後一行,
若是是最後一行, 在顯示最後一行的同時, 判斷當前是否存在上拉刷新
若是當前沒有上拉刷新, 就進行加載數據, 啓動小菊花轉啊轉。
以tableView的下拉刷新爲例:
判斷當前的上拉刷新視圖是否動畫
若是沒有動畫, 就不是上拉刷新
而後下拉刷新加載數據
加載完畢數據關閉刷新
若是但願每條數據顯示自身的行高, 必須設置兩個屬性, 1.預估行高, 2.自定義行高
設置預估行高 tableView.estimatedRowHeight = 200
設置定義行高 tableView.rowHeight = UITableViewAutomaticDimension
若是要讓自定義行高有效, 必須讓容器視圖有一個自下而上的約束
iOS開發中webview和native code的配合上的一些經驗和技巧。
webview與運維成本低,更新幾乎不依賴App的版本;但在交互和性能上與跟native code有很大差距。
native code與之對應。
HTML5確實給web帶入了一個新時代。這個時代是什麼,web app。也就是說,只有脫離native的這個前提,在瀏覽器的環境下,HTML5的意義才能顯現,而咱們討論iOS App的時候,HTML5顯然沒什麼意義。
無論是用webview仍是native code,兩個原則:
用戶體驗不打折
運維成本低
爲何不提開發成本。由於作web開發和iOS開發根本就是兩回事。固然,web開發發展了這麼多年,對於某些功能實現是要比native app快。但多數狀況,同一個功能,對於iOS開發者和web開發者,用各自擅長的方式開發成本都最低,因此說某個功能開發成本低,每每是一個僞命題。
剛剛說了,webview的優點在於更新不依賴版本,那麼在一款App中,只有會頻繁更新的界面考慮webview纔有意義。那麼哪些界面會頻繁更新,這就要因App而異了。
首頁。首頁資源可謂必爭之地,內容一天一換是正常現象,一天幾換也不稀奇。而若是僅僅是內容的更換,非要上個webview就顯得有些激進了。而事實上首頁的變化千奇百怪,逢年過節變個臉,特殊狀況掛個公告,偶爾還要特批強推一把某個業務,等等。此前,我在設計App首頁的時候,把首頁配置設計的很是複雜。App端要處理n種狀況,n各參數,server端要記住n種規則,直到一天,我崩潰了,把首頁徹底換成webview,才豁然開朗。
活動頁。作互聯網都知道,活動,是一個最多見的運營手段。特色是,週期短,功能少,但基本不能複用。這些特色都標識了活動不適合作native,要用webview實現。即便有人告訴你說,個人活動是一個長期活動並且形式不變,也不要相信他。由於在第二期,第三期,第四期他會分別加上一些很是詭異,卻有很合理的小變動,而這些變動是你在那個版本根本沒法實現的。
試水的新功能。這種界面,每每設計不成熟,須要在運行過程當中不斷收集用戶反饋,更新升級,甚至決定去留。因此,只有webview才能hold住如此不穩定的功能。切記在一個功能尚未肯定以前,不要大張旗鼓單位開發native code,要知道,你寫的這些代碼,三天後就要改一遍,並且要發佈上線。
富文本內容。這個不用多說了吧,按照HTML的經常使用標籤作一個webtext可不是小工程。並且富文本的變化太多了,一點沒法匹配,都會致使整個界面巨醜。
OK,上邊說了我認爲最該使用webview的4個界面,分別帶有不一樣的特色,但webview的交互是個短板,所以webview在一個App中,只能做爲界面,不容許在界面中出現動做。而一個webview的界面如何跟native code結合起來呢,個人答案是,超連接。在webview上點擊超連接,會調用webview delegate的shouldload方法,自這裏攔截請求,進行處理。因爲webview的連接都是URL,所以我建議,把整個App的界面都用URL管理起來。
長相問題,webview很難長成native的view。方案:長不成也要裝成。在一些狀況下,禁用webview滾動,使用滾動框架(iScroll不錯)去實現。webview上下留出200pixel的空白背景,y從-200開始。不然你們知道,webview上下會有陰影的背景,不藏起來會很醜。等等,還有不少其餘的方法去假裝webview,是要視情景而用。
cell中嵌套webview,在oc中調用js獲取web的高度, CGFloat height = [[self.webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];在經過webViewDidFinishLoad裏面更新行高。
我對UIScrollView的理解是frame就是他的contentSize,bounds就是他的可視範圍,經過改變bounds從而達到讓用戶誤覺得在滾動,如下是一個簡單的UIScrollView實現
第二個問題我的理解是解決手勢衝突,對本身添加的手勢進行捕獲和響應
// 讓UIScrollView遵照UIGestureRecognizerDelegate協議,實現這個方法,在這裏方法裏對添加的手勢進行處理就能夠解決衝突
animateWithDuration:這就等於建立一個定時器 animations:這是建立定時器須要實現的SEL completion:是定時器結束之後的一個回調block
imgData = UIImageJPEGRepresentation(image, 0.6f)
[tableView deselectRowAtIndexPath:indexPath animated:TRUE]; // 重點是這2句代碼實現的功能 [tableView beginUpdates]; [tableView endUpdates];
自定義一個UIView的子類
//提供一個成員屬性,接收下載進度值 @property (nonatomic, assign) CGFloat progress;
重寫成員屬性progress的setter
//每次改變成員屬性progress的值,就會調用它的setter -(void)setProgress:(CGFloat)progress { _progress = progress; //當下載進度改變時,手動調用重繪方法 [self setNeedsDisplay]; }
重寫
-(void)drawRect:(CGRect)rect(核心) -(void)drawRect:(CGRect)rect { //設置圓弧的半徑 CGFloat radius = rect.size.width * 0.5; //設置圓弧的圓心 CGPoint center = CGPointMake(radius, radius); //設置圓弧的開始的角度(弧度制) CGFloat startAngle = - M_PI_2; //設置圓弧的終止角度 CGFloat endAngle = - M_PI_2 + 2 * M_PI * self.progress; //使用UIBezierPath類繪製圓弧 UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius - 5 startAngle:startAngle endAngle:endAngle clockwise:YES]; //將繪製的圓弧渲染到圖層上(即顯示出來) [path stroke]; }
經過UIImageView顯示動畫效果,其實是把動態的圖拆成了一組靜態的圖,放到數組中,播放的時候依次從數組中取出。若是播放的圖片比較少佔得內存比較小或者比較經常使用(好比工具條上一直顯示的動態小圖標),能夠選擇用imageNamed:方式獲取圖片,可是經過這種方式加到內存中,使用結束,不會本身釋放,屢次播放動畫會形成內存溢出問題。所以,對於大圖或常常更換的圖,在取圖片的時候能夠選擇imageWithContentsOfFile:方式獲取圖片,優化內存。
使用UIWebView顯示圖片須要注意顯示圖片的尺寸與UIWebView尺寸的設置,若是隻是爲了顯示動態圖片,能夠禁止UIWebView滾動。在顯示動態圖片的時候,即便是動圖的背景處爲透明,默認顯示出來是白色背景,這個時候須要手動設置UIWebView的透明才能達到顯示動圖背景透明的效果。
- XIB:在編譯前就提供了可視化界面,能夠直接拖控件,也能夠直接給控件添加約束,更直觀一些,並且類文件中就少了建立控件的代碼,確實簡化很多,一般每一個XIB對應一個類。 - Storyboard:在編譯前提供了可視化界面,可拖控件,可加約束,在開發時比較直觀,並且一個storyboard能夠有不少的界面,每一個界面對應一個類文件,經過storybard,能夠直觀地看出整個App的結構。 - XIB:需求變更時,須要修改XIB很大,有時候甚至須要從新添加約束,致使開發週期變長。XIB載入相比純代碼天然要慢一些。對於比較複雜邏輯控制不一樣狀態下顯示不一樣內容時,使用XIB是比較困難的。當多人團隊或者多團隊開發時,若是XIB文件被髮動,極易致使衝突,並且解決衝突相對要困難不少。 - Storyboard:需求變更時,須要修改storyboard上對應的界面的約束,與XIB同樣可能要從新添加約束,或者添加約束會形成大量的衝突,尤爲是多團隊開發。對於複雜邏輯控制不一樣顯示內容時,比較困難。當多人團隊或者多團隊開發時,你們會同時修改一個storyboard,致使大量衝突,解決起來至關困難。
當程序訪問了控制器的View屬性時會先判斷控制器的View是否存在,若是存在就直接返回已經存在的View; 若是不存在,就會先調用loadView這個方法;若是控制器的loadView方法實現了,就會按照loadView方法加載自定義的View; 若是控制器的loadView方法沒有實現就會判斷storyboard是否存在; 若是storyboard存在就會按照storyboard加載控制器的View;若是storyboard不存在,就會建立一個空視圖返回。
1.執行Main 2.執行UIApplicationMain函數. 3.建立UIApplication對象,並設置UIApplicationMain對象的代理. UIApplication的第三個參數就是UIApplication的名稱,若是指定爲nil,它會默認爲UIApplication. UIApplication的第四個參數爲UIApplication的代理. 4.開啓一個主運行循環.保證應用程序不退出. 5.加載info.plist.加載配置文件.判斷一下info.plist文件當中有沒有Main storyboard file base name裏面有沒有指定storyboard文件,若是有就去加載info.plist文件,若是沒有,那麼應用程序加載完畢.
在產生一個事件時,系統會將該事件加入到一個由UIApplication管理的事件隊列中, UIApplication會從事件隊列中取出最前面的事件,將它傳遞給先發送事件給應用程序的主窗口. 主窗口會調用hitTest方法尋找最適合的視圖控件,找到後就會調用視圖控件的touches方法來作具體的事情. 當調用touches方法,它的默認作法, 就會將事件順着響應者鏈條往上傳遞, 傳遞給上一個響應者,接着就會調用上一個響應者的touches方法
A target-action:當兩個對象之間有⽐較緊密的關係時,如視圖控制器與其下的某個視圖。
B delegate:當某個對象收到多個事件,並要求同一個對象來處理全部事件時。委託機制必須依賴於某個協議定義的⽅法來發送消息。
C NSNotification:當須要多個對象或兩個無關對象處理同一個事件時。 D Block:適⽤於回調只發⽣生一次的簡單任務。 參考答案:B
imgView.layer.cornerRadius = 10; // 這一行代碼是很消耗性能的 imgView.clipsToBounds = YES;
- (UIImage *)hyb_imageWithCornerRadius:(CGFloat)radius { CGRect rect = (CGRect){0.f, 0.f, self.size}; UIGraphicsBeginImageContextWithOptions(self.size, NO, UIScreen.mainScreen.scale); CGContextAddPath(UIGraphicsGetCurrentContext(), [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath); CGContextClip(UIGraphicsGetCurrentContext()); [self drawInRect:rect]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
而後調用時就直接傳一個圓角來處理:
imgView.image = [[UIImage imageNamed:@"test"] hyb_imageWithCornerRadius:4];
這麼作就是on-screen-rendering了,經過模擬器->debug->Color Off-screen-rendering看到沒有離屏渲染了!(黃色的小圓角沒有顯示了,說明這個不是離屏渲染了)
- (void)drawRect:(CGRect)rect { CGRect bounds = self.bounds; [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:8.0] addClip]; [self.image drawInRect:bounds]; }
這個問題有不少種方式,並且不一樣的使用場景也不同的。好比說: • 第一種:若是是點擊某個按鈕後,纔會刷新它的值,其它不用修改,那麼不用引用任何按鈕,直接在回調時,就已經將接收響應的按鈕給傳過來了,直接經過它修改便可。 • 第二種:點擊某個按鈕後,全部與之同類型的按鈕都要修改值,那麼能夠經過在建立按鈕時將按鈕存入到數組中,在須要的時候遍歷查找。
controller layout觸發的時候,開發者有機會去從新layout本身的各個subview。
橫豎屏切換的時候,系統會響應一些函數,其中 viewWillLayoutSubviews 和 viewDidLayoutSubviews。
- (void)viewWillLayoutSubviews { [self _shouldRotateToOrientation:(UIDeviceOrientation)[UIApplication sharedApplication].statusBarOrientation]; } -(void)_shouldRotateToOrientation:(UIDeviceOrientation)orientation { if (orientation == UIDeviceOrientationPortrait ||orientation == UIDeviceOrientationPortraitUpsideDown) { // 豎屏 } else { // 橫屏 } } 經過上述一個函數就知道橫豎屏切換的接口了。 注意:viewWillLayoutSubviews只能用在ViewController裏面,在view裏面沒有響應。
答:首先咱們從代碼來看,數據源如何關聯上的,實際上是在數據源關聯的代理方法裏實現的。 所以咱們並不關心如何去關聯他,他怎麼關聯上,方法只是讓我返回根據本身的須要去設置如相關的數據源。 所以,我以爲能夠設置多個數據源啊,可是有個問題是,你這是想幹嗎呢?想讓列表如何顯示,不一樣的數據源分區塊顯示?
CocoaTouch框架中用到了大量委託,其中UITableViewDelegate就是委託機制的典型應用,是一個典型的使用委託來實現適配器模式,其中UITableViewDelegate協議是目標,tableview是適配器,實現UITableViewDelegate協議,並將自身設置爲talbeview的delegate的對象,是被適配器,通常狀況下該對象是UITableViewController。 UITableVIew的Data Source方法有- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
答:iPhone OS 應用程序的基礎 Cocoa Touch 框架重用了許多 Mac 系統的成熟模式,可是它更多地專一於觸摸的接口和優化。
UIKit 爲您提供了在 iPhone OS 上實現圖形,事件驅動程序的基本工具,其創建在和 Mac OS X 中同樣的 Foundation 框架上,包括文件處理,網絡,字符串操做等。
Cocoa Touch 具備和 iPhone 用戶接口一致的特殊設計。有了 UIKit,您可使用 iPhone OS 上的獨特的圖形接口控件,按鈕,以及全屏視圖的功能,您還可使用加速儀和多點觸摸手勢來控制您的應用。
各色俱全的框架 除了UIKit 外,Cocoa Touch 包含了建立世界一流 iPhone 應用程序須要的全部框架,從三維圖形,到專業音效,甚至提供設備訪問 API 以控制攝像頭,或經過 GPS 獲知當前位置。
Cocoa Touch 既包含只須要幾行代碼就能夠完成所有任務的強大的 Objective-C 框架,也在須要時提供基礎的 C 語言 API 來直接訪問系統。這些框架包括:
Core Animation:經過 Core Animation,您就能夠經過一個基於組合獨立圖層的簡單的編程模型來建立豐富的用戶體驗。
Core Audio:Core Audio 是播放,處理和錄製音頻的專業技術,可以輕鬆爲您的應用程序添增強大的音頻功能。
Core Data:提供了一個面向對象的數據管理解決方案,它易於使用和理解,甚至可處理任何應用或大或小的數據模型。
功能列表:框架分類
下面是 Cocoa Touch 中一小部分可用的框架:
音頻和視頻:Core Audio ,OpenAL ,Media Library ,AV Foundation
數據管理 :Core Data ,SQLite
圖形和動畫 :Core Animation ,OpenGL ES ,Quartz 2D
網絡:Bonjour ,WebKit ,BSD Sockets
用戶應用:Address Book ,Core Location ,Map Kit ,Store Kit
File’s Owner 是全部 nib 文件中的每一個圖標,它表示從磁盤加載 nib 文件的對象;
First Responder 就是用戶當前正在與之交互的對象;
View 顯示用戶界面;完成用戶交互;是 UIView 類或其子類。
-[AppDelegate application:willFinishLaunchingWithOptions:] -[AppDelegate application:didFinishLaunchingWithOptions:] -[AppDelegate applicationDidBecomeActive:]
退到後臺:
-[AppDelegate applicationWillResignActive:] -[AppDelegate applicationDidEnterBackground:]
回到前臺:
-[AppDelegate applicationWillEnterForeground:] -[AppDelegate applicationDidBecomeActive:]
ViewController之間,
加載頁面:
-[mainViewController viewDidLoad] -[mainViewController viewWillAppear:] -[mainViewController viewWillLayoutSubviews] -[mainViewController viewDidLayoutSubviews] -[mainViewController viewDidAppear:]
退出當前頁面:
-[mainViewController viewWillDisappear:] -[mainViewController viewDidDisappear:]
返回以前頁面:
-[mainViewController viewWillAppear:] -[mainViewController viewWillLayoutSubviews] -[mainViewController viewDidLayoutSubviews] -[mainViewController viewDidAppear:]
CoreText
• 隨意修改文本的樣式
• 圖文混排(純C語言) • 國外:Niumb Core Image(濾鏡處理) * 能調節圖片的各類屬性(對比度, 色溫, 色差等)
block, target-action ,代理,屬性
-(void)touchesBegan:(NSSet)touchedwithEvent:(UIEvent)event;
-(void)touchesMoved:(NSSet)touched withEvent:(UIEvent)event;
-(void)touchesEnded:(NSSet)touchedwithEvent:(UIEvent)event;
-(void)touchesCanceled:(NSSet)touchedwithEvent:(UIEvent)event;
文章若有問題,請留言,我將及時更正。