簡體   English   中英

自動布局-使用約束優先級使用一個Storyboard的縱向和橫向?

[英]Auto-Layout - Portrait and Landscape with one Storyboard using constraint priorities?

我應該如何使用“自動布局”實現以下布局?

我可以使用一組約束來做到這一點嗎,例如使用不同的約束優先級? 還是我需要使它成為兩個單獨的定義-如果是這樣,如何在它們之間無縫過渡?

在此處輸入圖片說明

大盒子(圖片)

  • 應該始終位於屏幕中央,並占用盡可能多的空間(減去最近邊框的空白)
  • 正方形,比例1:1
  • 實際尺寸動態分配在可用的屏幕上

小盒子(按鈕)

  • 正方形,比例1:1,固定大小(例如150×150 pt)

肖像

小盒子應該在大盒子下面

景觀

由於垂直空間有限,小盒子應該移動到右側,再次與大盒子和邊框保持相等的距離(但是這次是右邊的盒子)

理想情況下,我想直接在其Storyboard中設置約束。 但是,如果需要創建單獨的版本,我希望使用代碼。

我認為做到這一點的最佳方法是使用代碼動態更新約束。 我使用另一個SO用戶提供的框架

您需要覆蓋updateConstraints並將當前方向存儲在屬性中,這樣就不必繼續不必要地更新約束(這將導致性能問題)。 在您的布局中,可能只有一個約束需要替換; 我可能也將對它的引用存儲為屬性,因此不必查找它。 然后,您的updateConstraints實現只需刪除該約束並將其替換為portrait / landscape等效項即可。 使用框架提供的autoPinEdge:toEdge:ofView:withOffset:方法,您可以使用偏移量來管理視圖之間的間距。

例如:

self.savedConstraint = [smallView autoPinEdge:ALEdgeTop to Edge:ALEdgeBottom ofView:largeView withOffset:kSpacing];

在您的情況下,我認為您只需要替換將小視圖的頂部邊緣固定到大視圖(人像)底部的約束,並用將小視圖的頂部邊緣固定到后邊緣的約束替換即可。小的。 您可能還需要管理從小視圖的底部/后緣到超級視圖的底部/右端的約束。

您需要通過代碼來完成。 在您的視圖控制器中:

- (void)viewDidLoad
{

    //Set width and height of big box
    [bigBox addConstraint:[NSLayoutConstraint constraintWithItem:bigBox
                                                       attribute:NSLayoutAttributeWidth
                                                       relatedBy:NSLayoutRelationEqual
                                                          toItem:nil
                                                       attribute:NSLayoutAttributeNotAnAttribute
                                                      multiplier:1.0
                                                        constant:BIG_BOX_WIDTH]];

    [bigBox addConstraint:[NSLayoutConstraint constraintWithItem:bigBox
                                                       attribute:NSLayoutAttributeHeight
                                                       relatedBy:NSLayoutRelationEqual
                                                          toItem:nil
                                                       attribute:NSLayoutAttributeNotAnAttribute
                                                      multiplier:1 constant:BIG_BOX_HEIGHT]];

    //Center big box in super view
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:bigBox
                                                          attribute:NSLayoutAttributeCenterX
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeCenterX
                                                         multiplier:1.0 constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:bigBox
                                                          attribute:NSLayoutAttributeCenterX
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeCenterX
                                                         multiplier:1.0 constant:0]];

    //Set width and height of small box
    [smallBox addConstraint:[NSLayoutConstraint constraintWithItem:smallBox
                                                       attribute:NSLayoutAttributeWidth
                                                       relatedBy:NSLayoutRelationEqual
                                                          toItem:nil
                                                       attribute:NSLayoutAttributeNotAnAttribute
                                                      multiplier:1.0
                                                        constant:SMALL_BOX_WIDTH]];

    [smallBox addConstraint:[NSLayoutConstraint constraintWithItem:smallBox
                                                       attribute:NSLayoutAttributeHeight
                                                       relatedBy:NSLayoutRelationEqual
                                                          toItem:nil
                                                       attribute:NSLayoutAttributeNotAnAttribute
                                                      multiplier:1 constant:SMALL_BOX_HEIGHT]];


}

- (void) willAnimateRotationToInterfaceOrientation (UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [UIView animateWithDuration:duration animations:^{
        [self updateViewConstraints];
        [self.view layoutIfNeeded];
    }];
}

- (void)updateViewConstraints
{


    //Remove previous position constraints between big box and small box.
    for(NSLayoutConstraint *boxPosition in self.boxPositionConstraints) {
        [self.view removeConstraint:boxPosition];
    }
    self.boxPositionConstraints = nil;

    //Check orientation and create new visual format layout between big box and small box
    BOOL layoutIsPortrait = UIDeviceOrientationIsPortrait(self.interfaceOrientation);
    NSString *axisPrefix = layoutIsPortrait ? @"V" : @"H:";
    NSLayoutFormatOptions alignmentOption = layoutIsPortrait ? NSLayoutFormatAlignAllCenterX : NSLayoutFormatAlignAllCenterY;
    NSString *layoutFormat = [NSString stringWithFormat:@"%@:[bigBox]-%@-[smallBox]", axisPrefix, BOX_DISTANCES];

    NSDictionary *bindings = NSDictionaryOfVariableBindings(bigBox, smallBox);
    self.boxPositionConstraints = [NSLayoutConstraint constraintsWithVisualFormat:layoutFormat
                                                                              options:alignmentOption
                                                                              metrics:nil
                                                                                views:bindings];
    [self.view addConstraints:self.boxPositionConstraints];

}

從您的圖表中,我假設您的大盒子的大小取決於設備的寬度。 如果是這樣,您可以根據所使用的設備以正確的大小創建條件。 由於只有少數iOS設備,因此我認為現在這比將其大小取決於屏幕大小要容易得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM