在哪里更改"已安装"以进行自动布局约束?

Jor*_*n H 11 screen-rotation ios autolayout nsautolayout ios8

在故事板中使用自动布局时,可以选择是否使用"已安装"复选框来安装约束.禁用它将导致它表现得就像你没有添加该约束 - 它将没有任何效果.您可以在Interface Builder中为不同大小的类配置已安装的状态,并且可以通过将其active属性设置为true或以编程方式更改此值false.

在我的应用程序中,我希望仅在设备处于纵向时安装约束 - 旋转到横向时应该"卸载".通过取消选中为任意宽度紧凑高度安装,可以为iPhone完成此操作.(虽然这似乎不太正常,因为当它甚至不应该安装时,由于在转向横向时出现冲突的约束而破坏了这个约束,但是无论UI总是按预期出现.)但是没有办法卸载Interface Builder中的横向iPad约束(两个方向的常规宽度常规高度).

哪里是合适的地方来启用/禁用activeNSLayoutConstraint轮值设备时?在什么轮换方法将改变该状态导致所需的行为 - 只安装为肖像?如果在启动应用程序时没有调用该方法,除了旋转方法之外还应该放置哪种方法?

我已尝试将以下代码放入其中viewDidLoad,viewWillTransitionToSize但这会导致在iPad上运行时出现一些意外行为:

  • 以横向方式启动应用程序会导致约束处于活动状态,尽管事件active设置为false,它会破坏约束,并且UI不会按预期显示
  • 以纵向方式启动应用程序将活动设置为true(它已经安装在IB中),因此它按预期工作
  • 以纵向方式启动应用程序并将设备旋转到横向按预期工作 - 约束设置为非活动状态,它不会破坏约束,UI显示为预期
  • 以纵向方式启动应用程序,旋转到横向以及返回到纵向会导致UI显示正确,但它会破坏设置为活动的此约束

如果我在Interface Builder中卸载约束然后运行上面的场景我基本上会得到相反的行为.

if size.width > size.height {
    self.myConstraint.active = false
} else {
    self.myConstraint.active = true
}
Run Code Online (Sandbox Code Playgroud)

Özg*_*gür 0

我回答有点晚了,但当我遇到类似的问题来解决自动布局无法检测 iOS 7 的 iPhone 的紧凑宽度/紧凑高度的问题时,这是我的 2 美分。iOS 7 中没有activated属性,所以我必须添加/删除它们。

我创建了两种方法来添加和删除约束,并且这些约束已在 IB 上设置,并且我使用 IBOutlet 属性引用它们。因此,由于我删除了它们,与其他 IB 对象不同,我应该将它们设置为strong,而不是weak。否则,一旦我删除它们,它们就会被销毁,我将无法再次引用它们来重新添加它们。

这是我的约束去除方法:

-(void)removeiOS7andiPhone4inLandscapeToOrientation:(UIInterfaceOrientation)toInterfaceOrientation{

    if( !UIInterfaceOrientationIsLandscape(toInterfaceOrientation )&&(NSFoundationVersionNumber<=NSFoundationVersionNumber_iOS_7_1)&&( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone )){
         // if iPhone with iOS 7 on portrait remove Constraints here

    }
}
Run Code Online (Sandbox Code Playgroud)

这是约束加法器方法:

-(void)addiOS7andiPhone4inLandscapeToOrientation:(UIInterfaceOrientation)toInterfaceOrientation{

    if( UIInterfaceOrientationIsLandscape(toInterfaceOrientation )&&(NSFoundationVersionNumber<=NSFoundationVersionNumber_iOS_7_1)&&( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone )){
       // if iPhone with iOS 7 on landscape add Constraints here

    }

}
Run Code Online (Sandbox Code Playgroud)

至于在哪里调用这些方法,正如您尝试的那样,将它们都调用在viewWillAppear(无需调用viewWillDisappear)和viewWillTransitionToSize(在我的情况下是willRotateToInterfaceOrientation,因为viewWillTransitionToSize仅在iOS 8之后可用)。if随后调用它们是有意义的,毕竟在进行必要的更改之前,由于使用 检查它们的纵向/横向方向,因此只会运行其中一个。

这是我的willRotateToInterfaceOrientation方法定义:

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{

    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    // this will be run only if orientation is on Portrait
    [self addiOS7andiPhone4inLandscapeToOrientation:toInterfaceOrientation];

    // this will be run only if orientation is on Landscape
    [self removeiOS7andiPhone4inLandscapeToOrientation:toInterfaceOrientation];
}
Run Code Online (Sandbox Code Playgroud)

并在 中进行类似的调用viewWillAppear

注意:确保您在这些方法中执行完全相反的操作,并且不一定仅在 addConstraintMethod 中添加约束并仅在 removeConstraintMethod 中删除约束。就我而言,我在每个方法中添加和删除约束,因此方法的命名并不能准确反映它们的真正作用,但只要你做的事情完全相反,你就可以继续。