我有兩個視圖'視圖A'和'視圖B'。我想在橫向模式下並排顯示它們,但在縱向模式下一個顯示。如何使用自動佈局來實現這一點? 如何使用自動佈局在縱向模式下垂直堆疊視圖,在橫向模式下水平堆疊視圖?
回答
寫在一個UIViewController的-viewDidLoad方法:
[super viewDidLoad];
// Assuming viewA and viewB have already been setup and have their
// translatesAutoresizingMaskIntoConstraints property set to NO
NSDictionary *views = NSDictionaryOfVariableBindings(viewA,viewB);
NSArray *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
// Construct all of the constraints
a1 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[viewA]|" options:0 metrics:nil views:views];
a2 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[viewB]|" options:0 metrics:nil views:views];
a3 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[viewA][viewB]|" options:0 metrics:nil views:views];
a4 = @[[NSLayoutConstraint constraintWithItem:viewB attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:viewA attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]];
self.portraitConstraints = @[a1,a2,a3,a4];
a5 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[viewA][viewB]|" options:0 metrics:nil views:views];
a6 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[viewA]|" options:0 metrics:nil views:views];
a7 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[viewB]|" options:0 metrics:nil views:views];
a8 = @[[NSLayoutConstraint constraintWithItem:viewB attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:viewA attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
self.landscapeConstraints = @[a5,a6,a7,a8];
// Add all of the constraints
for (NSArray *constraints in self.portraitConstraints) {
[self.view addConstraints:constraints];
}
for (NSArray *constraints in self.landscapeConstraints) {
[self.view addConstraints:constraints];
}
// Activate the constraints based on the orientation
void(^constraintBlock)() = ^{
// I'm using 'active' property instead of adding and removing constraints. I haven't
// checked to see which way is "better" but it works well so I won't bother!
if (UIDeviceOrientationIsPortrait([[UIApplication sharedApplication]statusBarOrientation])) {
for (NSArray *constraints in self.landscapeConstraints) {
for (NSLayoutConstraint *c in constraints) {
c.active = NO;
}
}
for (NSArray *constraints in self.portraitConstraints) {
for (NSLayoutConstraint *c in constraints) {
c.active = YES;
}
}
} else {
for (NSArray *constraints in self.portraitConstraints) {
for (NSLayoutConstraint *c in constraints) {
c.active = NO;
}
}
for (NSArray *constraints in self.landscapeConstraints) {
for (NSLayoutConstraint *c in constraints) {
c.active = YES;
}
}
}
};
// Call the block immediately to setup the constraints
constraintBlock();
// self.observer is a property I would then use in the viewController's -dealloc
// method to remove it as an observer of the default NSNotificationCenter
self.observer = [[NSNotificationCenter defaultCenter]addObserverForName:UIApplicationDidChangeStatusBarOrientationNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
// Update the constraints whenever the status bar orientation changes
constraintBlock();
}];
還有很多其他的方法可以做到這一點的!
如果你的目標的iOS 8,你可以充分利用新size classes。雖然這不會對以前版本的操作系統有所幫助,但它肯定會成爲iOS 8+的資產。
您可以通過選擇一個視圖控制器和使大小類在Interface Builder做到這一點:
然後,構建視圖時,設置要建立在底部限制大小類
您還可以添加,修改,並直接從約束的屬性檢查器視圖中刪除尺寸類特定的約束條件:故事板窗口:
不幸的是,有沒有辦法來建立這種自動跟隨你的請求的佈局。在iOS8中,在Size Classes的幫助下(如之前的回答中已經提到的那樣),您可以做到這一點,但僅適用於iPhone,它會根據方向更改更改類。由於你的例子有iPad的佈局,所以沒有這樣的事情,你必須自己跟蹤方向並相應地改變佈局。
編輯: 其實,只要你做的iPad只佈局,或者你做通用的佈局,但iPhone和iPad有着相同的一個,並且僅在取向的變化而變化,有一個黑客所希望這將表現: 現嵌入在容器視圖控制器中的視圖控制器以及容器覆蓋-viewWillTransitionToSize:withTransitionCoordinator:
中,並通過調用-setOverrideTraitCollection:forChildViewController:
來強制更改控制器的特性,其特性與容器的新大小相關(例如:size.width> size.height爲UIUserInterfaceSizeClassRegular
水平和垂直上的UIUserInterfaceSizeClassCompact
)。
該過程的問題在於,它改變了所有其他使用其特徵的類感知此視圖控制器的方式。
隨着新的UIStackView
(在iOS 9.0中引入)現在很容易。只需在故事板中添加一個UIStackView和兩個視圖並定義所需的比例即可。
然後在視圖控制器,你可以直接在方向變化適應軸的對齊方式:
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
switch UIDevice.currentDevice().orientation {
case .Portrait:
self.stackview.axis = .Vertical
case .PortraitUpsideDown:
self.stackview.axis = .Vertical
case .LandscapeLeft:
self.stackview.axis = .Horizontal
case .LandscapeRight:
self.stackview.axis = .Horizontal
default:
self.stackview.axis = .Vertical
}
}
- 1. Android SCREEN_ORIENTATION_PORTRAIT僅在橫向模式下顯示縱向視圖
- 2. 在橫向模式下打開視圖
- 3. 使用堆疊面板 - 垂直+水平
- 4. 在橫向模式下向窗口添加新視圖以縱向模式渲染視圖
- 5. 導航控制器堆疊在橫向模式下,但模態顯示視圖控制器視圖總是以縱向框架大小
- 6. Appcelerator:垂直堆疊視圖可能嗎?
- 7. 反應原生:如何動畫視圖從垂直堆疊到水平
- 8. 縱向應用 - 橫向模式視圖 - 無自轉
- 9. UIViewController在縱向模式下爲空,但子視圖在橫向模式下可見?
- 10. 如何將視圖從縱向旋轉到橫向模式
- 11. 如何將縱向視圖更改爲橫向模式?
- 12. 在橫向和縱向模式下使用ScrollViewer正確滾動
- 13. 堆疊divs - 垂直和水平佈局的混合
- 14. 如何在縱向模式下創建2列,在橫向模式下創建3個iPad佈局?
- 15. 在橫向模式下向UIScrollView添加子視圖
- 16. 自定義視圖在橫向模式下替換TableView
- 17. UIWebview在模式視圖中以縱向模式顯示在風景模式下
- 18. Android相機在縱向和橫向模式下保存圖像
- 19. 如何製作橫向模式下的垂直工具欄,該模式可以在縱向模式下旋轉成水平狀態?
- 20. 如何在橫向模式下打開視圖控制器?
- 21. ARToolkit,如何在橫向模式下設置視圖
- 22. 在iPad上橫向模式下水平翻轉視圖控制器
- 23. 如何在橫向模式下添加兩個視圖或圖像視圖?
- 24. 如何更改橫向模式下圖像視圖的位置
- 25. Twitter Bootstrap - 直到移動視圖才堆疊的網格佈局
- 26. 橫向佈局不能在橫向模式下工作
- 27. 如何安排在水平堆疊視圖
- 28. 在橫向和縱向模式下啓動iPad應用程序
- 29. 如何在橫向模式下將子視圖與主視圖一起轉換
- 30. 在RecyclerView中堆疊視圖
我希望我能利用大小班,IB做到這一點。但是,這仍然有效。謝謝 – user1890689 2014-09-29 01:09:10