UITableViewCell是UIView的子類。創(chuàng)建UIView子類時(shí)况鸣,定制界面的方法是覆蓋drawRect:,但是在創(chuàng)建UITableViewCell子類時(shí),定制界面的方法是向UITableViewCell加入子視圖树叽。不過(guò),并不是直接將子視圖加入U(xiǎn)ITableViewCell谦絮,而是加入U(xiǎn)ITableViewCell的另一個(gè)子視圖:contentView题诵。
contentView起容器的作用,用于存放其他子視圖层皱。這些子視圖構(gòu)成UITableViewCell的布局(見圖192)性锭。要改變UITableViewCell子類的外觀,需要修改contentView所包含的子視圖叫胖。
必須將子視圖加入contentView而不是UITableViewCell對(duì)象自身的原因是草冈,UITableViewCell對(duì)象會(huì)根據(jù)外部條件改變contentView的大小。例如,當(dāng)UITableView對(duì)象進(jìn)入編輯模式時(shí)怎棱,UITableViewCell對(duì)象會(huì)改變contentView的大小哩俭,為編輯控件(例如刪除控件和移位控件)留出位置(見圖193)。如果直接將子視圖加入U(xiǎn)ITableViewCell對(duì)象拳恋,編輯控件就會(huì)遮住這些子視圖凡资。進(jìn)入編輯模式時(shí),UITableViewCell對(duì)象不會(huì)改變大忻恕(UITableViewCell對(duì)象的寬度必須和UITableView對(duì)象的寬度相等)讳苦,但是其包含的contentView會(huì)改變大小。
讀者可能已經(jīng)注意到視圖層次結(jié)構(gòu)中的UIScrollView對(duì)象吩谦,當(dāng)UITableView對(duì)象進(jìn)入編輯模式時(shí)鸳谜,UITableViewCell對(duì)象會(huì)將contentView移動(dòng)到左側(cè),這個(gè)過(guò)程需要借助UIScrollView對(duì)象式廷。同樣咐扭,在UITableViewCell對(duì)象中從右向左滑動(dòng)顯示刪除控件時(shí),也需要借助UIScrollView對(duì)象滑废。實(shí)際上蝗肪,contentView是UIScrollView對(duì)象的一個(gè)子視圖。
創(chuàng)建UITableViewCell子類界面的最簡(jiǎn)單方法就是使用XIB文件蠕趁。
UITableViewCell的XIB文件不會(huì)使用File'sOwner薛闪,所以不用為其設(shè)置類名,也不用為其創(chuàng)建任何關(guān)聯(lián)俺陋。與UIViewController的XIB文件不同豁延,UITableViewCell的XIB文件在解固時(shí),不需要使用某個(gè)對(duì)象代替File'sOwner腊状,也不需要將其中的固化對(duì)象關(guān)聯(lián)到File'sOwner诱咏。為了理解兩種XIB文件的區(qū)別,首先需要知道UITableView加載UITableViewCell的過(guò)程缴挖。
注冊(cè)NIB文件的原理非常簡(jiǎn)單袋狞,僅僅是將UINib對(duì)象以“BNRItemCell”作為鍵保存到NSDictionary中。UINib對(duì)象包含所有保存在其XIB文件中的數(shù)據(jù)映屋,當(dāng)UITableView對(duì)象需要使用UITableViewCell對(duì)象時(shí)苟鸯,就會(huì)使用相應(yīng)的UINib對(duì)象創(chuàng)建新的UITableViewCell對(duì)象。
在UITableView對(duì)象中注冊(cè)了包含xib的UINib對(duì)象之后棚点,UITableView對(duì)象就可以通過(guò)“BNRItemCell”鍵找到并加載BNRItemCell對(duì)象早处。
縮略圖
詳細(xì)看19.2
iOS SDK提供了多種創(chuàng)建縮略圖的途徑,其中之一是根據(jù)原圖在屏外上下文(offscreencontext)中畫出按比率縮小后的版本乙濒,然后從上下文取出新創(chuàng)建的圖片陕赃。下面通過(guò)這種途徑為BNRItem對(duì)象的圖片創(chuàng)建縮略圖卵蛉。
由UITableViewCell對(duì)象轉(zhuǎn)發(fā)動(dòng)作消息
請(qǐng)注意,Block被聲明為copy么库。系統(tǒng)對(duì)Block對(duì)象和其他對(duì)象的內(nèi)存管理方式不同傻丝,Block對(duì)象是在棧中創(chuàng)建的,而其他對(duì)象是在堆中創(chuàng)建的诉儒。這意味著葡缰,即使應(yīng)用針對(duì)新創(chuàng)建的Block對(duì)象保留了強(qiáng)引用類型的指針,一旦創(chuàng)建該對(duì)象的方法返回忱反,那么與方法內(nèi)部的其他局部變量相同泛释,新創(chuàng)建的Block對(duì)象也會(huì)被立即釋放。為了在聲明Block對(duì)象的方法返回后仍然保留該對(duì)象温算,必須向其發(fā)送copy消息怜校。拷貝某個(gè)Block對(duì)象時(shí)注竿,應(yīng)用會(huì)在堆中創(chuàng)建該對(duì)象的備份茄茁。這樣,即使應(yīng)用釋放了當(dāng)前方法的棧巩割,堆中的Block對(duì)象也不會(huì)被釋放裙顽。
image.png
捕獲變量
Block對(duì)象可以使用其封閉作用域(enclosingscope)內(nèi)的所有變量。對(duì)聲明了某個(gè)Block對(duì)象的方法宣谈,該方法的作用域就是這個(gè)Block對(duì)象的封閉作用域愈犹。因此,這個(gè)Block對(duì)象可以訪問(wèn)該方法的所有局部變量闻丑、傳入該方法的實(shí)參以及所屬對(duì)象的實(shí)例變量漩怎。如果捕獲變量是ObjectiveC對(duì)象俊啼,那么Block對(duì)象對(duì)捕獲變量具有強(qiáng)引用杏愤。如果捕獲變量也對(duì)Block對(duì)象具有強(qiáng)引用,就會(huì)導(dǎo)致強(qiáng)引用循環(huán)。
解決問(wèn)題的方法是:將actionBlock對(duì)cell的引用改為弱引用酸钦。
image.png
在Block對(duì)象執(zhí)行過(guò)程中,必須保證Block對(duì)象始終可以訪問(wèn)cell咱枉。因此卑硫,以上代碼在actionBlock內(nèi)部創(chuàng)建了strongCell,以保持對(duì)cell的強(qiáng)引用蚕断。這與Block對(duì)象對(duì)捕獲變量的強(qiáng)引用不同欢伏,strongCell只是在Block對(duì)象執(zhí)行過(guò)程中對(duì)cell保持強(qiáng)引用。
UICollectionView
UICollectionView與UITableView非常相似:
?UICollectionView是UIScrollView的子類亿乳。
?與UITableViewCell類似硝拧,UICollectionView對(duì)象顯示一組UICollectionViewCell或其子類径筏。
?UICollectionView具有數(shù)據(jù)源,負(fù)責(zé)提供UICollectionViewCell障陶∽烫瘢 ?UICollectionView具有委托,可以在委托方法中處理相關(guān)回調(diào)事件抱究,例如選擇了某一個(gè)UICollectionViewCell恢氯。
?UICollectionViewController與UITableViewController類似,UICollectionViewController也是UIViewController的子類鼓寺,其view是UICollectionView勋拟。
UICollectionView與UITableView的區(qū)別是,UITableView只能顯示一列UITableViewCell妈候,在大屏幕設(shè)備(如iPad)中有很大的局限性敢靡。UICollectionView則可以將UICollectionViewCell按任意方式布局,其中最常見的是網(wǎng)格布局
UICollectionView是如何布局UICollectionViewCell的苦银?UICollectionView含有一個(gè)布局對(duì)象醋安,負(fù)責(zé)控制每一個(gè)UICollectionViewCell的屬性,包括位置和大小墓毒。UICollectionView的布局對(duì)象繼承自一個(gè)名為UICollectionViewLayout的抽象類吓揪。如果需要將UICollectionViewCell按網(wǎng)格布局,則可以使用系統(tǒng)提供的UICollectionViewFlowLayout所计。但是柠辞,如果需要實(shí)現(xiàn)其他的布局方式,就必須創(chuàng)建UICollectionViewLayout的自定義子類主胧。
UICollectionViewCell也有contentView叭首,但是與UITableViewCell不同,UICollectionViewCell的contentView在默認(rèn)情況下沒(méi)有任何子視圖(UITableView默認(rèn)是有Cell踪栋,不一定要自主創(chuàng)建)焙格。因此,如果需要使用UICollectionView夷都,通常還需要?jiǎng)?chuàng)建一個(gè)UICollectionViewCell子類眷唉。
最后,UICollectionViewCell也具有背景視圖和選中狀態(tài)下的背景視圖(當(dāng)UICollectionViewCell處于選中狀態(tài)時(shí)囤官,該視圖會(huì)覆蓋在背景視圖上方)冬阳。