2013-07-21 62 views
5

我將一個UIView添加到UIScrollView並限制它,使其填充水平空間,除了一些利潤率。我的視覺約束是這樣的:UIView不遵守自動佈局約束UIScrollView

@"|-16-[theLineView]-16-|" 

我曾認爲一個像素高,所以它會顯示爲一條線,並將其放置兩個文本標籤之間:

@"V:[someOtherStuff]-[aTextLabel]-[theLineView]-[anotherLabel]" 

然而,我發現該線的寬度只擴展到最上面/最下面的標籤的寬度。

這是爲什麼?

P.S我已閱讀本http://developer.apple.com/library/ios/#technotes/tn2154/_index.html

enter image description here

代碼

這裏是由顯示在iPad上的SIM這個問題一個測試項目視圖控制器代碼的全部。

- (void)viewDidLoad 

{ [super viewDidLoad];

self.scrollView = [[UIScrollView alloc] init]; 
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO; 
self.scrollView.backgroundColor = [UIColor greenColor]; 
[self.view addSubview:self.scrollView]; 
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[scrollView]|" 
                   options:0 
                   metrics:0 
                    views:@{@"scrollView":self.scrollView}]]; 
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" 
                    options:0 
                    metrics:0 
                    views:@{@"scrollView":self.scrollView}]]; 

self.line1 = [[UIView alloc] init]; 
self.line2 = [[UIView alloc] init]; 
self.label1 = [[UILabel alloc] init]; 
self.label2 = [[UILabel alloc] init]; 
self.label3 = [[UILabel alloc] init]; 

for (UILabel *label in @[self.label1, self.label2, self.label3]) 
{ 
    label.text = @"I am a label and I am long enough that I can be multiline on an iphone but single on ipad"; 
} 

for (UIView *view in @[self.line1, self.line2, self.label1, self.label2, self.label3]) 
{ 
    view.translatesAutoresizingMaskIntoConstraints = NO; 
    view.backgroundColor = [UIColor redColor]; 
    [self.scrollView addSubview:view]; 
} 

//horizontal layout - all views/labels should fill the horizontal space expect for margin 
for (UIView *view in @[self.line1, self.line2, self.label1, self.label2, self.label3]) 
{ 
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-16-[view]-16-|" 
                    options:0 
                    metrics:0 
                    views:@{@"view":view}]; 
    [self.scrollView addConstraints:constraints]; 
} 

//vertical layout - stack em up 
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[lab1]-[line1(==1)]-[lab2]-[line2(==1)]-[lab3]-|" 
                    options:0 
                    metrics:0 
                    views:@{@"lab1":self.label1, @"line1":self.line1, @"lab2":self.label2, @"line2":self.line2, @"lab3":self.label3}]]; 

}

+0

你的1px UIView對它有沒有其他約束? – Yazid

+0

[view]與[theLineView]是否一樣?在選項參數中是否有任何對齊選項設置? – rdelmar

+0

選項參數中沒有其他限制或任何內容。我會看看我是否可以在測試項目中複製。是的,這些觀點是相同的,糾正了片段。 –

回答

6

UIScrollView的自動收縮以適應它裏面的景色。你需要在某個地方設置寬度。

推薦策略:

  1. 完全fixiate滾動視圖其父視圖內使用約束(前置,頂部,底部)。
  2. 在UIScrollView裏面創建一個UIView,並把你需要的所有東西放在裏面。
  3. 設置約束,以便UIView將充當內容視圖(這意味着它足夠大以包含所有元素)。使用固有內容大小,縮小阻力和鏈接的元素與約束很多。由此產生的佈局必須是明確的和獨特的(這意味着如果你要去除所有的限制,佈局仍然可以工作)。
  4. 連接UIView的邊界與他們的超級視圖(這是UIScrollView的實際內容視圖,而不是UIScrollView!)。

如果你在interface-builder中做到了這一點(這是可能的),那麼每次你觸摸那個場景中的東西時都需要重新檢查你的約束。我的意思是「選擇」不僅僅是「修改」。

+0

沒有爲我工作,如何我設置UIView來填充滾動視圖的整個寬度? – AndiDog

+0

正如我所說:contentView ALWAYS填充完整的scrollView,因爲scrollView縮小了。你必須在裏面設置寬度。在你的例子中,將格式從「| -16- [view] -16- |」到「| -16- [查看(288)] - 16- |」應該給你一個好的結果。 –

+3

這工作。在我看來,數字4是更好的方法,因爲它很簡單並且避免了任何幻數(這意味着它支持旋轉等)。 –

2

找到了一個適用於您的用例的工作解決方案。見here

2

擴展到Patric Sc​​henke答案的第4位;因爲scrollView的內容大小是流暢的,所以將內部視圖固定到它的邊緣對於確定視圖的寬度不起作用。你的左側別針會起作用,但兩者都不會。根據下一級容器計算視圖的寬度是一種方法。只要您的self.scrollView與其容器齊平(我稱之爲containerView),這行代碼就可以完成您想要的任務。該行添加到您的for環路水平的制約:

// Pin view's width to match the scrollView container's width 
// -32 constant offset for margins 
[containerView addConstraint: 
    [NSLayoutConstraint constraintWithItem:view 
           attribute:NSLayoutAttributeWidth 
           relatedBy:NSLayoutRelationEqual 
            toItem:containerView 
           attribute:NSLayoutAttributeWidth 
           multiplier:1.0f 
           constant:-32]]; 
0

我發現了一個簡單的基於約束的方式來做到這一點(我沒有測試過這種解決方案的脆性程度):

[email protected]"H:|-16-[view]-16-|"... // (your original constraint) 

[self.scrollView addConstraint: 
    [NSLayoutConstraint constraintWithItem:view 
           attribute:NSLayoutAttributeCenterX 
           relatedBy:NSLayoutRelationEqual 
            toItem:self.scrollView 
           attribute:NSLayoutAttributeCenterX 
           multiplier:1.0f 
           constant:0.0f]]; 

這延伸到view一直到視圖的另一側。對於水平滾動的內容而言,這可能並不理想,但應該垂直工作。

我意識到這是一年以後,但對於單維滾動用例來說比patric.schenke的答案更簡單(它更好,更穩健)。