可能碰到的iOS筆試面試題(10)--UI

UI

viewcontroller的一些方法的說明viewDidLoad,viewWillDisappear, viewWillAppear方法的 順序和作用哗魂?

viewWillAppear:視圖即將可見時調(diào)用。默認情況下不執(zhí)行任何操作

viewDidAppear:視圖已完全過渡到屏幕上時調(diào)用

viewWillDisappear:視圖被駁回時調(diào)用瓣颅,覆蓋或以其他方式隱藏窄俏。默認情況下不執(zhí)行任何操作

viewDidDisappear:視圖被駁回后調(diào)用霸旗,覆蓋或以其他方式隱藏芝囤。默認情況下不執(zhí)行任何操作loadView; .這是當他們沒有正在使用nib視圖頁面敢伸,子類將會創(chuàng)建自己的自定義視圖層。絕不能直接調(diào)用喳魏。

viewDidLoad:在視圖加載后被調(diào)用棉浸,如果是在代碼中創(chuàng)建的視圖加載器,他將會在loadView方法后被調(diào)用刺彩,如果是從nib視圖頁面輸出迷郑,他將會在視圖設置好后后被調(diào)用枝恋。

「initWithNibName: bundle:」載入nib檔案來初始化「loadView」載入視圖「viewDidLoad」在載入視圖至內(nèi)存后會呼叫的方法「viewDidUnload」在視圖從內(nèi)存中釋放后會呼叫的方法 (當內(nèi)存過低,釋放一些不需要的視圖時調(diào)用)

「viewWillAppear」當收到視圖在視窗將可見時的通知會呼叫的方法

「viewDidAppear」當收到視圖在視窗已可見時的通知會呼叫的方法

「viewWillDisappear」當收到視圖將去除嗡害、被覆蓋或隱藏于視窗時的通知會呼叫的方法

「viewDidDisappear」當收到視圖已去除焚碌、被覆蓋或隱藏于視窗時的通知會呼叫的方法

「didReceiveMemoryWarning」收到系統(tǒng)傳來的內(nèi)存警告通知后會執(zhí)行的方法

「shouldAutorotateToInterfaceOrientation」是否支持不同方向的旋轉視圖

「willAnimateRotationToInterfaceOrientation」在進行旋轉視圖前的會執(zhí)行的方法(用于調(diào)整旋轉視圖之用)

代碼的執(zhí)行順序

1、 alloc 創(chuàng)建對象霸妹,分配空間

2十电、init (initWithNibName) 初始化對象,初始化數(shù)據(jù)

3叹螟、loadView 從nib載入視圖 鹃骂,通常這一步不需要去干涉。除非你沒有使用xib文件創(chuàng)建視圖

4罢绽、viewDidLoad 載入完成畏线,可以進行自定義數(shù)據(jù)以及動態(tài)創(chuàng)建其他控件

5、viewWillAppear 視圖將出現(xiàn)在屏幕之前良价,馬上這個視圖就會被展現(xiàn)在屏幕上了

6寝殴、viewDidAppear 視圖已在屏幕上渲染完成當一個視圖被移除屏幕并且銷毀的時候的執(zhí)行順序,這個順序差不多和上面的相反

1明垢、viewWillDisappear 視圖將被從屏幕上移除之前執(zhí)行

2杯矩、viewDidDisappear 視圖已經(jīng)被從屏幕上移除,用戶看不到這個視圖了

3袖外、dealloc 視圖被銷毀史隆,此處需要對你在init和viewDidLoad中創(chuàng)建的對象進行釋放

什么是key window?

  • 一個窗口當前能接受鍵盤和非觸摸事件時曼验,便被認為是主窗口泌射。而觸摸事件則被投遞到觸摸發(fā)生的窗口,沒有相應坐標值的事件被投遞到主窗口鬓照。同一時刻只有一個窗口是主窗口熔酷。

談一談你是怎么封裝view的

- 先添加所需子控件
- 再接收模型數(shù)據(jù)根據(jù)模型數(shù)據(jù)設置子控件數(shù)據(jù)和位置
- 簡而言之, 自己的事情自己做, 把不需要暴露出去的封裝起來

簡單說一下APP的啟動過程,從main文件開始說起

    程序啟動分為兩類:1.有storyboard 2.沒有storyboard
有storyboard情況下:
1.main函數(shù)
2.UIApplicationMain
* 創(chuàng)建UIApplication對象
* 創(chuàng)建UIApplication的delegate對象
3.根據(jù)Info.plist獲得Main.storyboard的文件名,加載Main.storyboard(有storyboard)
* 創(chuàng)建UIWindow
* 創(chuàng)建和設置UIWindow的rootViewController
* 顯示窗口

沒有storyboard情況下:
1.main函數(shù)
2.UIApplicationMain
* 創(chuàng)建UIApplication對象
* 創(chuàng)建UIApplication的delegate對象
3.delegate對象開始處理(監(jiān)聽)系統(tǒng)事件(沒有storyboard)
* 程序啟動完畢的時候, 就會調(diào)用代理的application:didFinishLaunchingWithOptions:方法
* 在application:didFinishLaunchingWithOptions:中創(chuàng)建UIWindow
* 創(chuàng)建和設置UIWindow的rootViewController
* 顯示窗口

怎么解決緩存池滿的問題(cell)

iOS中不存在緩存池滿的情況,因為通常我們ios中開發(fā)豺裆,對象都是在需要的時候才會創(chuàng)建拒秘,有種常用的說話叫做懶加載,還有在UITableView中一般只會創(chuàng)建剛開始出現(xiàn)在屏幕中的cell臭猜,之后都是從緩存池里取躺酒,不會在創(chuàng)建新對象。緩存池里最多也就一兩個對象蔑歌,緩存池滿的這種情況一般在開發(fā)java中比較常見羹应,java中一般把最近最少使用的對象先釋放。

UIButton與UITableView的層級結構

  • 繼承結構次屠,屬于內(nèi)部的子控件結構

  • UIButton為:UIButton > UIControl > UIView > UIResponder > NSObject

  • UITableView為:UITableView > UIScrollView > UIView > UIResponder > NSObject

設置scroll view的contensize能在Viewdidload里設置么,為什么

  • 一般情況下可以設置在viewDidLoad中园匹,但在autolayout下雳刺,系統(tǒng)會在viewDidAppear之前根據(jù)subview的constraint重新計算scrollview的contentsize。 這就是為什么裸违,在viewdidload里面手動設置了contentsize沒用掖桦。因為在后面,會再重新計算一次供汛,前面手動設置的值會被覆蓋掉枪汪。

  • 解決辦法就是:

    • 去除autolayout選項,自己手動設置contentsize

    • 如果要使用autolayout紊馏,要么自己設置完subview的constraint料饥,然后讓系統(tǒng)自動根據(jù)constraint計算出contentsize蒲犬。要么就在viewDidAppear里面自己手動設置contentsize朱监。

