日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用XIB实现嵌套自定义XIB视图

發(fā)布時(shí)間:2024/9/30 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用XIB实现嵌套自定义XIB视图 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在進(jìn)行?iOS?開發(fā)的過程中,對(duì)于一些復(fù)雜的界面,我們可以通過?Interface Builder?這個(gè)?Xcode?集成的可視化界面編輯工具在完成,這回節(jié)省大部分時(shí)間以及代碼量。它的使用方法這里不做介紹了,這次我要介紹是使用它來實(shí)現(xiàn)一個(gè)嵌套的自定義視圖。解釋一下就是,我們使用?IB?自定義了一個(gè)?View?,然后又在其他的?xib?文件中使用了這個(gè)?View?,那么這就是所謂的嵌套自定義視圖。之所以要介紹它,是因?yàn)槲易约涸谑褂盟臅r(shí)候遇到了一些問題,一方面寫下來做個(gè)記錄供自己查看,另一方面我相信大家在使用的時(shí)候應(yīng)該也會(huì)遇到這樣的問題,方便大家。?

下面使用的示例代碼我已經(jīng)放到?Github?上了,?項(xiàng)目地址?,有需要的朋友可以去查看,?Demo?非常簡(jiǎn)單,主要是介紹這個(gè)知識(shí)點(diǎn)。?

Question

首先我們創(chuàng)建一個(gè)?SingleView?的工程,項(xiàng)目使用?StoryBoard?,(使用?Xib也無所謂,因?yàn)橛行├系捻?xiàng)目可能還沒有使用到?StoryBoard?),然后創(chuàng)建一個(gè)?CustomView?作為我們的自定義視圖。?

有時(shí)對(duì)于復(fù)雜的界面我們可能會(huì)拆分出來對(duì)它進(jìn)行單獨(dú)處理,又有可能它的界面布局很復(fù)雜,這時(shí)我們就會(huì)用?Interface Builder?對(duì)它的布局進(jìn)行處理。這里的?CustomView?就是這樣一個(gè)視圖,所以我們?yōu)樗鼊?chuàng)建一個(gè)?xib?文件,我們通常的作法就是把?xib?中的?View?的?custom class?更改為我們的?CustomView?。?

接下來對(duì)我們的界面進(jìn)行布局,并連接輸出口,編寫響應(yīng)邏輯,這里我放了一個(gè)?ImageView?和一個(gè)?Label?在這里,并把?View?的背景色設(shè)置為淺灰色。?

自定義的?View?制作完成,回到我們?ViewController?的?xib?文件,拖入兩個(gè)?View?并把他們的?custom class?更改為?CustomView?。?

這時(shí),我們算是工作做完了,運(yùn)行程序,結(jié)果悲劇了,怎么不是我們想要的結(jié)果,為什么只生成了兩個(gè)空白的視圖,我們視圖上的圖片和文字哪里去了?

在?CustomView?中的?awakeFromeNib?方法中增加斷點(diǎn)調(diào)試發(fā)現(xiàn),在?CustomView?初始化完成后,?ImageView?和?Label?并沒有被初始化,他們?nèi)匀皇?nil?。這就是在嵌套使用?xib?自定義視圖時(shí)非常容易出現(xiàn)的問題,我們覺得被嵌套的視圖能夠正常顯示出來,但是實(shí)際上它并沒有被按照我們?cè)?xib?上指定的方式被初始化。?

Solution

那么如何解決這種問題,以及這種問題又是如何出現(xiàn)的呢?其實(shí)這主要是由于我們對(duì)?xib?文件的加載原理不熟悉所導(dǎo)致的,我們以為定義一個(gè)?View?,創(chuàng)建一個(gè)?xib文件并布局好它的子視圖,讓后將它使用在另外一個(gè)?xib?文件中,把?custom class?改成它,然后?xib?的加載系統(tǒng)會(huì)自動(dòng)為我們做好其余的一切。其實(shí)并不是這樣的。?

這樣做?xib?加載系統(tǒng)只會(huì)為我們創(chuàng)建一個(gè)?CustomView?的對(duì)象,但這并不包括?CustomView?所對(duì)應(yīng)的?xib?文件中的部分,所以只創(chuàng)建了一個(gè)空白的?View?。?

