gpt4 book ai didi

Swift 3 - 以编程方式创建标题栏约束

转载 作者:行者123 更新时间:2023-11-28 10:15:00 25 4
gpt4 key购买 nike

我正在使用 Swift 3、iOS 10、XCode 8.2。

在我的代码中,我需要创建一个 UIViewController以编程方式,因此也以编程方式指定其布局和内容。

@IBAction func testViewController() {

let detailViewController = UIViewController()
detailViewController.view.backgroundColor = UIColor.white

let titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = UIColor.blue
label.text = "Scan Results"
label.textAlignment = .center
label.font = UIFont.boldSystemFont(ofSize: 18)
label.textColor = UIColor.white
return label
}()

let titleConstraints: [NSLayoutConstraint] = [
NSLayoutConstraint(item: titleLabel, attribute: .left, relatedBy: .equal, toItem: self.view, attribute: .left, multiplier: 1, constant: 0),
NSLayoutConstraint(item: titleLabel, attribute: .right, relatedBy: .equal, toItem: self.view, attribute: .right, multiplier: 1, constant: 0),
NSLayoutConstraint(item: titleLabel, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1, constant: 0),
NSLayoutConstraint(item: titleLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 40)
]

detailViewController.view.addSubview(titleLabel)

detailViewController.view.addConstraints(titleConstraints)

self.navigationController?.pushViewController(detailViewController, animated: true)
}

在垂直 View 中(忽略所有其他垃圾;只关注蓝色标题栏):

enter image description here

但在水平 View 中:

enter image description here

要设置的正确约束是什么,以便它占据栏的整个宽度并且顶部没有多余的空间,因为状态栏在水平时消失了?

编辑

在@thexande 提出建议后,我确​​实得到了一个错误:

[LayoutConstraints] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x608000098100
UILabel:0x7fe35b60edc0'Scan Results'.left ==
UIView:0x7fe35b405c20.left (inactive)>
When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView(UIConstraintBasedLayout) _viewHierarchyUnpreparedForConstraint:] to debug. 2017-02-24 21:01:59.807 EOB-Reader[78109:10751346] * Assertion failure in -[UIView _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.6.21/NSLayoutConstraint_UIKitAdditions.m:649 2017-02-24 21:01:59.951 EOB-Reader[78109:10751346] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Impossible to set up layout with view hierarchy unprepared for constraint.'

我还在原来的帖子中更新了我的代码。

最佳答案

发生这种情况的原因是因为您正在使用框架。您根据屏幕的宽度计算了框架。你不需要框架,你可以使用自动布局来完成这一切。相反,您应该使用约束将标签固定到它的 super View 边界,并给它一个静态高度。例如:

lazy var titleConstraints: [NSLayoutConstraint] = [
NSLayoutConstraint(item: self.titleLabel, attribute: .left, relatedBy: .equal, toItem: self.view, attribute: .left, multiplier: 1, constant: 0),
NSLayoutConstraint(item: self.titleLabel, attribute: .right, relatedBy: .equal, toItem: self.view, attribute: .right, multiplier: 1, constant: 0),
NSLayoutConstraint(item: self.titleLabel, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1, constant: 0),
NSLayoutConstraint(item: self.titleLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 40)
]

然后,在viewDidLoad()中

self.view.addConstraints(titleConstraints)

您可以像这样简化您的标签声明。不要忘记自动调整大小掩码标志以使约束正常工作:

let titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = UIColor.blue
label.text = "Scan Results"
label.textAlignment = .center
label.textColor = UIColor.white
return label
}()

最后,您正在做奇怪的数学运算以使 View Controller 的顶部紧靠导航栏 Controller 的底部。删除所有垃圾并将以下内容放入 viewDidLoad() 中,以使 View Controller 的顶部紧靠 UINavigationBar 的底部:

self.edgesForExtendedLayout = []

更新:

这里的问题是您将 View 和约束附加到尚未分配的 View Controller 中。

我们在 viewDidLoad() 中附加 subview 和约束的原因是因为我们不能在 View ....did....加载到内存之前添加 subview 和约束。否则,它不存在,你会得到上面的错误。考虑将您的 detailViewController 分解为类声明,如下所示:

class detailViewController: UIViewController {
let eobTitleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = UIColor.blue
label.text = "Scan Results"
label.textAlignment = .center
label.font = UIFont.boldSystemFont(ofSize: 18)
label.textColor = UIColor.white
return label
}()

lazy var eobTitleConstraints: [NSLayoutConstraint] = [
NSLayoutConstraint(item: self.eobTitleLabel, attribute: .left, relatedBy: .equal, toItem: self.view, attribute: .left, multiplier: 1, constant: 0),
NSLayoutConstraint(item: self.eobTitleLabel, attribute: .right, relatedBy: .equal, toItem: self.view, attribute: .right, multiplier: 1, constant: 0),
NSLayoutConstraint(item: self.eobTitleLabel, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1, constant: 0),
NSLayoutConstraint(item: self.eobTitleLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 40)
]

override func viewDidLoad() {
self.view.addSubview(eobTitleLabel)
self.view.addConstraints(self.eobTitleConstraints)
}
}

此外,不要冒犯他人,但您的代码有点乱。以后应该避免的事情:

  1. 向不存在的标签添加约束。 (重命名修复约束的标签)
  2. 您在导出方法中声明变量。不要这样做,在类级别声明方法和属性。
  3. 了解 OOP 及其如何在 swift 中实现。这将帮助您了解完成任务的方法和模式:)

关于Swift 3 - 以编程方式创建标题栏约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42450034/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com