问答APP中SnapKit约束配置与按钮数组添加问题排查
问答APP按钮约束异常的解决方案
嘿,我一眼就看出你问题出在哪了——你创建约束的时机完全错了!当你在类顶部定义answerButtonsConstraints数组的时候,answerButtons还是个空数组呢!你直接用self.answerButtons[0]和self.answerButtons[1]去创建约束,这两个按钮根本还没被实例化,更没添加到answerView的视图层级里,系统自然会抛出"约束锚点没有共同祖先"的异常。
下面是具体的修复步骤:
1. 先调整变量定义
把answerButtonsConstraints改成空数组,等按钮创建好再往里加约束:
private var answerButtons = [RoundedButton]() private var answerButtonsConstraints = [Constraint]() // 用SnapKit的Constraint类型声明空数组
2. 移到正确的时机创建约束
把原来写在answerButtonsConstraints里的约束代码,放到创建按钮的for循环之后——这时候按钮已经被实例化,并且添加到answerView里了,视图层级关系也建立好了:
for index in 0...1 { let button = RoundedButton() answerButtons.append(button) button.translatesAutoresizingMaskIntoConstraints = false answerView.addSubview(button) button.setTitle(index == 0 ? "Correct" : "Wrong", for: .normal) button.addTarget(self, action: #selector(answerButtonHandler), for: .touchUpInside) } // 现在可以安全创建约束了 answerButtonsConstraints.append( answerButtons[0].snp.makeConstraints { make in make.leading.trailing.top.equalTo(answerView) make.bottom.equalTo(answerButtons[1].snp.top).offset(-RightWrongQuizViewController.buttonPadding) make.height.width.equalTo(answerButtons[1]) } ) answerButtonsConstraints.append( answerButtons[1].snp.makeConstraints { make in make.leading.trailing.bottom.equalTo(answerView) } )
3. 给你的RoundedButton提个小优化
把圆角设置移到初始化方法里,避免每次draw都重复执行,性能更好:
class RoundedButton: UIButton { override init(frame: CGRect) { super.init(frame: frame) setupButtonStyle() } required init?(coder: NSCoder) { super.init(coder: coder) setupButtonStyle() } private func setupButtonStyle() { layer.cornerRadius = 5.0 layer.masksToBounds = true } }
再啰嗦两句为什么报错
在类的顶部直接初始化answerButtonsConstraints时,你的ViewController还在初始化阶段,answerButtons是空的,这时候访问answerButtons[0]本质上是数组越界,而且按钮还没被添加到answerView的视图树里,约束里的两个锚点(按钮和answerView)不属于同一个视图层级,系统就会抛出那个NSGenericException异常啦。
内容的提问来源于stack exchange,提问作者rb2030
相关产品推荐
相关产品推荐

