Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 添加视图、删除视图并再次添加视图将打破自动布局约束_Ios_Xcode_Swift_Uikit_Autolayout - Fatal编程技术网

Ios 添加视图、删除视图并再次添加视图将打破自动布局约束

Ios 添加视图、删除视图并再次添加视图将打破自动布局约束,ios,xcode,swift,uikit,autolayout,Ios,Xcode,Swift,Uikit,Autolayout,我有一个非常简单的方法,可以在两个视图之间进行交换。添加内容视图(带有.xib的UIViewController,其中包含一个带有自动布局约束的按钮)时,其布局良好,没有冲突约束。按下按钮可将该视图切换为另一个视图(同一类型视图的另一个实例),该视图也可以在没有冲突约束的情况下进行良好布局 当我再次交换视图以重新插入第一个视图(已存储且与先前删除的视图相同)时,iOS“无法同时满足约束”。每次交换第二个视图后,iOS都会发出相同的未满足约束的警告 显示视图控制器的代码: func display

我有一个非常简单的方法,可以在两个视图之间进行交换。添加内容视图(带有.xib的UIViewController,其中包含一个带有自动布局约束的按钮)时,其布局良好,没有冲突约束。按下按钮可将该视图切换为另一个视图(同一类型视图的另一个实例),该视图也可以在没有冲突约束的情况下进行良好布局

当我再次交换视图以重新插入第一个视图(已存储且与先前删除的视图相同)时,iOS“无法同时满足约束”。每次交换第二个视图后,iOS都会发出相同的未满足约束的警告

显示视图控制器的代码:

func displayController(controller:UIViewController) {

    self.addChildViewController(controller)
    controller.view.setTranslatesAutoresizingMaskIntoConstraints(false)
    controller.view.frame = CGRectMake(0.0, 0.0, self.view.bounds.width, self.view.bounds.height)
    self.view.addSubview(controller.view)

    self.view.addConstraint(NSLayoutConstraint(item: controller.view, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: 0))
    self.view.addConstraint(NSLayoutConstraint(item: controller.view, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Leading, multiplier: 1.0, constant: 0))
    self.view.addConstraint(NSLayoutConstraint(item: controller.view, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Width, multiplier: 1.0, constant: 0))
    self.view.addConstraint(NSLayoutConstraint(item: controller.view, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Height, multiplier: 1.0, constant: 0))

    controller.didMoveToParentViewController(self)
    self.currentViewController = controller;
}
删除视图控制器的代码

func hideController(controller:UIViewController) {

    controller.willMoveToParentViewController(nil)
    controller.view.removeFromSuperview()
    controller.removeFromParentViewController()

    if self.currentViewController == controller {

        self.currentViewController = nil
    }
}
交换视图的代码只调用这两种方法:

func switchToViewController(controller:UIViewController) {

    if self.currentViewController != nil {

        self.hideController(self.currentViewController!)
    }

    self.displayController(controller)
}
两个子视图控制器使用相同的.xib,并带有一个大按钮,该按钮在InterfaceBuilder中设置了约束

第一次添加和删除这些子视图时,它们显示良好,没有警告

一旦第一个视图被再次添加,按钮的高度就错误了,我会得到一个“无法同时满足约束”的警告

2015-02-23 21:40:17.223 Swift集装箱视图控制器[27976:832141]无法同时满足约束条件。
(
"",
"",
"",
"",
""
)

我相当肯定按钮上的约束是正确的,因为它们第一次正确布局,但在后续使用中会中断。

问题在于约束“UIView封装布局高度”。它是SDK出于未知原因添加的约束。这种情况很少发生,但当它发生时,我发现唯一的解决办法就是将我自己的一个约束条件的优先级设置为999。就你而言:

let heightConstraint = NSLayoutConstraint(item: controller.view, attribute: .Height, relatedBy: .Equal, toItem: self.view, attribute: .Height, multiplier: 1.0, constant: 0)
heightConstraint.priority = 999
self.view.addConstraint( heightConstraint)

SDK约束只是临时添加的,因此布局应按预期工作。

问题在于子视图控制器的高度是以多种方式定义的。这三条线很重要

"<NSLayoutConstraint:0x7fa57a71d1c0 V:[UIButton:0x7fa57a71bce0'Switch to Yellow View']-(413)-|   (Names: '|':UIView:0x7fa57a71cff0 )>",
日志如下所示:

"<NSLayoutConstraint:0x7fa57a41eed0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7fa57a715b40(667)]>"
“”
由于视图的高度不能同时为667pts和800pts,因此必须打破某些约束,并且您的界面显示不正确

要解决这个问题,我们需要重新考虑按钮周围的约束。答案是不要对按钮使用顶部和底部约束。而是定义按钮的宽度和高度,然后将按钮中心x和y与视图控制器中心x和y相匹配


请记住,如果需要从边到边(即从上到下或从前到后)链接(优先级1000)约束,这将定义superview的大小。最好只约束两条边以及宽度和高度,或者和父对象的相对点(例如中心)匹配

我打赌你的xib有800点高?iPhone6有667点高。错误是说它不能使800=667,但为什么它最初没有失败,我不能说。谢谢@lassej。这样做了。这可能已经解决了它,但这不是正确的答案。这只实现了放弃一个高度限制。子视图控制器视图的剪裁帧高度仍为800m@P-double。一旦我修正了限制,优先级设置就不再需要了。没问题。自动布局有时令人头痛:)
"<NSLayoutConstraint:0x7fa57a71d260 V:|-(262)-[UIButton:0x7fa57a71bce0'Switch to Yellow View']   (Names: '|':UIView:0x7fa57a71cff0 )>",
"<NSLayoutConstraint:0x7fa57a71d300 V:[UIButton:0x7fa57a71bce0'Switch to Yellow View'(125)]>",
self.view.addConstraint(NSLayoutConstraint(item: controller.view, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Height, multiplier: 1.0, constant: 0))
"<NSLayoutConstraint:0x7fa57a41eed0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7fa57a715b40(667)]>"