环境Xcode-8Swift-3iOS-10
Intent Germain的意图是将三个子视图添加到主视图中,以便它们从屏幕顶部开始依次相邻显示。
工作代码如果我只是添加一个子视图,它可以与以下代码一起使用(略有删节,添加了行号以供参考):
01: class ViewController: UIViewController, UITextFieldDelegate {
02: var textMatte: UIView!
03: override func viewDidLoad() {
04: super.viewDidLoad()
05: setupTextfieldMatte(inView: view)
06: }
07: func setupTextfieldMatte(inView: UIView) {
08: textMatte = UIView()
09: textMatte.backgroundColor = UIColor.lightGray
10: textMatte.translatesAutoresizingMaskIntoConstraints = false
11: inView.addSubview(textMatte)
12: let tmGuide = textMatte.layoutMarginsGuide
13: let inGuide = inView.layoutMarginsGuide
14: tmGuide.topAnchor.constraint(equalTo: inGuide.topAnchor, constant: 40).isActive = true
15: tmGuide.leadingAnchor.constraint(equalTo: inGuide.leadingAnchor, constant: 20).isActive = true
16: tmGuide.trailingAnchor.constraint(equalTo: inGuide.trailingAnchor, constant: -20).isActive = true
17: tmGuide.heightAnchor.constraint(equalToConstant: 40).isActive = true
18: }
19: //... other code ...
20: }
损坏的CodeI希望从约束步骤中分解创建步骤,以便进行“批处理”(并且因为还有更多的事情要做,因为最终这些子视图也将拥有自己的子视图...)。添加了相对行号,以便于进一步描述和(希望)您的回答:
01: class ViewController: UIViewController, UITextFieldDelegate {
02: var mattes = [UIView()]
03: override func viewDidLoad() {
04: super.viewDidLoad()
05: for (index, title) in ["A", "B", "C"].enumerated() { // genericized for posting
06: let v = createView(idx: index)
07: mattes.append(v)
08: view.addSubview(v)
09: }
10: _ = mattes.popLast() //from testing/debugging found that there was an extraneous entry in the array
11: addViewAnnotations(views: mattes, inView: self.view)
12: }
13: func createView(idx: Int) -> UIView {
14: let v = UIView()
15: v.backgroundColor = UIColor.lightGray
16: v.translatesAutoresizingMaskIntoConstraints = false
17: v.tag = idx
18: return v
19: }
20: func addViewAnnotations(views: [UIView], inView: UIView) {
21: let inGuide = inView.layoutMarginsGuide
22: for (index, v) in views.enumerated() {
23: let myGuide = v.layoutMarginsGuide
24: if index == 0 {
25: myGuide.topAnchor.constraint(equalTo: inGuide.topAnchor, constant: 40).isActive = true
*** //^^^ libc++abi.dylib: terminating with uncaught exception of type NSException
26: }
27: else {
28: myGuide.topAnchor.constraint(equalTo: views[index-1].layoutMarginsGuide.bottomAnchor, constant: 10).isActive = true
29: }
30: myGuide.leadingAnchor.constraint(equalTo: inGuide.leadingAnchor, constant: 20).isActive = true
31: myGuide.trailingAnchor.constraint(equalTo: inGuide.trailingAnchor, constant: -20).isActive = true
32: myGuide.heightAnchor.constraint(equalToConstant: 40).isActive = true
33: }
34: }
35: //... other code ...
36: }
该错误发生在第25行(该行下方的注释中的错误消息),并通过该行上下的
print
语句进行了验证。我没有看到其他错误/调试信息,我原以为它可能会在第28行中断,但是25(在“破损代码”中)与第14行(在工作代码中)相同。注意:如果我在该行的from中放入try
,则Xcode会告诉我:“'try'中未发生对throw函数的调用表达”我感觉这是在修改代码时经常出现的愚蠢的疏忽之一,但是我似乎无法发现问题的根源,所以我希望你们中的一个能够做到。
更新2016-10-16基于我添加的第一个注释中所述的修改,我对代码进行了更多处理,发现仅当尝试使[what is now]最后一个约束处于活动状态时,才会出现问题:
001: override func viewDidLoad() {
002: super.viewDidLoad()
003: for (index, title) in ["Small Blind", "Big Blind", "Ante"].enumerated() {
004: let v = createView(idx: index)
005: mattes.append(v)
006: view.addSubview(v)
007: let myGuide = v.layoutMarginsGuide
008: let inGuide = view.layoutMarginsGuide
009: myGuide.leadingAnchor.constraint(equalTo: inGuide.leadingAnchor, constant: 20 ).isActive = true
010: myGuide.trailingAnchor.constraint(equalTo: inGuide.trailingAnchor, constant: -20).isActive = true
011: myGuide.heightAnchor.constraint(equalToConstant: 40).isActive = true
012: if index == 0 {
013: myGuide.topAnchor.constraint(equalTo: inGuide.topAnchor, constant: 40).isActive = true
014: }
015: else {
016: let x = myGuide.topAnchor.constraint(equalTo: mattes[index-1].bottomAnchor, constant: 10)
017: x.isActive = true
//^^^ libc++abi.dylib: terminating with uncaught exception of type NSException
018: }
019: }
020: }
所有其他约束都没有问题。如果使用以下命令,这似乎并不重要:
mattes[index-1].bottomAnchor
mattes[index-1].layoutMarginsGuide.bottomAnchor
第一个计算为<NSLayoutYAxisAnchor:0x174076540 "UIView:0x100b0d380.bottom">
,第二个计算为<NSLayoutYAxisAnchor:0x174076c00 "UILayoutGuide:0x174191e00'UIViewLayoutMarginsGuide'.bottom">
(如果有关系?)如果我注释掉第017行,则代码会运行,但是当第一个矩形位于正确的位置时,其余两个则不是-它们与屏幕顶部齐平,而不是顶部指示器下方。所以-也许有更好的设置方法? 最佳答案
对异常的描述是什么?在添加约束之前,请确保将视图添加到其父视图(在同一视图层次结构中)。您不能在不同层次的视图之间创建约束。
在更新中,您将index-1
用作mattes
数组的索引,这可能是第一次出现异常的原因。
我不知道这是否会导致问题,但是我不会创建从一个视图的layoutMarginsGuide到超级视图的layoutMarginsGuide的约束。将该指南视为视图及其子视图。因此约束将是从子视图本身(而不是其边距)到超级视图的layoutMarginsGuide。