UI

一.控件

1.屬性

1> frame和bounds的區(qū)別

frame:可表示尺寸和位置,與父視圖坐標系的關(guān)系,位置以自己的左上角為原點,可用于形變和位移

bounds:可表示尺寸和位置,與自身視圖坐標系的關(guān)系,大多數(shù)情況(滾動視圖的子視圖等除外)以自己的中心點為原點,可用于形變

center:只表示位置,表示自己中心的坐標,可用于位移

2> trasform

修改位移\形變\旋轉(zhuǎn),transform不同于board\center\frame,前者中記錄的是形變的數(shù)據(jù),不發(fā)生形變其值是空的,所以我們需要新建結(jié)構(gòu)體,用CGAffineTransform(仿射變換)函數(shù)給對象結(jié)構(gòu)體屬性賦值,而后者是控件的固有屬性,內(nèi)存數(shù)據(jù)是始終存在的,當我們用他們做移動等操作時,是改變其值,所以是結(jié)構(gòu)體賦值三步曲,不用CG的函數(shù)

使用情景區(qū)別: transform一般用于有來有回的變化,而frame是有去無回

2.UIScrollView

1> contentsize、contentoffset、contentinset的區(qū)別

內(nèi)容視圖的尺寸

內(nèi)容視圖當前位置相對滾動視圖frame的偏移量

內(nèi)容視圖相對滾動視圖frame的展示原點

3.UITableview

1> 自定義高度

1.1>新建一個繼承自UITableViewCell的類

1.2>重寫initWithStyle:reuseIdentifier:方法

1.3>添加所有需要顯示的子控件(不需要設(shè)置子控件的數(shù)據(jù)和frame,? 子控件要添加到contentView中)

1.4>進行子控件一次性的屬性設(shè)置(有些屬性只需要設(shè)置一次, 比如字體\固定的圖片)

1.5>提供2個模型

數(shù)據(jù)模型: 存放文字數(shù)據(jù)\圖片數(shù)據(jù)

frame模型: 存放數(shù)據(jù)模型\所有子控件的frame\cell的高度

1.6>cell擁有一個frame模型(不要直接擁有數(shù)據(jù)模型)

1.7>重寫frame模型屬性的setter方法: 在這個方法中設(shè)置子控件的顯示數(shù)據(jù)和frame

2> 自定義高度原理

A 手動計算

1>? 由于heightForRow比cellForRow方法先調(diào)用,創(chuàng)建frame模型包含微博模型,重寫微博模型賦值set方法,提前計算cell子控件的frame并保存,heightForRow方法中取出frame模型中保存的高度,實現(xiàn)自定義高度cell

2>? 設(shè)置最大尺寸、文本屬性,根據(jù)文本內(nèi)容計算正文內(nèi)容展示尺寸

3>? cellForRow中創(chuàng)建自定義cell包含frame屬性,重寫frame屬性set方法創(chuàng)建cell子控件并賦值frame模型保存的子控件尺寸

B. 自動計算

1>? 首先設(shè)置行高使用autolayout自動計算并預(yù)估高度

2>? 在stroboard中對cell內(nèi)容進行自動布局,注意設(shè)置圖片距離底部約束,cellForRow中創(chuàng)建storyboard中對應(yīng)標記的自定義cell

3>? 由于正文內(nèi)容的不確定性,設(shè)置label多行,拖線圖片高度約束,根據(jù)圖片有無,設(shè)置代碼設(shè)置高度約束

4.UICollectionView

1> 如何實現(xiàn)瀑布流,流水布局

1.1> 使用UICollectionView

1.2> 使用自定義的FlowLayout

1.3> 需要在layoutAttributesForElementsInRect中設(shè)置自定義的布局(item的frame)

1.4> 在 prepareLayout中計算布局

1.5> 遍歷數(shù)據(jù)內(nèi)容,根據(jù)索引取出對應(yīng)的attributes(使用layoutAttributesForCellWithIndexPath),根據(jù)九宮格算法設(shè)置布局

1.6> 細節(jié)1: 實時布局,重寫shouldInvalidateLayoutForBoundsChange(bounds改變重新布局,scrollview的contentoffset>bounds)

1.7> 細節(jié)2: 計算設(shè)置itemsize(保證內(nèi)容顯示完整,uicollectionview的content size是根據(jù)itemize計算的),根據(jù)列最大高度/對應(yīng)列數(shù)量求出,最大高度累加得到

1.8> 細節(jié)3: 追加item到最短列,避免底部參差不齊.

2> 和UITableView的使用區(qū)別