簡述你對UIView、UIWindow和CALayer的理解

  • UIView: 屬于UIkit.framework框架,負責渲染矩形區(qū)域的內(nèi)容,為矩形區(qū)域添加動畫,響應區(qū)域的觸摸事件,布局和管理一個或多個子視圖

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

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

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

    • 與UIViewController協(xié)同工作,方便完成設備方向旋轉的支持

  • CAlayer:屬于QuartzCore.framework,是用來繪制內(nèi)容的,對內(nèi)容進行動畫處理依賴與UIView來進行顯示,不能處理用戶事件赫编。

  • UIView和CALayer是相互依賴的,UIView依賴CALayer提供內(nèi)容,CALayer依賴UIView的容器顯示繪制內(nèi)容。

  • (補充)UIViewController:每個視圖控制器都有一個自帶的視圖,并且負責這個視圖相關的一切事務奋隶。方便管理視圖中的子視圖,負責model與view的通信;檢測設備旋轉以及內(nèi)存警告;是所有視圖控制類的積累,定義了控制器的基本功能擂送。

frame和bounds有什么不同?(Difference between frame and bounds?)

  • frame指的是:該view在父view坐標系統(tǒng)中的位置和大形ㄐ馈(參照點是父親的坐標系統(tǒng))

  • bounds指的是:該view在本身坐標系統(tǒng)中的位置和大朽诙帧(參照點是本身坐標系統(tǒng))

關于頁面間傳值的問題?

屬性傳值:A頁面設置屬性 NSString *paramString,在跳轉B頁面的時候初始化paramString境氢。
//A頁面.h文件
@property (nonatomic, copy)NSString *paramString;
//A頁面.m文件
 NextViewController *nextVC = [[NextViewController alloc] init];
 nextVC.paramString = @"參數(shù)傳質(zhì)";
 [self presentViewController:nextVC animated:YES completion:nil];
 
委托delegate傳值:在B頁面定義delegate蟀拷,并且設置delegate屬性,在A頁面實現(xiàn)delegate協(xié)議

