2014-02-06 49 views
10

我以編程方式構建視圖並使用自動佈局,根本沒有接口構建器。在自定義的ScrollView控制器中,我添加了一個UILabel和一個UIButton作爲子視圖。我想將標籤對齊屏幕左側和屏幕右側的按鈕。出於某種原因,我的按鈕只與我的滾動視圖的左側對齊。我已經削減了我的代碼,以便它只有這兩個標籤,我不明白爲什麼它不會對齊到正確的位置。自動佈局iOS 7 - 無法將子視圖的右側對齊到UIScrollView的右側

HWScrollViewController.m(我如何初始化主滾動視圖)

- (void)loadView 
{ 
    self.scrollView = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; 

    self.scrollView.delegate = self; 

    self.view = self.scrollView; 
} 

HWListingDetailViewController.m

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 

UILabel *priceLabel = [[UILabel alloc] init]; 
UIButton *favouriteButton = [UIButton buttonWithType:UIButtonTypeContactAdd]; 

[priceLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; 
[favouriteButton setTranslatesAutoresizingMaskIntoConstraints:NO]; 

[priceLabel setText:@"$125.00"]; 
[favouriteButton setTitle:@"Add to Favourites" forState:UIControlStateNormal]; 

[self.view addSubview:priceLabel]; 
[self.view addSubview:favouriteButton]; 

[self.view addConstraints:@[ 
    [NSLayoutConstraint constraintWithItem:priceLabel 
           attribute:NSLayoutAttributeCenterY 
           relatedBy:NSLayoutRelationEqual 
            toItem:self.view 
           attribute:NSLayoutAttributeCenterY 
           multiplier:1 
            constant:0], 

    [NSLayoutConstraint constraintWithItem:priceLabel 
           attribute:NSLayoutAttributeLeft 
           relatedBy:NSLayoutRelationEqual 
            toItem:self.view 
           attribute:NSLayoutAttributeLeft 
           multiplier:1 
           constant:5], 

    [NSLayoutConstraint constraintWithItem:favouriteButton 
           attribute:NSLayoutAttributeCenterY 
           relatedBy:NSLayoutRelationEqual 
            toItem:self.view 
           attribute:NSLayoutAttributeCenterY 
           multiplier:1 
            constant:0], 

    [NSLayoutConstraint constraintWithItem:favouriteButton 
           attribute:NSLayoutAttributeRight 
           relatedBy:NSLayoutRelationEqual 
            toItem:self.view 
           attribute:NSLayoutAttributeRight 
           multiplier:1 
            constant:5], 

}

Screenshot of problem

正如你所看到的,綠色價格標籤正確對齊,但紅色按鈕遠離屏幕的左側。 (我給它5個像素的偏移量以顯示它的位置。)那麼,爲什麼scrollview的右側實際上是左側?我該如何正確對齊屏幕右側?我哪裏做錯了?這真讓我抓狂!

感謝您的幫助!

最後的版面圖: 我希望的最終佈局是這樣的: Final Layout Portrait

,我希望它看起來就像這樣旋轉爲橫向: Final Layout Landscape

回答

8

約束的數量不是問題。 UILabelUIButton將根據intrinsicContentSize確定它們的大小,並且由於您對該職位有限制,因此它應該具有所需的所有佈局信息。

但是,當涉及到自動佈局時,UIScrollViews以獨特的方式運行。最好的描述來自這個technical note。有兩個選項可用,包括示例,但是每個選項都是摘要。


混合的方法

你只需要添加一個UIViewUIScrollView然後在UIView添加和定位所有的子視圖。這需要您手動設置UIScrollView上的UIViewcontentSizeframe

這可能是您嘗試實現的佈局最容易使用的。但是,如果contentSize可以更改,則必須手動計算並更新大小。


純自動佈局方法

該選項使用自動佈局的限制,以確定UIScrollViewcontentSize。這需要約束到UIScrollView的所有四個邊,並且不能依賴於UIScrollView的大小。

由於您需要確保您有足夠的限制,因此使用該選項更加困難。在你的情況下,你會遇到問題,因爲UIScrollView的頂部和底部沒有限制,並且沒有限制可以用來確定UIScrollView的寬度。然而,當你必須處理動態內容時,這個選項是驚人的,因爲它會根據需要調整contentSize的大小。


就我個人而言,我會採用純自動佈局方法。它能夠處理動態內容大小,使額外的約束設置值得。

如果你發佈你想要的最終佈局是什麼,我會更新我的答案以反映這一點。


更新

根據您發佈的圖片,這是我會用純自動佈局方法組織子視圖的方式。主要區別在於UIScrollView現在是UIViewControllers視圖的子視圖。

- UIView           (self.view) 
    - UIScrollView         (scrollView) 
    - UIView          (contentView) 
     - UIImageView, UIButtons, UILabels, etc. 

scrollView需要約束條件,所以它的邊緣是0px來自self.view。

contentView需要約束,所以它的邊距是scrollView的0px,寬度等於self.view。這是旋轉設備時scrollView更新的contentSize

接下來只需將您的所有圖像和標籤按您想要的方式放置即可。標籤需要被限制在左側和右側,以便可以計算其高度。重要的是要注意的是,contentView將根據其子視圖的約束來確定其高度,因此您需要約束「鏈接」contentView的頂部和底部。一個模樣的例子看起來像這樣。

  • 內容查看頂部的ImageView頂部
  • ImageView的高度==一些價值
  • ImageView的底部標註頂部
  • 標籤底部內容查看底部
+1

我同意純自動佈局方法是我正在尋找的,在屏幕上會有大量的動態內容,但是它只會在垂直方向上呈動態。除了屏幕寬度之外,我沒有任何設置水平約束的東西。我將編輯我的問題以添加最終佈局圖像。 – Wernzy

0

你沒有足夠的按鈕限制。實際上,你對標籤的限制還不夠,但這並不一定會使你的按鈕停在屏幕右側。

總是必須具有約束條件,這些約束條件指定視圖在水平方向和垂直方向上的行爲方式。通常這意味着至少有四個約束 - x,y,寬度和高度。如果你不這樣做,iOS會猜測你的機會是錯的。您可能會注意到Xcode控制檯中出現了一些警告。

對於這個問題,它確實取決於你希望你的視圖看起來如何,但最簡單的解決方案是設置按鈕的寬度約束。你可以這樣做:

[NSLayoutConstraint constraintWithItem:favouriteButton 
          attribute:NSLayoutAttributeWidth 
          relatedBy:NSLayoutRelationEqual 
          toItem:nil 
          attribute:NSLayoutAttributeNotAnAttribute 
          multiplier:1.0 
          constant:64.0]; 

其中64.0f如果按鈕的寬度。

如果您希望按鈕是標籤的右邊和寬度相同(即每個佔用屏幕的50%),你可以這樣做:

[NSLayoutConstraint constraintWithItem:favouriteButton 
           attribute:NSLayoutAttributeLeading 
           relatedBy:NSLayoutRelationEqual 
            toItem:priceLabel 
           attribute:NSLayoutAttributeTrailing 
           multiplier:1.0f 
            constant:0.0f]; 

    [NSLayoutConstraint constraintWithItem:favouriteButton 
           attribute:NSLayoutAttributeWidth 
           relatedBy:NSLayoutRelationEqual 
            toItem:priceLabel 
           attribute:NSLayoutAttributeWidth 
           multiplier:1.0f 
            constant:0.0f]; 

以上所有兩個約束條件是將標籤的後沿設置爲按鈕的前沿,然後說兩個視圖的寬度必須相同。

您還應該爲兩個視圖(或頂部和底部約束)真的添加高度約束。我知道你有一個垂直居中約束,但是沒有指定它的大小。iOS可能會通過內容高度來解決問題,但很可能會在控制檯中引發警告。

+1

不幸的是這並沒有解決問題。只要我根本不旋轉視圖,它就提供了一個相當接近的近似值,但如果我切換到橫向模式,則該按鈕僅與標籤左對齊。我的這個答案的另一個問題是,如果沒有UILabel那裏,我希望仍然能夠對齊一個視圖。 – Wernzy