1)必須使用下面的方法進行Cell類的注冊:

- (void)registerClass:forCellWithReuseIdentifier:

- (void)registerClass:forSupplementaryViewOfKind:withReuseIdentifier:

- (void)registerNib:forCellWithReuseIdentifier:

2)collectionView與tableView最大的不同點,collectionView必須要使用自己的layout(UICollectionViewLayout)

如:

UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];

flowLayout.itemSize = CGSizeMake(52, 52);? ? ? ? ? ? ? // cell大小

flowLayout.minimumInteritemSpacing = 1;? ? ? ? ? ? ? ? // cell間距

flowLayout.minimumLineSpacing = 1;? ? ? ? ? ? ? ? ? ? ? // cell行距

flowLayout.sectionInset = (UIEdgeInsets){81,1,1,1};? ? // cell邊距

創(chuàng)建collectionView需要帶Layout的初始化方法:

- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;

5.UIImage

1> 有哪幾種加載方式

1.1> 二進制? ? imageWithData

1.2> Bundle? ? imageWithName

1.3> 本地路徑? imageWithContentOfFile

1.4>

6.webview

1>解決webview的內(nèi)存占用和泄露

7.描述九宮格算法

1>? 1> 根據(jù)格子寬appW高appH和每行格數(shù)totalCol計算格子間隙marginX

CGFloat marginX = (self.view.frame.size.width - totalCol * appW)/(totalCol + 1);

2>? 2> 根據(jù)序號i和每行格數(shù)totalCol計算行號列號

int row = i / totalCol;

int col = i % totalCol;

3>? 3> 根據(jù)格子間隙、格子寬高和行號列號計算x,y

CGFloat appX = marginX + col * (appW + marginX);

CGFloat appY = row * (appH + marginY);

8. 實現(xiàn)圖片輪播圖

1>? 1> UIScrollView設(shè)置contentSize,添加圖片并設(shè)置frame,設(shè)置分頁

2>? 2> 添加分頁控制器,在UIScrollView滾動代理方法中根據(jù)contentOffset計算當前頁數(shù)并設(shè)置

3> 設(shè)置定時器,主動改變contentOffset,設(shè)置定時器的模式進行并發(fā)操作(終極方案定時器放在異步線程)

二.生命周期

1> 應(yīng)用的生命周期

各個程序運行狀態(tài)時代理的回調(diào):

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions? 告訴代理進程啟動但還沒進入狀態(tài)保存

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions? 告訴代理啟動基本完成程序準備開始運行

- (void)applicationWillResignActive:(UIApplication *)application? 當應(yīng)用程序?qū)⒁敕腔顒訝顟B(tài)執(zhí)行,在此期間,應(yīng)用程序不接收消息或事件,比如來電話了

- (void)applicationDidBecomeActive:(UIApplication *)application? ? 當應(yīng)用程序入活動狀態(tài)執(zhí)行,這個剛好跟上面那個方法相反

- (void)applicationDidEnterBackground:(UIApplication *)application? 當程序被推送到后臺的時候調(diào)用。所以要設(shè)置后臺繼續(xù)運行,則在這個函數(shù)里面設(shè)置即可

- (void)applicationWillEnterForeground:(UIApplication *)application? 當程序從后臺將要重新回到前臺時候調(diào)用,這個剛好跟上面的那個方法相反。

- (void)applicationWillTerminate:(UIApplication *)application? 當程序?qū)⒁顺鍪潜徽{(diào)用,通常是用來保存數(shù)據(jù)和一些退出前的清理工作。

2> 視圖的生命周期

loadView - 默認調(diào)用super方法,根據(jù)控制器創(chuàng)建方式加載視圖,重寫后將根據(jù)重寫方法創(chuàng)建視圖

viewDidLoad-視圖加載完成

viewWillAppear-UIViewController對象的視圖即將加入窗口時調(diào)用;

viewDidApper-UIViewController對象的視圖已經(jīng)加入到窗口時調(diào)用;

viewWillDisappear-UIViewController對象的視圖即將消失、被覆蓋或是隱藏時調(diào)用;

viewDidDisappear-UIViewController對象的視圖已經(jīng)消失、被覆蓋或是隱藏時調(diào)用;

viewVillUnload-當內(nèi)存過低時,需要釋放一些不需要使用的視圖時,即將釋放時調(diào)用;

viewDidUnload-當內(nèi)存過低,釋放一些不需要的視圖時調(diào)用。

3>? load initialize方法的區(qū)別

+(void)load

+(void)initialize

執(zhí)行時機

在程序運行后立即執(zhí)行

在類的方法第一次被調(diào)時執(zhí)行

若自身未定義,是否沿用父類的方法?

類別中的定義

全都執(zhí)行,但后于類中的方法

覆蓋類中的方法,只執(zhí)行一個

4> 創(chuàng)建控制器、視圖的方式

4.1> 創(chuàng)建控制器的方式

1)通過代碼的方式加載viewController