通知notification傳值:在B頁面中發(fā)送通知萍聊,在A頁面注冊觀察者并且在不用的時候移除觀察者问芬。
//B頁面發(fā)送通知 
[[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的時候調(diào)用這個block寿桨。在A頁面跳轉到B頁面的時候對B頁面的block賦值此衅。
//B頁面定義block,并設置block類型的變量
 typedef void (^ablock)(NSString *str);
 @property (nonatomic, copy) ablock block; 
//B頁面跳轉到A頁面調(diào)用這個block
 self.block(self.nameTextField.text);
 [self dismissViewControllerAnimated:YES completion:nil];
//A頁面跳轉到B頁面的時候對B頁面的block賦值亭螟,這樣在B頁面跳轉的時候就會回調(diào)這個block函數(shù)
 [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頁面實現(xiàn)
- (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];
//實現(xiàn)這個觀察對象的方法
 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
//在B頁面對userName進行設置,在A頁面都可以間聽到
 
 單例模式傳值:通過全局的方式保存
 對于通知代理面試常問, 代理和通知分別在什么情況下使用? 區(qū)別? 各自優(yōu)點?

關于視圖的生命周期的問題

  • 首先判斷控制器是否有視圖默伍,如果沒有就調(diào)用loadView方法創(chuàng)建:通過storyboard或者代碼欢嘿;

  • 隨后調(diào)用viewDidLoad衰琐,可以進行下一步的初始化操作;只會被調(diào)用一次炼蹦;

  • 在視圖顯示之前調(diào)用viewWillAppear羡宙;該函數(shù)可以多次調(diào)用;

  • 視圖viewDidAppear

  • 在視圖顯示之前調(diào)用viewWillDisappear掐隐;該函數(shù)可以多次調(diào)用狗热;如需要);

  • 在布局變化前后虑省,調(diào)用viewWill/DidLayoutSubviews處理相關信息匿刮;

  • 視圖生命周期圖

  • image
    image

響應者鏈條? (What is responder chain?)

  • 事件響應鏈。包括點擊事件探颈,畫面刷新事件等熟丸。在視圖棧內(nèi)從上至下,或者從下之上傳播. 可以說點事件的分發(fā)伪节,傳遞以及處理光羞。具體可以去看下touch事件這塊。

  • 首先解釋響應者鏈的概念

    • UIResponder類怀大,是UIKIT中一個用于處理事件響應的基類纱兑。窗口上的所有事件觸發(fā),都由該類響應(即事件處理入口)化借。所以潜慎,窗口上的View及控制器都是派生于該類的,例如UIView蓖康、UIViewController等铐炫。

    • 調(diào)用UIResponder類提供的方法或屬性,我們就可以捕捉到窗口上的所有響應事件钓瞭,并進行處理驳遵。

    • 響應者鏈條是由多個響應者對象連接起來的鏈條,其中響應者對象是能處理事件的對象山涡,所有的View和ViewController都是響應者對象堤结,利用響應者鏈條能讓多個控件處理同一個觸摸事件.

  • 事件傳遞機制

如果當前view不能處理當前事件,那么事件將會沿著響應者鏈(Responder Chain)進行傳遞鸭丛,知道遇到能處理該事件的響應者(Responsder Object)竞穷。
image
image
- 接收事件的initial view如果不能處理該事件并且她不是頂層的View,則事件會往它的父View進行傳遞鳞溉。

- initial view的父View獲取事件后如果仍不能處理瘾带,則繼續(xù)往上傳遞,循環(huán)這個過程熟菲。如果頂層的View還是不能處理這個事件的話看政,則會將事件傳遞給它們的ViewController朴恳,

- 如果ViewController也不能處理,則傳遞給Window(UIWindow)允蚣,此時Window不能處理的話就將事件傳遞UIApplication于颖,最后如果連Application也不能處理,則廢棄該事件

ViewController的loadView,viewDidLoad,viewDidUnload分別是在什么時候調(diào)用的嚷兔?在自定義ViewController的時候這幾個函數(shù)里面應該做什么工作森渐?

  • viewDidLoad在view從nib文件初始化時調(diào)用,

  • loadView在controller的view為nil時調(diào)用冒晰。

  • 此方法在編程實現(xiàn)view時調(diào)用, view控制器默認會注冊memory warning notification,當viewcontroller的任何view沒有用的時候同衣,viewDidUnload會被調(diào)用,在這里實現(xiàn)將retain的view release,如果是retain的IBOutlet view屬性則不要在這里release,IBOutlet會負責release壶运。

UITableView的重用機制?(或者如何在一個view上顯示多個tableView,tableView要求不同的數(shù)據(jù)源以及不同的樣式 (要求自定義cell), 如何組織各個tableView的delegate和dataSource?請說說實現(xiàn)思路?)

  • 查看UITableView頭文件,會找到NSMutableArray *visiableCells,和NSMutableArray * reusableTableCells兩個結構耐齐。

  • visiableCells內(nèi)保存當前顯示的cells,reusableTableCells保存可重用的cells。

  • TableView顯示之初,reusableTableCells為空,那么
    [tableView dequeueReusableCellWithIdentifier:CellIdentifier]返回nil前弯。

  • 開始的cell都是通過 [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] 來創(chuàng)建,而且cellForRowAtIndexPath只是調(diào)用最大顯示cell數(shù)的次數(shù)蚪缀。 比如:有100條數(shù)據(jù),iPhone一屏最多顯示10個cell秫逝。

  • 程序最開始顯示TableView的情況是:

    • 用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]創(chuàng)建10次cell,并給cell指定同樣的重用標識(當然,可以為不同顯示類型的cell指定不同的標識)恕出。并且10個cell全部都加入到visiableCells數(shù)組,reusableTableCells為空。

    • 向下拖動tableView,當cell1完全移出屏幕,并且cell11(它也是alloc出來的,原因同上)完全顯示出來的時候违帆。cell11加入到visiableCells,cell1移出visiableCells,cell1加入到reusableTableCells浙巫。

    • 接著向下拖動tableView,因為reusableTableCells中已經(jīng)有值,所以,當需要顯示新的cell, cellForRowAtIndexPath再次被調(diào)用的時候,[tableView dequeueReusableCellWithIdentifier:CellIdentifier],返回cell1。 cell1加入到visiableCells,cell1 移出reusableTableCells;cell2移出 visiableCells,cell2加入到reusableTableCells刷后。之后再需要顯示的Cell就可 以正常重用了.

    • 注意:配置Cell的時候一定要注意的畴,對取出的重用的cell做重新賦值,不要遺留老數(shù)據(jù)尝胆。

在一個tableView中需要自定義多種樣式的cell(兩種或三種),通常你如何實現(xiàn),說說思路即可?

  • 同上丧裁!

UITableView的性能優(yōu)化? 滑動的時候有種卡的感覺是為什么?怎么解決含衔?

  • 在使用第三方應用時煎娇,卻經(jīng)常遇到性能上的問題,普遍表現(xiàn)在滾動時比較卡贪染,特別是cell中包含圖片的情況時缓呛。

  • 實際上針對性地優(yōu)化一下就可以解決tableView滑動的時候卡頓的問題:

    • 使用不透明視圖。不透明的視圖可以提高渲染的速度杭隙∮窗恚可以將cell及其子視圖的opaque屬性設為YES(默認值)。

    • 不要重復創(chuàng)建不必要的cell痰憎。UITableView只需要一屏幕的UITableViewCell對象即可票髓。因此在cell不可見時攀涵,可以將其緩存起來,而在需要時繼續(xù)使用它即可洽沟。注意:cell被重用時汁果,需要調(diào)用setNeedsDisplayInRect:或setNeedsDisplay方法重繪cell。

    • 減少動畫效果的使用,最好不要使用insertRowsAtIndexPaths:withRowAnimation:方法爷辱,而是直接調(diào)用reloadData方法般此。

    • 減少視圖的數(shù)目。Cell包含了textLabel棘利、detailTextLabel和imageView等view,而你還可以自定義一些視圖放在它的contentView里朽缴,創(chuàng)建它會消耗較多資源善玫,并且也影響渲染的性能。

    • cell包含圖片密强,且數(shù)目較多茅郎,使用自定義的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]; }
      不過這樣一來系冗,你會發(fā)現(xiàn)選中一行后,這個cell就變藍了薪鹦,其中的內(nèi)容就被擋住了掌敬。最簡單的方法就是將cell的selectionStyle屬性設為UITableViewCellSelectionStyleNone,這樣就不會被高亮了池磁。

    -不需要與用戶交互時奔害,使用CALayer,將內(nèi)容繪制到layer上地熄,然后對cell的contentView.layer調(diào)用addSublayer:方法华临。這個例子中,layer并不會顯著影響性能端考,但如果layer透明雅潭,或者有圓角、變形等效果跛梗,就會影響到繪制速度了寻馏。解決辦法可參見后面的預渲染圖像。

    • 不要做多余的繪制工作核偿。在實現(xiàn)drawRect:的時候诚欠,它的rect參數(shù)就是需要繪制的區(qū)域,這個區(qū)域之外的不需要進行繪制。

    • 預渲染圖像轰绵。你會發(fā)現(xiàn)即使做到了上述幾點粉寞,當新的圖像出現(xiàn)時,仍然會有短暫的停頓現(xiàn)象左腔。解決的辦法就是在圖形上下文中畫唧垦,導出成UIImage對象,然后再繪制到屏幕液样。(頭像圓角振亮,或者其他變形的時候,用圖形上下文能提高性能鞭莽。)異步繪制

    • 不要阻塞主線程坊秸。tableview在更新數(shù)據(jù)時,整個界面卡住不動澎怒,完全不響應用戶請求褒搔。常見的是網(wǎng)絡請求,等待時間長待數(shù)秒喷面。

    • 解決方案:使用多線程星瘾,讓子線程去執(zhí)行這些函數(shù)或方法。

    • 注意:當下載線程數(shù)超過2時惧辈,會顯著影響主線程的性能琳状。所以在不需要響應用戶請求時,下載線程數(shù)可以增加到5咬像,不建議再加了算撮,以加快下載速度生宛。如果用戶正在交互县昂,應把線程數(shù)量控制在2個以內(nèi)。

    • 提前計算并緩存好高度陷舅,因為heightforrowatindexpath調(diào)用非常頻繁

    • 選擇正確的數(shù)據(jù)結構:學會選擇對業(yè)務場景最合適的數(shù)組結構是寫出高效代碼的基礎倒彰。比如,數(shù)組: 有序的一組值莱睁。使用索引來查詢很快待讳,使用值查詢很慢,插入/刪除很慢仰剿。字典: 存儲鍵值對创淡,用鍵來查找比較快。集合: 無序的一組值南吮,用值來查找很快琳彩,插入/刪除很快。

    • gzip/zip壓縮:當從服務端下載相關附件時,可以通過gzip/zip壓縮后再下載露乏,使得內(nèi)存更小碧浊,下載速度也更快。

tableview的cell里如何嵌套collection view瘟仿?

思路同網(wǎng)易新聞類似,用自定義的繼承自UITableViewCell的類,在initWithFrame的構造方法中, 初始化自定義的繼承自UICollectionView的類

下拉和上拉的原理?

  • 以tableView的上拉刷新為例:

    • 為了進行無縫閱讀, 通過tableView的代理方法, willDisplayCell判斷是否是最后一行,

    • 如果是最后一行, 在顯示最后一行的同時, 判斷當前是否存在上拉刷新

    • 如果當前沒有上拉刷新, 就進行加載數(shù)據(jù), 啟動小菊花轉啊轉箱锐。

  • 以tableView的下拉刷新為例:

    • 判斷當前的上拉刷新視圖是否動畫

    • 如果沒有動畫, 就不是上拉刷新

    • 然后下拉刷新加載數(shù)據(jù)

    • 加載完畢數(shù)據(jù)關閉刷新

