在 UITabView 中切换选项卡时,View Controller 失去与 IBOutlets 约束的连接
View Controller loses connection to constraints in IBOutlets when switching tabs in UITabView
好的,下面是我的代码的相关部分:
class MyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var questionView: QuestionView!
@IBOutlet weak var answerView: AnswerView!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var tableViewTopConstraint: NSLayoutConstraint! // Active at start, attaches tableView.topAnchor to questionView.bottomAnchor
@IBOutlet weak var tableViewTopAlternateConstraint: NSLayoutConstraint! // Inactive at start, attaches tableView.topAnchor to answerView.bottomAnchor
func submitAnswer() {
tableViewTopConstraint.isActive = false
tableViewTopAlternateConstraint = true
}
func newQuestion() {
tableViewTopConstraint.isActive = true
tableViewTopAlternateConstraint = false
}
}
我正在构建 question/answer 类型的应用程序,由于设计原因,两个子视图的大小不同。我将其设置为根据当前状态在两个子视图之间切换(当用户点击前进时切换回新问题),并且工作正常...
...直到我转到 UITabView
上包含所有内容的不同选项卡(例如,更改设置然后恢复测试)
选项卡更改的那一刻,就好像 NSLayoutConstraint
网点不再存在一样。更改它们的命令仍在处理中(我已在控制台中验证了这一点),但它们什么也没做。
- 我已经尝试过将网点声明为强 (行为没有差异)
- 我已经删除了插座并在代码中管理它们 (它第一次工作,但后来它拉伸了较短的
QuestionView
的高度以匹配 tableView
' s 新的顶部位置,而不是按预期将 tableView
移动到 QuestionView
的底部)
- 我已经尝试实现
UITabViewController
以便我可以调用 tabBar(_:didSelect:)
并在我切换回该选项卡时用 MyViewController()
的全新实例替换视图控制器 (它是第一次加载,但是当我尝试切换选项卡时,它在访问任何 IBOutlet
时发现 nil
...即使我没有点击选项卡测试视图并在替换现有视图控制器时按 item.tag
过滤)
关于如何解决这个问题有什么建议吗?
首先,不要将 @IBOutlet
属性设置为 weak
。我知道这是默认设置,但它不正确。
如果你有这个:
@IBOutlet weak var tableViewTopAlternateConstraint: NSLayoutConstraint!
通过 Storyboard 连接到一个约束,你这样做:
tableViewTopAlternateConstraint.isActive = false
你只是移除了那个约束。
此外,如果您在 Storyboard 中有两个不同的 Top 约束,您应该会收到错误指示器,因为它们无法满足。
最好要么更改优先级,要么使用单个约束并更改 .constant
值。
因此,Storyboard 中的两个约束:
- 将“默认”约束设置为
Priority: High (750)
- 将“备用”约束设置为
PriorityL Low (250)
您的代码变为:
func submitAnswer() {
tableViewTopConstraint.priority = .defaultLow
tableViewTopAlternateConstraint.priority = .defaultHigh
}
func newQuestion() {
tableViewTopAlternateConstraint.priority = .defaultLow
tableViewTopConstraint.priority = .defaultHigh
}
好的,下面是我的代码的相关部分:
class MyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var questionView: QuestionView!
@IBOutlet weak var answerView: AnswerView!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var tableViewTopConstraint: NSLayoutConstraint! // Active at start, attaches tableView.topAnchor to questionView.bottomAnchor
@IBOutlet weak var tableViewTopAlternateConstraint: NSLayoutConstraint! // Inactive at start, attaches tableView.topAnchor to answerView.bottomAnchor
func submitAnswer() {
tableViewTopConstraint.isActive = false
tableViewTopAlternateConstraint = true
}
func newQuestion() {
tableViewTopConstraint.isActive = true
tableViewTopAlternateConstraint = false
}
}
我正在构建 question/answer 类型的应用程序,由于设计原因,两个子视图的大小不同。我将其设置为根据当前状态在两个子视图之间切换(当用户点击前进时切换回新问题),并且工作正常...
...直到我转到 UITabView
上包含所有内容的不同选项卡(例如,更改设置然后恢复测试)
选项卡更改的那一刻,就好像 NSLayoutConstraint
网点不再存在一样。更改它们的命令仍在处理中(我已在控制台中验证了这一点),但它们什么也没做。
- 我已经尝试过将网点声明为强 (行为没有差异)
- 我已经删除了插座并在代码中管理它们 (它第一次工作,但后来它拉伸了较短的
QuestionView
的高度以匹配tableView
' s 新的顶部位置,而不是按预期将tableView
移动到QuestionView
的底部) - 我已经尝试实现
UITabViewController
以便我可以调用tabBar(_:didSelect:)
并在我切换回该选项卡时用MyViewController()
的全新实例替换视图控制器 (它是第一次加载,但是当我尝试切换选项卡时,它在访问任何IBOutlet
时发现nil
...即使我没有点击选项卡测试视图并在替换现有视图控制器时按item.tag
过滤)
关于如何解决这个问题有什么建议吗?
首先,不要将 @IBOutlet
属性设置为 weak
。我知道这是默认设置,但它不正确。
如果你有这个:
@IBOutlet weak var tableViewTopAlternateConstraint: NSLayoutConstraint!
通过 Storyboard 连接到一个约束,你这样做:
tableViewTopAlternateConstraint.isActive = false
你只是移除了那个约束。
此外,如果您在 Storyboard 中有两个不同的 Top 约束,您应该会收到错误指示器,因为它们无法满足。
最好要么更改优先级,要么使用单个约束并更改 .constant
值。
因此,Storyboard 中的两个约束:
- 将“默认”约束设置为
Priority: High (750)
- 将“备用”约束设置为
PriorityL Low (250)
您的代码变为:
func submitAnswer() {
tableViewTopConstraint.priority = .defaultLow
tableViewTopAlternateConstraint.priority = .defaultHigh
}
func newQuestion() {
tableViewTopAlternateConstraint.priority = .defaultLow
tableViewTopConstraint.priority = .defaultHigh
}