UIViewController *controller = [[UIViewController alloc] init];

2)通過stroyboard來加載viewController

2.1) 加載storyboard中箭頭指向的viewController

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; //加載箭頭指向的viewController

CZViewController *controller = [storyboard instantiateInitialViewController];

2.2) 加載storyboard中特定標示的viewController(storyboard可以有多個controller)

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

CZViewController *controller = [storyboard instantiateViewControllerWithIdentifier:@"two"];

3)通過xib加載viewController

3.1) 傳統(tǒng)方法

3.1.1)創(chuàng)建Xib,并指定xib的files owner為自定義控制器類(為了能連線關(guān)聯(lián)管理IB的內(nèi)容)

3.1.2)xib中要有內(nèi)容,且xib中描述的控制器類的view屬性要與xib的view控件完成關(guān)聯(lián)(關(guān)聯(lián)方法兩種,一種是control+files owner拖線到xib中搭建的指定view控件,另一種是指定xib中的view拖線到@interface)

3.1.3)從xib加載viewController

CZViewController *controller = [[CZViewController alloc] initWithNibName:@"CZOneView" bundle:nil];

3.2)bundle中取出xib內(nèi)容

CZViewController *vc = [[NSBundle mainBundle] loadNibNamed:@"Two" owner:nil options:nil].lastObject;

4.2> 創(chuàng)建視圖的方式

1.用系統(tǒng)的loadView方法創(chuàng)建控制器的視圖

2.如果指定加載某個storyboard文件做控制器的視圖,就會加載storyboard里面的描述去創(chuàng)建view

3.如果指定讀取某個xib文件做控制器的視圖,就根據(jù)指定的xib文件去加載創(chuàng)建

4.如果有xib文件名和控制器的類名前綴(也就是去掉controller)的名字一樣的? xib文件 就會用這個xib文件來創(chuàng)建控件器的視圖 例:控件器的名為 MJViewController? xib文件名為 MJView.xib? 如果xib文件名后有一個字不一樣就不會去根據(jù)它去創(chuàng)建如:MJView8.xib

5.找和控制器同名的xib文件去創(chuàng)建

6.如果以上都沒有就創(chuàng)建一個空的控制器的視圖;

5> UIWindow

是一種特殊的UIView,通常在一個程序中只會有一個UIWindow,但可以手 動創(chuàng)建多個UIWindow,同時加到程序里面。UIWindow在程序中主要起到三個作用:

1、作為容器,包含app所要顯示的所有視圖

2、傳遞觸摸消息到程序中view和其他對象

3、與UIViewController協(xié)同工作,方便完成設(shè)備方向旋轉(zhuǎn)的支持

三.多控制器管理

1.

四.核心繪圖

6> View和layer的區(qū)別

圖層不會直接渲染到屏幕上,UIView是iOS系統(tǒng)中界面元素的基礎(chǔ),所有的界面元素都是繼承自它。它本身完全是由CoreAnimation來實現(xiàn)的。它真正的繪圖部分,是由一個CALayer類來管理。UIView本身更像是一個CALayer的管理器。一個UIView上可以有n個CALayer,每個layer顯示一種東西,增強UIView的展現(xiàn)能力。

6.1>都可以顯示屏幕效果

6.2> 如果需要用戶交互就要用UIVIew,其可接收觸摸事件(繼承UIResponder),而CALayer不能接收觸摸事件

6.3> 如果沒有用戶交互可選用CALayer,因為其所在庫較小,占用的資源較少

7> new和alloc init的區(qū)別

采用new的方式只能采用默認的init方法完成初始化,采用alloc的方式可以用其他定制的初始化方法。

五.動畫

1> ios界面切換

2> iOS中各種動畫的類型&特點&使用場景

CAPropertyAnimation

是CAAnimation的子類,也是個抽象類,要想創(chuàng)建動畫對象,應(yīng)該使用它的兩個子類:CABasicAnimation和CAKeyframeAnimation

屬性解析:

keyPath:通過指定CALayer的一個屬性名稱為keyPath(NSString類型),并且對CALayer的這個屬性的值進行修改,達到相應(yīng)的動畫效果。比如,指定@”position”為keyPath,就修改CALayer的position屬性的值,以達到平移的動畫效果

