通过在iPad上打破约束来向UIAlertController结果添加视图

时间:2016-03-12 13:02:08

标签: ios swift autolayout uialertcontroller

我在UIAlertController内构建滑块,它实际上在iPhone上工作正常,但在iPad上给出了破坏约束错误,我在呈现之前将高度警报140作为约束。

这是我的代码:

let alertController = UIAlertController(title:"Title", message: "", preferredStyle: UIAlertControllerStyle.Alert)
let slider = UISlider(frame: CGRectMake(35, 50, 200, 20))
alertController.view.addSubview(slider)

let height:NSLayoutConstraint = NSLayoutConstraint(item: alertController.view, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 140)
alertController.view.addConstraint(height);

alertController.addAction(UIAlertAction(title: "close", style: UIAlertActionStyle.Cancel, handler: { (error) -> Void in

}))

self.presentViewController(alertController, animated: true, completion: nil)

错误:

Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7b555900 V:[_UIAlertControllerView:0x788d2a60'Title'(140)]>",
    "<NSLayoutConstraint:0x789db3f0 V:[_UIAlertControllerView:0x788d2a60'Title'(1024)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x789db3f0 V:[_UIAlertControllerView:0x788d2a60'Title'(1024)]>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

1 个答案:

答案 0 :(得分:0)

好的,我有一个答案,但你不会喜欢它

如果您执行以下操作(未添加任何约束):

print("Alert frame" + String(alertController.view.frame))
self.presentViewController(alertController, animated: true, completion: nil)

您将获得以下内容:

Alert frame(0.0, 0.0, 768.0, 1024.0)

恰好是纵向模式下iPad Air的宽度和高度。好吧,这显然不是视图的宽度和高度。让我们稍微修改一下代码。

self.presentViewController(alertController, animated: true)
{
    print("Alert frame" + String(alertController.view.frame))
}

这次我得到以下内容:

Alert frame(0.0, 0.0, 300.0, 85.5)

请注意我的标题中有两个“\ n \ n”。因此,让我们假设他们在呈现之前做了一些时髦的事情(记得Apple告诉我们这是一个不透明的类)。

所以让我们添加以下内容:

self.presentViewController(alertController, animated: true)
{
    let height:NSLayoutConstraint = NSLayoutConstraint(item: alertController.view,
                                            attribute: NSLayoutAttribute.Height,
                                            relatedBy: NSLayoutRelation.Equal,
                                            toItem: nil,
                                            attribute: NSLayoutAttribute.NotAnAttribute,
                                            multiplier: 1,
                                            constant: self.view.frame.height * 1.20)
    alertController.view.addConstraint(height);

}

现在,为了运气,我们的手指交叉,看看会发生什么。

Unable to simultaneously satisfy constraints.

对我而言,这表明苹果公司对iPad的限制并不在iPhone上。当我们投入高度约束时,我们已经建立了一种情况,其中内部约束代码试图解决两个冲突的命令。因此,它只能通过打破约束来实现。

我正在使用.ActionSheet,但我遇到了同样的问题。 Apple似乎没有对iPhone使用约束。如果您没有构建通用应用程序,那么您应该没问题。

然而,这很重要,Apple 可能会在未来对iPhone施加限制,这可能会导致同样的问题

底线是:

  

UIAlertController类旨在按原样使用,不支持子类化。此类的视图层次结构是私有的,不得修改。

对我而言,Apple应该更明确地说,“我们不支持修改根本不用。”我怀疑他们认为“原样”涵盖了它,但你可能已经看到(就像我一样)很多人都没有测试所有病例。

因此,我计划寻找支持iPhone和iPad的第三方版本(请参阅UIAlertController - add custom views to actionsheet - 这是一个类似的问题。

在iOS的临时版本中浪费我的时间是不值得的。