2012-11-20 67 views
12

我已經創建了子類UIView來創建一個自定義的組視圖,以便以簡單的方式向佈局中添加一些內容。這個groupView包含一個用作標題的UILabel和一個用背景顏色在CALayer上繪製一個roundRect的UIView。想想UITableView的部分。我通過刪除一個UIView並將它的類更改爲我的子類來將此groupView添加到故事板。一切正常,我通過Xcode中的用戶定義的運行時屬性設置標題。所有的作品都很棒,我在故事板上的這個視圖中添加了UILabels,並在它運行時創建了標題標籤和圓角。以編程方式自動生成子類UIView的子視圖

結構我groupView的:

  1. groupView:(UIView的)clipToBounds:否;
    • 標題:(UILabel)位於groupView的上方 。
    • contentView:(UIView)通過CALayer創建roundRect 和顏色,其大小應與groupView相同。

那麼是什麼問題?那麼,處理自動佈局是一個痛苦開始,但對於這個子類UIView工作,我需要以編程方式設置contentView約束。我無法弄清楚這個自動佈局ASCII格式字符串的語法。目前,我有:

_contentView = [[UIView alloc]initWithFrame:self.bounds]; 

    _contentView.layer.cornerRadius = 5.0f; 
    _contentView.layer.masksToBounds=YES; 
    _contentView.backgroundColor=_backgroundColor; 
    _contentView.layer.borderWidth=_borderWidth; 
    _contentView.layer.borderColor=_borderColor.CGColor; 
    [self insertSubview:_contentView atIndex:0]; 
    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(self,_contentView); 
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"[self]-0-[_contentView]-0-[self]" options:0 metrics:nil views:viewsDictionary]; 

    for (NSLayoutConstraint *constraint in constraints) { 
     [_contentView addConstraint:constraint]; 
    } 

與崩潰:*終止應用程序由於未捕獲的異常「NSGenericException」,理由是:「無法在視圖安裝約束。約束是否從視圖的子樹之外引用了某些東西?這是違法的。約束:查看:>「

我嘗試這樣做第一,它仍然沒有工作:

NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_contentView); 
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-0-[_contentView]-0-|" options:0 metrics:nil views:viewsDictionary]; 

與崩潰:*終止應用程序由於未捕獲的異常‘NSGenericException’,原因:」無法在視圖上安裝約束。約束是否從視圖的子樹之外引用了某些東西?這是違法的。約束:查看:>」

RANT:不知怎的,這個自動版式是想拯救我們的工作,但我 怎麼看不到好處了重量開銷現在。爲什麼 他們從使用參考和方法,甚至輸入 defs這個古老的格式字符串?這樣做會容易多少: [_contentView constraint:NSLayoutFormatAlignLeading toView:self withDistance:0.0f];或類似的東西?在這一點上,我寧願用彈簧和支柱來處理 。

任何幫助理解,或向我展示將contentView約束爲自身大小的語法將有所幫助。

+2

關於你的咆哮:Autolayout有一個學習曲線,你一開始往往會討厭它 - 但一旦你完全用約束而不是框架來思考,它會變得更容易。而「視覺格式」是非常沒用的,除非你只是把東西排成一排。另一種方法(constraintWithItem ...)基本上就是你在上面提到的語法之後的語法。 – jrturton

+0

如果其他人在理解這種ASCII-Art格式字符串時遇到問題,我發現本教程很有幫助。我知道它是用於Ruby的,但格式字符串與Objective-C中的相同。 http://seanlilmateus.github.com – brucemartin

回答

26

錯誤告訴你,你需要知道:

是否約束參考的東西從視圖中的子樹之外?

是的。它引用了它的超級視圖。

你正在需要這些限制將被應用於上海華,在這種情況下groupView

+0

好吧,但是這不是子視圖的約束嗎?這是我需要自動調整大小的子視圖。我只是在想這個錯嗎? – brucemartin

+1

想一下這樣:它對'groupView'中'contentView'的位置和大小有一個約束。請參閱安裝限制部分:http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AutolayoutPG/Articles/constraintFundamentals.html – jackslash

+0

好吧,是的,我看到現在,這就是爲什麼在Xcode的約束下顯示superViews不是視圖本身。仍然有語法問題。回到文檔中,也許它會在這個時候下沉。感謝您的洞察力。 – brucemartin

0

的|字符表示的視覺形式語言的上海華盈,所以我想你想:

@"|-0-[_contentView]-0-|" 

,然後你需要將約束添加到自我,而不是內容查看,你需要將它添加到可以看到一個視圖所有參與的球員。

下面是視覺語言參考: https://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AutolayoutPG/Articles/formatLanguage.html#//apple_ref/doc/uid/TP40010853-CH3-SW1

您也可避免視覺格式完全使用:

+(id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c 
+0

當然,如果你將約束添加到self而不是contentView,那麼管道(|)將引用self的superview? –

0

嘗試檢查constrints,他們是否正確添加到視圖

如:

UIView *yellowView = [[UIView alloc] init]; 
yellowView.backgroundColor = [UIColor yellowColor]; 
yellowView.translatesAutoresizingMaskIntoConstraints = false; 
[self.view addSubview:yellowView]; 

//ios 9 last 
NSLayoutConstraint *heightAnchor = [yellowView.heightAnchor constraintEqualToAnchor:self.purView.heightAnchor]; 
// addConstraints 
[self.view addConstraints:@[heightAnchor]]; 
[self.view setNeedsLayout]; 

如果加上heightAnchor toyellowView就像下面一樣。它會顯示錯誤

[yellowView addConstraints:@ [heightAnchor]];

相關問題