2014-09-28 58 views

回答

1

寫在一個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(); 
}]; 

還有很多其他的方法可以做到這一點的!

+0

我希望我能利用大小班,IB做到這一點。但是,這仍然有效。謝謝 – user1890689 2014-09-29 01:09:10

1

如果你的目標的iOS 8,你可以充分利用新size classes。雖然這不會對以前版本的操作系統有所幫助,但它肯定會成爲iOS 8+的資產。

您可以通過選擇一個視圖控制器和使大小類在Interface Builder做到這一點:

然後,構建視圖時,設置要建立在底部限制大小類

您還可以添加,修改,並直接從約束的屬性檢查器視圖中刪除尺寸類特定的約束條件:故事板窗口:

1

不幸的是,有沒有辦法來建立這種自動跟隨你的請求的佈局。在iOS8中,在Size Classes的幫助下(如之前的回答中已經提到的那樣),您可以做到這一點,但僅適用於iPhone,它會根據方向更改更改類。由於你的例子有iPad的佈局,所以沒有這樣的事情,你必須自己跟蹤方向並相應地改變佈局。

編輯: 其實,只要你做的iPad只佈局,或者你做通用的佈局,但iPhone和iPad有着相同的一個,並且僅在取向的變化而變化,有一個黑客所希望這將表現: 現嵌入在容器視圖控制器中的視圖控制器以及容器覆蓋-viewWillTransitionToSize:withTransitionCoordinator:中,並通過調用-setOverrideTraitCollection:forChildViewController:來強制更改控制器的特性,其特性與容器的新大小相關(例如:size.width> size.height爲UIUserInterfaceSizeClassRegular水平和垂直上的UIUserInterfaceSizeClassCompact)。

該過程的問題在於,它改變了所有其他使用其特徵的類感知此視圖控制器的方式。

0

隨着新的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 
    } 
} 
相關問題