在使用xib自定義view的時候,我的習慣性的直接使用xib中的約束,因此天然而然的要打開Autolayout。之前在使用的時候沒有發現什麼問題,最近項目中使用的時候忽然發如今導航欄透明的狀況下,出現實際的frame比設置的frame高度縮小64的問題,而後上網查找各類博客,最後差點被五花八門的寫法帶跑偏了,遂簡單記錄一下正確的解決方式。佈局
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor redColor]; NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"TestXibView" owner:nil options:nil]; self = xib.lastObject;//注意這裏我使用的是「=」 self.frame = frame; } return self; } - (void)awakeFromNib{ [super awakeFromNib]; }
問題:spa
正常狀況下在控制器的view中添加TestXibView實例view的時候是沒有問題的,3d
可是當我須要設置導航欄不透明的時候,須要用到這句代碼:code
self.navigationController.navigationBar.translucent = NO;
這時,問題出現,問題以下:(僅在控制器view是UIView類型的時候纔會出現,當xib view添加到滾動視圖上時不會有下面的問題)orm
一、添加的view高度會縮減64blog
二、同時控制檯會打印約束衝突的狀況博客
注意:(親測automaticallyAdjustsScrollViewInsets,self.extendedLayoutIncludesOpaqueBars,edgesForExtendedLayout這些設置都解決不了這個問題)it
解決辦法1:(偏門)io
最初在沒有找到形成這種問題的緣由的狀況下,我只能把設置frame的相關demo寫在這個方法中viewDidLayoutSubviews,雖然用着彆扭,可是至少能夠臨時解決問題。ast
- (void)viewDidLayoutSubviews{ [super viewDidLayoutSubviews]; }
解決辦法二、關閉Autoresize SubViews(正解)
控制器中的Autoresize SubViews不勾選
或者在viewdidload方法中添加下面代碼,也能起到相同的效果:
self.view.autoresizesSubviews = NO;
問題的分析:
其實形成xib view高度縮小64像素以及會打印約束衝突的最根本緣由是,咱們在Xcode9上建立xib或者storyboard文件時,會默認打開Autoresize SubViews,因此在設置導航欄透明的時候,由於自動從新佈局以後致使高度縮小,原來的xib中的約束無效。
既然問題查清楚了,那就對症下藥,關閉Autoresize SubViews便可。
其實本身寫的代碼,出錯了,網上的不少辦法只能是參考,由於錯誤的前提或者環境可能差異很大,因此,出現bug時,首先仔細認真的檢查本身的代碼是否存在問題,在確保沒問題(或者本身沒有找到問題)的狀況下能夠去參考網上的一些解決辦法。可是最終仍是要對症下藥,瞭解病症所在才能真正的解決辦法。
其它贅述:固然在xib不綁定TextXibView狀況下,直接使用xib,也就是下面的方法
NSArray *arr=[[NSBundle mainBundle]loadNibNamed:@"TestXibView" owner:nil options:nil]; UIView *tmpView = arr.lastObject; tmpView.frame = CGRectMake(0, 300, 100, 100); [self.view addSubview:tmpView];