[英]Auto-Layout - Portrait and Landscape with one Storyboard using constraint priorities?
我應該如何使用“自動布局”實現以下布局?
我可以使用一組約束來做到這一點嗎,例如使用不同的約束優先級? 還是我需要使它成為兩個單獨的定義-如果是這樣,如何在它們之間無縫過渡?
大盒子(圖片)
小盒子(按鈕)
肖像
小盒子應該在大盒子下面
景觀
由於垂直空間有限,小盒子應該移動到右側,再次與大盒子和邊框保持相等的距離(但是這次是右邊的盒子)
理想情況下,我想直接在其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.