如何實現(xiàn)cell的動態(tài)的行高?

  • 如果希望每條數(shù)據(jù)顯示自身的行高, 必須設置兩個屬性, 1.預估行高, 2.自定義行高

  • 設置預估行高 tableView.estimatedRowHeight = 200

  • 設置定義行高 tableView.rowHeight = UITableViewAutomaticDimension

  • 如果要讓自定義行高有效, 必須讓容器視圖有一個自下而上的約束

談談webView

  • iOS開發(fā)中webview和native code的配合上的一些經(jīng)驗和技巧劳较。

  • webview與運維成本低驹止,更新幾乎不依賴App的版本;但在交互和性能上與跟native code有很大差距观蜗。

  • native code與之對應幢哨。

  • HTML5確實給web帶入了一個新時代。這個時代是什么嫂便,web app捞镰。也就是說,只有脫離native的這個前提毙替,在瀏覽器的環(huán)境下岸售,HTML5的意義才能顯現(xiàn),而我們討論iOS App的時候厂画,HTML5顯然沒什么意義凸丸。

  • 不管是用webview還是native code,兩個原則:

    • 用戶體驗不打折

    • 運維成本低

  • 為什么不提開發(fā)成本袱院。因為做web開發(fā)和iOS開發(fā)根本就是兩回事屎慢。當然,web開發(fā)發(fā)展了這么多年忽洛,對于某些功能實現(xiàn)是要比native app快腻惠。但多數(shù)情況,同一個功能欲虚,對于iOS開發(fā)者和web開發(fā)者集灌,用各自擅長的方式開發(fā)成本都最低,所以說某個功能開發(fā)成本低复哆,往往是一個偽命題欣喧。

  • 剛剛說了,webview的優(yōu)勢在于更新不依賴版本梯找,那么在一款App中唆阿,只有會頻繁更新的界面考慮webview才有意義。那么哪些界面會頻繁更新锈锤,這就要因App而異了驯鳖。

  • 首頁饰躲。首頁資源可謂必爭之地,內(nèi)容一天一換是正尘矢簦現(xiàn)象嘹裂,一天幾換也不稀奇。而如果僅僅是內(nèi)容的更換摔握,非要上個webview就顯得有些激進了寄狼。而事實上首頁的變化千奇百怪,逢年過節(jié)變個臉氨淌,特殊情況掛個公告泊愧,偶爾還要特批強推一把某個業(yè)務,等等盛正。此前删咱,我在設計App首頁的時候,把首頁配置設計的非常復雜豪筝。App端要處理n種情況痰滋,n各參數(shù),server端要記住n種規(guī)則续崖,直到一天敲街,我崩潰了,把首頁完全換成webview严望,才豁然開朗多艇。

  • 活動頁。做互聯(lián)網(wǎng)都知道像吻,活動峻黍,是一個最常見的運營手段。特點是拨匆,周期短姆涩,功能少,但基本不能復用涮雷。這些特點都標識了活動不適合做native阵面,要用webview實現(xiàn)。即使有人告訴你說洪鸭,我的活動是一個長期活動而且形式不變,也不要相信他仑扑。因為在第二期览爵,第三期,第四期他會分別加上一些非常詭異镇饮,卻有很合理的小變更蜓竹,而這些變更是你在那個版本根本無法實現(xiàn)的。

  • 試水的新功能。這種界面俱济,往往設計不成熟嘶是,需要在運行過程中不斷收集用戶反饋,更新升級蛛碌,甚至決定去留聂喇。所以,只有webview才能hold住如此不穩(wěn)定的功能蔚携。切記在一個功能還沒有確定之前希太,不要大張旗鼓單位開發(fā)native code,要知道酝蜒,你寫的這些代碼誊辉,三天后就要改一遍,而且要發(fā)布上線亡脑。

  • 富文本內(nèi)容堕澄。這個不用多說了吧,按照HTML的常用標簽做一個webtext可不是小工程霉咨。而且富文本的變化太多了奈偏,一點無法匹配,都會導致整個界面巨丑躯护。

  • OK惊来,上邊說了我認為最該使用webview的4個界面,分別帶有不同的特點棺滞,但webview的交互是個短板裁蚁,因此webview在一個App中,只能作為界面继准,不允許在界面中出現(xiàn)動作枉证。而一個webview的界面如何跟native code結合起來呢,我的答案是移必,超鏈接室谚。在webview上點擊超鏈接,會調(diào)用webview delegate的shouldload方法崔泵,自這里攔截請求秒赤,進行處理。由于webview的鏈接都是URL憎瘸,因此我建議入篮,把整個App的界面都用URL管理起來。

  • 長相問題幌甘,webview很難長成native的view潮售。方案:長不成也要裝成痊项。在一些情況下,禁用webview滾動酥诽,使用滾動框架(iScroll不錯)去實現(xiàn)鞍泉。webview上下留出200pixel的空白背景,y從-200開始肮帐。否則大家知道咖驮,webview上下會有陰影的背景,不藏起來會很丑泪姨。等等游沿,還有很多其他的方法去偽裝webview,是要視情景而用肮砾。

  • cell中嵌套webview诀黍,在oc中調(diào)用js獲取web的高度, CGFloat height = [[self.webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];在通過webViewDidFinishLoad里面更新行高仗处。

awakeFromNib與viewdidload區(qū)別

  • awakefromnib:當.nib文件被加載的時候眯勾,會發(fā)送一個awakefromnib消息到.nib文件中的每個對象,每個對象都可以定義自己的awakefromnib函數(shù)來響應這個消息婆誓,執(zhí)行必要操作吃环。也就是說 通過.nib文件創(chuàng)建view對象執(zhí)行awakefromnib
  • viewdidload:當view對象被加載到內(nèi)存就會執(zhí)行viewdidload,不管是通過nib還是代碼形式洋幻,創(chuàng)建對象就會執(zhí)行viewdidload

layoutSubview何時調(diào)用?

  • 初始化init方法時不會觸發(fā)
  • 滾動uiscrollview觸發(fā)
  • 旋轉屏幕觸發(fā)
  • 改變view的值觸發(fā)郁轻,前提是frame改變了
  • 改變uiview的大小觸發(fā)

viewcontroller的didreceivememorywaring在什么時候調(diào)用 默認操作是什么

  • 應用程序收到來自系統(tǒng)的內(nèi)存警告時,調(diào)用didreceivememorywaring方法
  • 默認做法:控制器上的view不再窗口上顯示時文留,調(diào)用viewWillUnload好唯,直接銷毀view,并調(diào)用viewdidunload

UIWindow和UIView和 CALayer 的聯(lián)系和區(qū)別?

  • UIView是視圖的基類燥翅,UIViewController是視圖控制器的基類骑篙,UIResponder是表示一個可以在屏幕上響應觸摸事件的對象;
  • UIwindow是UIView的子類森书,UIWindow的主要作用:一是提供一個區(qū)域來顯示UIView靶端,二是將事件(event)的分發(fā)給UIView,一個應用基本上只有一個UIWindow.
    圖層不會直接渲染到屏幕上凛膏,UIView是iOS系統(tǒng)中界面元素的基礎杨名,所有的界面元素都是繼承自它。它本身完全是由CoreAnimation來實現(xiàn)的译柏。它真正的繪圖部分镣煮,是由一個CALayer類來管理。UIView本身更像是一個CALayer的管理器鄙麦。一個UIView上可以有n個CALayer典唇,每個layer顯示一種東西,增強UIView的展現(xiàn)能力胯府。
  • 都可以顯示屏幕效果
  • 如果需要用戶交互就要用UIVIew,其可接收觸摸事件(繼承UIResponder),而CALayer不能接收觸摸事件
  • 如果沒有用戶交互可選用CALayer,因為其所在庫較小,占用的資源較少

UIScrollView

  • contentsize 內(nèi)容視圖的尺寸
  • contentoffset 內(nèi)容視圖當前位置相對滾動視圖frame的偏移量
  • contentinset 內(nèi)容視圖相對滾動視圖frame的展示原點

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

  • 使用UICollectionView
  • 使用自定義的FlowLayout
  • 需要在layoutAttributesForElementsInRect中設置自定義的布局(item的frame)
  • 在 prepareLayout中計算布局
  • 遍歷數(shù)據(jù)內(nèi)容,根據(jù)索引取出對應的attributes(使用layoutAttributesForCellWithIndexPath),根據(jù)九宮格算法設置布局
  • 細節(jié)1: 實時布局,重寫shouldInvalidateLayoutForBoundsChange(bounds改變重新布局,scrollview的contentoffset>bounds)
  • 細節(jié)2: 計算設置itemsize(保證內(nèi)容顯示完整,uicollectionview的content size是根據(jù)itemize計算的),根據(jù)列最大高度/對應列數(shù)量求出,最大高度累加得到
  • 細節(jié)3: 追加item到最短列,避免底部參差不齊.

UIImage有哪幾種加載方式

  • 二進制 imageWithData
  • Bundle imageWithName
  • 本地路徑 imageWithContentOfFile

描述九宮格算法

  • NSInteger col = x;//定義列數(shù)
  • NSInteger index = self.shopsView.subviews.count;//獲取下標
  • CGFloat margin = (self.shopsView.frame.size.width - col*viewW) / (col - 1);//定義間隔
  • CGFloat viewX = (index % col ) * (viewW + margin);
  • CGFloat viewY = (index / col ) * (viewH + 10);

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

  • ScrollView只需要設置三個ImageView即可介衔,并且默認顯示中間的ImageView
  • 根據(jù)ScrollView的移動情況,迅速變化三個ImageView中圖片數(shù)據(jù)
  • ImageView更新完畢后骂因,偷偷把ScrollView拉回到中間的ImageView位置炎咖,這樣視覺效果上就實現(xiàn)了無限循環(huán)的效果

應用的生命周期

  • -(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions 告訴代理進程啟動但還沒進入狀態(tài)保存
  • -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 告訴代理啟動基本完成程序準備開始運行
  • -(void)applicationWillResignActive:(UIApplication *)application 當應用程序將要入非活動狀態(tài)執(zhí)行,在此期間寒波,應用程序不接收消息或事件乘盼,比如來電話了
  • -(void)applicationDidBecomeActive:(UIApplication *)application 當應用程序入活動狀態(tài)執(zhí)行,這個剛好跟上面那個方法相反
  • -(void)applicationDidEnterBackground:(UIApplication *)application 當程序被推送到后臺的時候調(diào)用俄烁。所以要設置后臺繼續(xù)運行绸栅,則在這個函數(shù)里面設置即可
  • -(void)applicationWillEnterForeground:(UIApplication *)application 當程序從后臺將要重新回到前臺時候調(diào)用,這個剛好跟上面的那個方法相反页屠。
  • -(void)applicationWillTerminate:(UIApplication *)application 當程序將要退出是被調(diào)用粹胯,通常是用來保存數(shù)據(jù)和一些退出前的清理工作。

load initialize方法的區(qū)別

  • +(void)load;
    • 當類對象被引入項目時, runtime 會向每一個類對象發(fā)送 load 消息
    • load 方法會在每一個類甚至分類被引入時僅調(diào)用一次,調(diào)用的順序:父類優(yōu)先于子類, 子類優(yōu)先于分類
    • load 方法不會被類自動繼承
  • +(void)initialize;
    • 也是在第一次使用這個類的時候會調(diào)用這個方法

UIScrollView 大概是如何實現(xiàn)的辰企,它是如何捕捉风纠、響應手勢的?

  • 我對UIScrollView的理解是frame就是他的contentSize,bounds就是他的可視范圍,通過改變bounds從而達到讓用戶誤以為在滾動,以下是一個簡單的UIScrollView實現(xiàn)

  • 第二個問題個人理解是解決手勢沖突,對自己添加的手勢進行捕獲和響應

// 讓UIScrollView遵守UIGestureRecognizerDelegate協(xié)議,實現(xiàn)這個方法,在這里方法里對添加的手勢進行處理就可以解決沖突

  • (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

+[UIView animateWithDuration:animations:completion:] 內(nèi)部大概是如何實現(xiàn)的牢贸?

animateWithDuration:這就等于創(chuàng)建一個定時器
animations:這是創(chuàng)建定時器需要實現(xiàn)的SEL
completion:是定時器結束以后的一個回調(diào)block

什么時候會發(fā)生「隱式動畫」竹观?

  • 當改變CALayer的一個可做動畫的屬性,它并不能立刻在屏幕上體現(xiàn)出來.相反潜索,它是從先前的值平滑過渡到新的值臭增。這一切都是默認的行為,你不需要做額外的操作,這就是隱式動畫

如何把一張大圖縮小為1/4大小的縮略圖帮辟?

imgData = UIImageJPEGRepresentation(image, 0.6f)

當TableView的Cell改變時速址,如何讓這些改變以動畫的形式呈現(xiàn)?

[tableView deselectRowAtIndexPath:indexPath animated:TRUE];
// 重點是這2句代碼實現(xiàn)的功能
[tableView beginUpdates];
[tableView endUpdates];

為什么當 Core Animation 完成時由驹,layer 又會恢復到原先的狀態(tài)芍锚?

  • 因為這些產(chǎn)生的動畫只是假象,并沒有對layer進行改變.那么為什么會這樣呢,這里要講一下圖層樹里的呈現(xiàn)樹.呈現(xiàn)樹實際上是模型圖層的復制,但是它的屬性值表示了當前外觀效果,動畫的過程實際上只是修改了呈現(xiàn)樹,并沒有對圖層的屬性進行改變,所以在動畫結束以后圖層會恢復到原先狀態(tài)

設計一個進度條。

  1. 自定義一個UIView的子類

     //提供一個成員屬性蔓榄,接收下載進度值
     @property (nonatomic, assign) CGFloat progress;
    
  2. 重寫成員屬性progress的setter

     //每次改變成員屬性progress的值并炮,就會調(diào)用它的setter
     -(void)setProgress:(CGFloat)progress
     {
     _progress = progress;
     //當下載進度改變時,手動調(diào)用重繪方法
     [self setNeedsDisplay];
     }
    
  3. 重寫

     -(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];
     }
    

如何播放 GIF 圖片甥郑,有什么優(yōu)化方案么逃魄?

  • UIImageView用來顯示圖片, 使用UIImageView中的動畫數(shù)組來實現(xiàn)圖片的動畫效果

  • 用UIWebView來顯示動態(tài)圖片

  • 第三方顯示框架

  • 通過UIImageView顯示動畫效果澜搅,實際上是把動態(tài)的圖拆成了一組靜態(tài)的圖伍俘,放到數(shù)組中邪锌,播放的時候依次從數(shù)組中取出。如果播放的圖片比較少占得內(nèi)存比較小或者比較常用(比如工具條上一直顯示的動態(tài)小圖標)癌瘾,可以選擇用imageNamed:方式獲取圖片觅丰,但是通過這種方式加到內(nèi)存中,使用結束妨退,不會自己釋放妇萄,多次播放動畫會造成內(nèi)存溢出問題。因此咬荷,對于大圖或經(jīng)常更換的圖冠句,在取圖片的時候可以選擇imageWithContentsOfFile:方式獲取圖片,優(yōu)化內(nèi)存幸乒。

  • 使用UIWebView顯示圖片需要注意顯示圖片的尺寸與UIWebView尺寸的設置懦底,如果只是為了顯示動態(tài)圖片,可以禁止UIWebView滾動逝变。在顯示動態(tài)圖片的時候基茵,即使是動圖的背景處為透明,默認顯示出來是白色背景壳影,這個時候需要手動設置UIWebView的透明才能達到顯示動圖背景透明的效果拱层。

有哪幾種方式可以對圖片進行縮放,使用 CoreGraphics 縮放時有什么注意事項宴咧?

  • UIImageView整體拉伸
  • UIImage局部拉伸
  • UIImage修改大小
  • images.xcassets:多虧了Xcode中Asset Catalog的slice和dice根灯,我們不需要代碼也能拉伸圖片。首先在Xcode中選中圖片掺栅,然后點擊右下角的Show Slicing:
  • 圖形上下文等比例縮放

XIB與Storyboards的優(yōu)缺點?

- XIB:在編譯前就提供了可視化界面烙肺,可以直接拖控件,也可以直接給控件添加約束氧卧,更直觀一些桃笙,而且類文件中就少了創(chuàng)建控件的代碼,確實簡化不少沙绝,通常每個XIB對應一個類搏明。

- Storyboard:在編譯前提供了可視化界面,可拖控件闪檬,可加約束星著,在開發(fā)時比較直觀,而且一個storyboard可以有很多的界面粗悯,每個界面對應一個類文件虚循,通過storybard,可以直觀地看出整個App的結構。

- XIB:需求變動時横缔,需要修改XIB很大铺遂,有時候甚至需要重新添加約束,導致開發(fā)周期變長剪廉。XIB載入相比純代碼自然要慢一些娃循。對于比較復雜邏輯控制不同狀態(tài)下顯示不同內(nèi)容時炕檩,使用XIB是比較困難的斗蒋。當多人團隊或者多團隊開發(fā)時,如果XIB文件被發(fā)動笛质,極易導致沖突泉沾,而且解決沖突相對要困難很多。

- Storyboard:需求變動時妇押,需要修改storyboard上對應的界面的約束跷究,與XIB一樣可能要重新添加約束,或者添加約束會造成大量的沖突敲霍,尤其是多團隊開發(fā)俊马。對于復雜邏輯控制不同顯示內(nèi)容時,比較困難肩杈。當多人團隊或者多團隊開發(fā)時柴我,大家會同時修改一個storyboard,導致大量沖突扩然,解決起來相當困難艘儒。

控制器View的加載過程?

當程序訪問了控制器的View屬性時會先判斷控制器的View是否存在夫偶,如果存在就直接返回已經(jīng)存在的View界睁;
如果不存在,就會先調(diào)用loadView這個方法兵拢;如果控制器的loadView方法實現(xiàn)了翻斟,就會按照loadView方法加載自定義的View;
如果控制器的loadView方法沒有實現(xiàn)就會判斷storyboard是否存在说铃;
如果storyboard存在就會按照storyboard加載控制器的View访惜;如果storyboard不存在,就會創(chuàng)建一個空視圖返回截汪。

應用程序的啟動流程疾牲?

1.執(zhí)行Main
2.執(zhí)行UIApplicationMain函數(shù).
3.創(chuàng)建UIApplication對象,并設置UIApplicationMain對象的代理.
  UIApplication的第三個參數(shù)就是UIApplication的名稱,如果指定為nil,它會默認為UIApplication.
  UIApplication的第四個參數(shù)為UIApplication的代理.
4.開啟一個主運行循環(huán).保證應用程序不退出.
5.加載info.plist.加載配置文件.判斷一下info.plist文件當中有沒有Main storyboard file base name里面有沒有指定storyboard文件,如果有就去加載info.plist文件,如果沒有,那么應用程序加載完畢.

事件傳遞與響應的完整過程?

在產(chǎn)生一個事件時,系統(tǒng)會將該事件加入到一個由UIApplication管理的事件隊列中,
UIApplication會從事件隊列中取出最前面的事件,將它傳遞給先發(fā)送事件給應用程序的主窗口.
主窗口會調(diào)用hitTest方法尋找最適合的視圖控件,找到后就會調(diào)用視圖控件的touches方法來做具體的事情.
當調(diào)用touches方法,它的默認做法, 就會將事件順著響應者鏈條往上傳遞,
傳遞給上一個響應者,接著就會調(diào)用上一個響應者的touches方法

下列回調(diào)機制的理解不正確的是

A target-action:當兩個對象之間有?較緊密的關系時衙解,如視圖控制器與其下的某個視圖阳柔。       
B delegate:當某個對象收到多個事件,并要求同一個對象來處理所有事件時蚓峦。委托機制必須依賴于某個協(xié)議定義的?法來發(fā)送消息舌剂。       
C NSNotification:當需要多個對象或兩個無關對象處理同一個事件時济锄。       
D Block:適?于回調(diào)只發(fā)?生一次的簡單任務。
參考答案:B

給UIImageView添加圓角

  • 最直接的方法就是使用如下屬性設置:
imgView.layer.cornerRadius = 10;
// 這一行代碼是很消耗性能的
imgView.clipsToBounds = YES;
  • 好處是使用簡單霍转,操作方便荐绝。壞處是離屏渲染(off-screen-rendering)需要消耗性能。對于圖片比較多的視圖上避消,不建議使用這種方法來設置圓角低滩。通常來說,計算機系統(tǒng)中CPU岩喷、GPU恕沫、顯示器是協(xié)同工作的。CPU計算好顯示內(nèi)容提交到GPU纱意,GPU渲染完成后將渲染結果放入幀緩沖區(qū)婶溯。
  • 簡單來說,離屏渲染偷霉,導致本該GPU干的活迄委,結果交給了CPU來干,而CPU又不擅長GPU干的活类少,于是拖慢了UI層的FPS(數(shù)據(jù)幀率)叙身,并且離屏需要創(chuàng)建新的緩沖區(qū)和上下文切換,因此消耗較大的性能瞒滴。
  • 給UIImage添加生成圓角圖片的擴展API:
- (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;
}

然后調(diào)用時就直接傳一個圓角來處理:

imgView.image = [[UIImage imageNamed:@"test"] hyb_imageWithCornerRadius:4];

這么做就是on-screen-rendering了曲梗,通過模擬器->debug->Color Off-screen-rendering看到?jīng)]有離屏渲染了!(黃色的小圓角沒有顯示了,說明這個不是離屏渲染了)

  • 在畫之前先通過UIBezierPath添加裁剪妓忍,但是這種不實用
