【问题标题】:Adding view to UIAlertController result by breaking constraint on iPad通过在 iPad 上打破约束将视图添加到 UIAlertController 结果
【发布时间】:2023-03-07 08:17:01
【问题描述】:

我在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.

【问题讨论】:

  • 我自己也遇到了同样的问题——就好像文档说“应该按原样使用”是最后的决定。唯一适用于两个平台的解决方案是在标题中添加“\n\n\n”。

标签: ios swift autolayout uialertcontroller


【解决方案1】:

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

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

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.

在我看来,这表明 Apple 对 iPad 有一些限制,而对 iPhone 没有。当我们折腾高度约束时,我们已经设置了内部约束代码试图解决两个冲突命令的情况。因此,它只能通过打破约束来做到这一点。

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

但是,这很重要,Apple将来可能会对 iPhone 施加限制,这可能会导致同样的问题

底线是这样的:

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

对我来说,Apple 应该更明确地说:“我们根本不支持修改。”我怀疑他们认为“原样”涵盖了它,但正如您可能已经看到(如我所见)的那样,许多人并未测试所有案例。

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

将我的时间浪费在可能会在 iOS 的临时版本中中断的事情上是不值得的。

【讨论】:

  • 我去看看^_^
  • 我正在提交一份错误报告,Apple 的文档确实需要澄清不应该(如零)尝试修改 UIAlertController(无论是否子类化)。这包括但不限于添加约束等。
  • 我想它应该是子类的,你可以想象一个 scrollView 并且你需要在其中添加东西,而不是自定义它,因为使用它。我猜这没什么问题!!
  • UIAlertController 不支持根据 Apple 文档进行子类化 - 理想情况下,您将创建自己的类,使其具有外观和感觉。但是您可以不使用 UIAlertController 作为基类。
  • 嗯实际上你是对的,我已经在苹果文档中检查过了。并且添加我自己的课程会更容易。
猜你喜欢
  • 2019-07-15
  • 2021-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多