CABasicAnimation

CAPropertyAnimation的子類

屬性解析:

fromValue:keyPath相應(yīng)屬性的初始值

toValue:keyPath相應(yīng)屬性的結(jié)束值

隨著動畫的進行,在長度為duration的持續(xù)時間內(nèi),keyPath相應(yīng)屬性的值從fromValue漸漸地變?yōu)閠oValue

如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在動畫執(zhí)行完畢后,圖層會保持顯示動畫執(zhí)行后的狀態(tài)。但在實質(zhì)上,圖層的屬性值還是動畫執(zhí)行前的初始值,并沒有真正被改變。比如,CALayer的position初始值為(0,0),CABasicAnimation的fromValue為(10,10),toValue為(100,100),雖然動畫執(zhí)行完畢后圖層保持在(100,100)這個位置,實質(zhì)上圖層的position還是為(0,0)

CAKeyframeAnimation

CApropertyAnimation的子類,跟CABasicAnimation的區(qū)別是:CABasicAnimation只能從一個數(shù)值(fromValue)變到另一個數(shù)值(toValue),而CAKeyframeAnimation會使用一個NSArray保存這些數(shù)值

屬性解析:

values:就是上述的NSArray對象。里面的元素稱為”關(guān)鍵幀”(keyframe)。動畫對象會在指定的時間(duration)內(nèi),依次顯示values數(shù)組中的每一個關(guān)鍵幀

path:可以設(shè)置一個CGPathRef\CGMutablePathRef,讓層跟著路徑移動。path只對CALayer的anchorPoint和position起作用。如果你設(shè)置了path,那么values將被忽略

keyTimes:可以為對應(yīng)的關(guān)鍵幀指定對應(yīng)的時間點,其取值范圍為0到1.0,keyTimes中的每一個時間值都對應(yīng)values中的每一幀.當keyTimes沒有設(shè)置的時候,各個關(guān)鍵幀的時間是平分的

CABasicAnimation可看做是最多只有2個關(guān)鍵幀的CAKeyframeAnimation

CAAnimationGroup

CAAnimation的子類,可以保存一組動畫對象,將CAAnimationGroup對象加入層后,組中所有動畫對象可以同時并發(fā)運行

屬性解析:

animations:用來保存一組動畫對象的NSArray

默認情況下,一組動畫對象是同時運行的,也可以通過設(shè)置動畫對象的beginTime屬性來更改動畫的開始時間

CATransition

CAAnimation的子類,用于做轉(zhuǎn)場動畫,能夠為層提供移出屏幕和移入屏幕的動畫效果。iOS比Mac OS X的轉(zhuǎn)場動畫效果少一點

UINavigationController就是通過CATransition實現(xiàn)了將控制器的視圖推入屏幕的動畫效果

屬性解析:

type:動畫過渡類型

subtype:動畫過渡方向

startProgress:動畫起點(在整體動畫的百分比)

endProgress:動畫終點(在整體動畫的百分比)

UIView動畫

UIKit直接將動畫集成到UIView類中,當內(nèi)部的一些屬性發(fā)生改變時,UIView將為這些改變提供動畫支持

執(zhí)行動畫所需要的工作由UIView類自動完成,但仍要在希望執(zhí)行動畫時通知視圖,為此需要將改變屬性的代碼放在[UIView beginAnimations:nil context:nil]和[UIView commitAnimations]之間

Block動畫

幀動畫

六.事件處理

1> 描述響應(yīng)者鏈條

當觸摸事件發(fā)生時,壓力轉(zhuǎn)為電信號,iOS系統(tǒng)將產(chǎn)生UIEvent對象,記錄事件產(chǎn)生的時間和類型,然后系統(tǒng)將事件加入到一個由UIApplication管理的事件隊列中。

UIApplication會從事件隊列中取出最前面的事件,并將事件分發(fā)下去以便處理,通常,先發(fā)送事件給應(yīng)用程序的主窗口(keyWindow)

主窗口會在視圖層次結(jié)構(gòu)中找到一個最合適的視圖來處理觸摸事件(從父到子,從后到前),這也是整個事件處理過程的第一步

找到合適的視圖控件后,就會調(diào)用視圖控件的touches方法來作具體的事件處理

4.Runloop

1> 每個線程上都有一個runloop,主線程默認開啟,輔助線程需要手動開啟,主要用于

使用端口或自定義輸入源來和其他線程通信

使用線程的定時器

Cocoa中使用任何performSelector…的方法