- (void)drawRect:(CGRect)rect {
  CGRect bounds = self.bounds;
  [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:8.0] addClip];
 
  [self.image drawInRect:bounds];
}
  • 通過mask遮罩實現(xiàn)

一個view已經(jīng)初始化完畢虏两,view上面添加了n個button(可能使用循環(huán)創(chuàng)建),除用view的tag之外世剖,還可以采用什么辦法來找到自己想要的button來修改Button的值

這個問題有很多種方式定罢,而且不同的使用場景也不一樣的。比如說:
?   第一種:如果是點擊某個按鈕后旁瘫,才會刷新它的值祖凫,其它不用修改,那么不用引用任何按鈕酬凳,直接在回調(diào)時惠况,就已經(jīng)將接收響應的按鈕給傳過來了,直接通過它修改即可宁仔。
?   第二種:點擊某個按鈕后稠屠,所有與之同類型的按鈕都要修改值,那么可以通過在創(chuàng)建按鈕時將按鈕存入到數(shù)組中,在需要的時候遍歷查找权埠。

使用drawRect有什么影響榨了?

  • drawRect方法依賴Core Graphics框架來進行自定義的繪制,但這種方法主要的缺點就是它處理touch事件的方式:每次按鈕被點擊后攘蔽,都會用setNeddsDisplay進行強制重繪龙屉;而且不止一次,每次單點事件觸發(fā)兩次執(zhí)行满俗。這樣的話從性能的角度來說转捕,對CPU和內(nèi)存來說都是欠佳的。特別是如果在我們的界面上有多個這樣的UIButton實例漫雷。