解決他們有兩種方式,不過最終的思路都是通過代碼強(qiáng)制使?CustomView?的?xib部分被加載。第一種是通過代碼創(chuàng)建?CustomView?的對(duì)象,然后?addSubview?到?viewController?的?view?上。第二種是在?CustomView?的實(shí)現(xiàn)文件里,通過重載一些方法,來完成加載?xib?文件。?

這兩種方法各有利弊,第一種使用起來方便也好理解,但是當(dāng)嵌套的層級(jí)比較多的時(shí)候或者一個(gè)?View?中有多個(gè)這樣的?CustomView?時(shí),這種方式就會(huì)顯得過于麻煩。而第二種雖然理解起來有些難度,但是當(dāng)你處理好之后,直接在需要的?xib?文件中拖入?view?,改個(gè)?custom class?,就能直接生成需要的對(duì)象了,并且也能夠在?xib?中對(duì)他們進(jìn)行直接布局,不再需要用代碼去布局了。?

NO 1.

先來介紹第一種方法,很簡(jiǎn)單,就是找到?xib?文件,生成對(duì)象,設(shè)置屬性,?addsubview?到視圖上。?

NO 2.

第二種方法是通過重載?initWithCoder?方法來實(shí)現(xiàn),因?yàn)橥ㄟ^?xib?來創(chuàng)建一個(gè)對(duì)象會(huì)調(diào)用到這個(gè)方法,所以我們需要在這個(gè)方法里做一些處理,把這個(gè)?CustomView?的?xib?中的內(nèi)容加載進(jìn)來,這時(shí)同樣是需要通過代碼來來加載,首先附上代碼?

? - (id)initWithCoder:(NSCoder *)aDecoder { if (self = [super initWithCoder:aDecoder]) { UIView *containerView = [[[UINib nibWithNibName:@"CustomView" bundle:nil] instantiateWithOwner:self options:nil] objectAtIndex:0]; CGRect newFrame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); containerView.frame = newFrame; [self addSubview:containerView]; } return self; }

此外,還要這里的輸出口以及設(shè)置?custom class?的位置跟第一種方式有所不同,這里需要取消掉?xib?中?view?的?custom class?,再將跟它連接的圖片與文字的輸出口取消掉,在這里這個(gè)?view?只是被當(dāng)做一個(gè)容器來處理,它跟?Customview?沒有直接關(guān)系,它將來會(huì)被?addSubview?到?CustomView?上,除此之外還要把?xib?的?File's ower?的?custom class?改成?CustomView?,表示這個(gè)?xib?文件的持有者是?CustomView?。再把它與圖片和文字通過輸出口連接起來。?

這個(gè)時(shí)候在運(yùn)行程序就看到了我們想要的結(jié)果了。?_^

其實(shí)想要實(shí)現(xiàn)第二種解決方案所要的效果,還有一種方式,它是通過重載?awakeAfterUsingCoder:?方法來實(shí)現(xiàn)的,這個(gè)方法的返回值會(huì)替換掉真正的加載對(duì)象,所以在具體的加載?CustomView?的方式又與第一種相同,所以?xib?的輸出口連接與?custom class?的設(shè)置也與第一種解決方案相同。不過這種方式是更復(fù)雜也更難于理解的,不推薦使用,因?yàn)樯弦粋€(gè)方法就能很好的解決這個(gè)問題了,這里只是貼出這個(gè)方法的代碼,有想仔細(xì)研究的請(qǐng)參看文章底部的參考文章。?

? - (id) awakeAfterUsingCoder:(NSCoder*)aDecoder { BOOL isJustAPlaceholder = ([[self subviews] count] == 0); if (isJustAPlaceholder) { CustomView* theRealThing = [[self class] getClassObjectFromNib]; theRealThing.frame = self.frame; // make compatible with Auto Layout self.translatesAutoresizingMaskIntoConstraints = NO; theRealThing.translatesAutoresizingMaskIntoConstraints = NO; // convince ARC that we're legit, unnecessary since at least Xcode 4.5 CFRelease((__bridge const void*)self); CFRetain((__bridge const void*)theRealThing); return theRealThing; } return self; }


原文:http://blog.wtlucky.com/blog/2014/08/10/nested-xib-views/

總結(jié)

以上是生活随笔為你收集整理的使用XIB实现嵌套自定义XIB视图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。