使線程周期性工作

2> runloop的工作流程

七.屏幕適配

多線程

一.資源搶奪

2> 資源搶奪解決方案

@sychronized{ }

dispatch_barrier_async

NSLock NSCondition

dispatch_semaphore_wait

二.iOS多線程技術(shù)

3> 對比iOS中的多線程技術(shù)

3.1> pthread

pthread跨平臺,使用難度大,需要手動管理線程生命周期

pthread_create創(chuàng)建線程,傳參線程標記,線程屬性,初始函數(shù),函數(shù)參數(shù)

3.2> NSThread

NSThread需要手動管理線程生命周期和

3.3> GCD

3.4> NSOperation

GCD是純C語言的API,NSOperationQueue是基于GCD的OC版本封裝

3.2> GCD僅僅支持FIFO隊列,只可以設(shè)置隊列的優(yōu)先級,而NSOperationQueue中的每一個任務(wù)都可以被重新設(shè)置優(yōu)先級(setQueuePriority:),從而實現(xiàn)不同操作的執(zhí)行順序調(diào)整

3.3> GCD不支持異步操作之間的依賴關(guān)系設(shè)置。如果某個操作的依賴另一個操作的數(shù)據(jù),使用NSOperationQueue能夠設(shè)置依賴按照正確的順序執(zhí)行操作(addDependency:)。GCD則沒有內(nèi)建的依賴關(guān)系支持(只能通過Barrior和同步任務(wù)手動實現(xiàn))。

3.4> NSOperationQueue方便停止隊列中的任務(wù)(cancelAllOperations, suspended),GCD不方便停止隊列中的任務(wù).

3.5> NSOperationQueue支持KVO,可以監(jiān)測operation是否正在執(zhí)行(isExecuted)、是否結(jié)束(isFinished),是否取消(isCanceld)

3.6> GCD的執(zhí)行速度比NSOperationQueue快

3.7> NSOperationQueue可設(shè)置最大并發(fā)數(shù)量(節(jié)電),GCD具有dispatch_once(只執(zhí)行一次,單例)和dispatch_after(延遲執(zhí)行)功能

3.8> NSObject分類(perform)和NSThread遇到對象分配需要手動內(nèi)存管理,手動管理線程生命周期

3.9> NSThread查看線程

3.10> NSObject分類線程通信

4> 原子屬性

原子屬性采用的是"多讀單寫"機制的多線程策略

"多讀單寫"縮小了鎖范圍,比互斥鎖的性能好

規(guī)定只在主線程更新UI,就是因為如果在多線程中更新,就需要給UI對象加鎖,防止資源搶占寫入錯誤,但是這樣會降低UI交互的性能,所以ios設(shè)計讓所有UI對象都是非線程安全的(不加鎖),并規(guī)定只在主線程中更新UI,規(guī)避多線程搶占資源問題

三.其他

1> 多線程優(yōu)缺點

優(yōu)點:

使應(yīng)用程序的響應(yīng)速度更快,用戶界面在進行其他工作的同時仍始終保持活動狀態(tài);

優(yōu)化任務(wù)執(zhí)行,適當提高資源利用率(cpu, 內(nèi)存);

缺點:

線程占用內(nèi)存空間,管理線程需要額外的CPU開銷,開啟大量線程,降低程序性能;

增加程序復(fù)雜度,如線程間通信,多線程的資源共享等;

2> 在多線程中使用通知需要注意什么問題?

3> iOS中的延遲操作

1> [self performSelector:@selector(clearCache) withObject:nil afterDelay:duration];

1>? 2> dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{..});

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 7、不使用IB是,下面這樣做有什么問題? 6、請說說Layer和View的關(guān)系,以及你是如何使用它們的。 1.首先...
    AlanGe閱讀 719評論 0 1
  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點贊按鈕進度條TabLayout圖標下拉刷新...
    皇小弟閱讀 46,887評論 22 665
  • UI viewcontroller的一些方法的說明viewDidLoad,viewWillDisappear, v...
    b485c88ab697閱讀 3,596評論 0 22
  • 一.控件 1.屬性 1> frame和bounds的區(qū)別 frame:可表示尺寸和位置,與父視圖坐標系的關(guān)系,位置...
    藍心兒的藍色之旅閱讀 788評論 0 0
  • 你總是在入夢時被記起亭亭玉立的是你細步款款的是你在回廊上對月空望的也是你 送別多在江畔玉壺光轉(zhuǎn),曲終人散一切歸于沉...
    余子嵐閱讀 392評論 2 3