viewWillLayoutSubView你總是知道的瓜富。

controller layout觸發(fā)的時候,開發(fā)者有機會去重新layout自己的各個subview降盹。
橫豎屏切換的時候,系統(tǒng)會響應一些函數(shù)谤辜,其中 viewWillLayoutSubviews 和 viewDidLayoutSubviews蓄坏。
- (void)viewWillLayoutSubviews  {       
[self _shouldRotateToOrientation:(UIDeviceOrientation)[UIApplication sharedApplication].statusBarOrientation];  
} 
 -(void)_shouldRotateToOrientation:(UIDeviceOrientation)orientation {         

 if (orientation == UIDeviceOrientationPortrait ||orientation ==                 UIDeviceOrientationPortraitUpsideDown)

  {           // 豎屏 } 

 else {          // 橫屏     } }
通過上述一個函數(shù)就知道橫豎屏切換的接口了。 
注意:viewWillLayoutSubviews只能用在ViewController里面丑念,在view里面沒有響應涡戳。

一個tableView是否可以關聯(lián)兩個不同的數(shù)據(jù)源?

  • 當然是可以關聯(lián)多個不同的數(shù)據(jù)源脯倚,但是不能同時使用多個數(shù)據(jù)源而已渔彰。比如,一個列表有兩個篩選功能推正,一個是篩選城市恍涂,一個是篩選時間,那么這兩個就是兩個數(shù)據(jù)源了植榕。當篩選城市時再沧,就會使用城市數(shù)據(jù)源;當篩選時間時尊残,就會使用時間數(shù)據(jù)源炒瘸。

如何自動計算cell的高度?

  • 實現(xiàn)原理:通過數(shù)據(jù)模型的id作為key寝衫,以確保唯一顷扩,如何才能保證復用cell時不會出現(xiàn)混亂。在配置完數(shù)據(jù)后慰毅,通過更新約束隘截,得到最后一個控件的frame,就只可以判斷cell實際需要的高度,并且緩存下來技俐,下次再獲取時乘陪,判斷是否存在,若存在則直接返回雕擂。因此啡邑,只會計算一遍

UITableView是如何計算內(nèi)容高度的?為什么初始化時配置數(shù)據(jù)時井赌,獲取行高的代理方法會調(diào)用數(shù)據(jù)條數(shù)次谤逼?

  • UITableView是繼承于UIScrollView的,因此也有contentSize仇穗。要得到tableview的contentsize流部,就需要得到所有cell的高度,從而計算出總高度纹坐,才能得到contentsize枝冀。因此,在reloadData時耘子,就會調(diào)用該代理方法數(shù)據(jù)條數(shù)次果漾。

一個tableView是否可以關聯(lián)兩個不同的數(shù)據(jù)源?你會怎么處理?

答:首先我們從代碼來看,數(shù)據(jù)源如何關聯(lián)上的谷誓,其實是在數(shù)據(jù)源關聯(lián)的代理方法里實現(xiàn)的绒障。
因此我們并不關心如何去關聯(lián)他,他怎么關聯(lián)上捍歪,方法只是讓我返回根據(jù)自己的需要去設置如相關的數(shù)據(jù)源户辱。
因此,我覺得可以設置多個數(shù)據(jù)源啊糙臼,但是有個問題是庐镐,你這是想干嘛呢?想讓列表如何顯示,不同的數(shù)據(jù)源分區(qū)塊顯示?

給出委托方法的實例弓摘,并且說出UITableVIew的Data Source方法

CocoaTouch框架中用到了大量委托焚鹊,其中UITableViewDelegate就是委托機制的典型應用,是一個典型的使用委托來實現(xiàn)適配器模式韧献,其中UITableViewDelegate協(xié)議是目標末患,tableview是適配器,實現(xiàn)UITableViewDelegate協(xié)議锤窑,并將自身設置為talbeview的delegate的對象璧针,是被適配器,一般情況下該對象是UITableViewController渊啰。
UITableVIew的Data Source方法有- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

cocoa touch框架

答:iPhone OS 應用程序的基礎 Cocoa Touch 框架重用了許多 Mac 系統(tǒng)的成熟模式探橱,但是它更多地專注于觸摸的接口和優(yōu)化申屹。

UIKit 為您提供了在 iPhone OS 上實現(xiàn)圖形,事件驅動程序的基本工具隧膏,其建立在和 Mac OS X 中一樣的 Foundation 框架上哗讥,包括文件處理,網(wǎng)絡胞枕,字符串操作等杆煞。

Cocoa Touch 具有和 iPhone 用戶接口一致的特殊設計。有了 UIKit腐泻,您可以使用 iPhone OS 上的獨特的圖形接口控件决乎,按鈕,以及全屏視圖的功能派桩,您還可以使用加速儀和多點觸摸手勢來控制您的應用构诚。

各色俱全的框架 除了UIKit 外,Cocoa Touch 包含了創(chuàng)建世界一流 iPhone 應用程序需要的所有框架铆惑,從三維圖形范嘱,到專業(yè)音效,甚至提供設備訪問 API 以控制攝像頭鸭津,或通過 GPS 獲知當前位置彤侍。

Cocoa Touch 既包含只需要幾行代碼就可以完成全部任務的強大的 Objective-C 框架,也在需要時提供基礎的 C 語言 API 來直接訪問系統(tǒng)逆趋。這些框架包括:

Core Animation:通過 Core Animation,您就可以通過一個基于組合獨立圖層的簡單的編程模型來創(chuàng)建豐富的用戶體驗晒奕。

Core Audio:Core Audio 是播放闻书,處理和錄制音頻的專業(yè)技術,能夠輕松為您的應用程序添加強大的音頻功能脑慧。

Core Data:提供了一個面向對象的數(shù)據(jù)管理解決方案魄眉,它易于使用和理解,甚至可處理任何應用或大或小的數(shù)據(jù)模型闷袒。

功能列表:框架分類

下面是 Cocoa Touch 中一小部分可用的框架:

音頻和視頻:Core Audio 坑律,OpenAL ,Media Library 囊骤,AV Foundation

數(shù)據(jù)管理 :Core Data 晃择,SQLite

圖形和動畫 :Core Animation ,OpenGL ES 也物,Quartz 2D

網(wǎng)絡:Bonjour 宫屠,WebKit ,BSD Sockets

用戶應用:Address Book 滑蚯,Core Location 浪蹂,Map Kit 抵栈,Store Kit

xib文件的構成分為哪3個圖標?都具有什么功能坤次。

File’s Owner 是所有 nib 文件中的每個圖標古劲,它表示從磁盤加載 nib 文件的對象;

First Responder 就是用戶當前正在與之交互的對象缰猴;

View 顯示用戶界面产艾;完成用戶交互;是 UIView 類或其子類洛波。

簡述應用程序按Home鍵進入后臺時的生命周期,和從后臺回到前臺時的生命周期? 應用程序:

-[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:]

是否使用Core Text或者Core Image等?如果使用過蹬挤,請談談你使用Core Text或者Core Image的體驗译蒂。

CoreText
?   隨意修改文本的樣式
?   圖文混排(純C語言)
?   國外:Niumb
Core Image(濾鏡處理)
* 能調(diào)節(jié)圖片的各種屬性(對比度, 色溫, 色差等)

分析一下使用手機獲取驗證碼注冊賬號的實現(xiàn)邏輯(給了一個示例圖),發(fā)送到手機的驗證碼超過60秒鐘后重新發(fā)送

  • 定義一個label屬性翼闽,賦值為60秒藐石,再定義一個count 設置一個timer 每次減少一秒 把count-- 再把count的值拼接到label上 當count == 0 的時候 再顯示重新發(fā)送

你做iphone開發(fā)時候,有哪些傳值方式,view和view之間是如何傳值的?

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;

文章如有問題扫茅,請留言,我將及時更正育瓜。

滿地打滾賣萌求贊葫隙,如果本文幫助到你,輕點下方的紅心躏仇,給作者君增加更新的動力恋脚。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市焰手,隨后出現(xiàn)的幾起案子糟描,更是在濱河造成了極大的恐慌,老刑警劉巖书妻,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件船响,死亡現(xiàn)場離奇詭異,居然都是意外死亡躲履,警方通過查閱死者的電腦和手機见间,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來崇呵,“玉大人缤剧,你說我怎么就攤上這事∮蚩叮” “怎么了荒辕?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵汗销,是天一觀的道長。 經(jīng)常有香客問我抵窒,道長弛针,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任李皇,我火速辦了婚禮削茁,結果婚禮上,老公的妹妹穿的比我還像新娘掉房。我一直安慰自己茧跋,他們只是感情好,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布卓囚。 她就那樣靜靜地躺著瘾杭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪哪亿。 梳的紋絲不亂的頭發(fā)上粥烁,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音蝇棉,去河邊找鬼讨阻。 笑死,一個胖子當著我的面吹牛篡殷,可吹牛的內(nèi)容都是我干的钝吮。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼板辽,長吁一口氣:“原來是場噩夢啊……” “哼搀绣!你這毒婦竟也來了?” 一聲冷哼從身側響起戳气,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎巧鸭,沒想到半個月后瓶您,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡纲仍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年呀袱,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片郑叠。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡夜赵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乡革,到底是詐尸還是另有隱情寇僧,我是刑警寧澤摊腋,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站嘁傀,受9級特大地震影響兴蒸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜细办,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一橙凳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧笑撞,春花似錦岛啸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至炉爆,卻和暖如春堕虹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背芬首。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工赴捞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人郁稍。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓赦政,卻偏偏與公主長得像,于是被迫代替她去往敵國和親耀怜。 傳聞我的和親對象是個殘疾皇子恢着,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

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

  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件财破、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,022評論 4 62
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結起來就是把...
    Dove_iOS閱讀 27,124評論 29 470
  • 曾經(jīng)在某一瞬間掰派,我們都以為自己長大了。但是有一天左痢,我們終于發(fā)現(xiàn)靡羡,長大的含義除了欲望,還有勇氣俊性、責任略步、堅強以及某種必...
    18183b55ea01閱讀 293評論 0 1
  • 第一天發(fā)現(xiàn)這個軟件,好久沒寫東西了定页,希望堅持下來
    昀義閱讀 134評論 0 0
  • 你/ 斬了我的首/ 割去我的臀/ 扒掉我的皮/ 剔下我的骨/ 攪碎我的肉/ 榨干我的血/ 然后/ 還嫌我粘手趟薄。
    裸山閱讀 579評論 2 5