环境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。

07-24 09:38
查看更多