在 UITabView 中切换选项卡时,视图控制器与 IBOutlets 中的约束失去连接
Posted
技术标签:
【中文标题】在 UITabView 中切换选项卡时,视图控制器与 IBOutlets 中的约束失去连接【英文标题】:View Controller loses connection to constraints in IBOutlets when switching tabs in UITabView 【发布时间】:2020-11-04 19:36:46 【问题描述】:好的,这是我的代码的相关部分:
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
我正在构建一个问答类型的应用程序,并且出于设计原因,两个子视图的大小不同。我设置了它,以便它根据当前状态在两个子视图之间切换(当用户点击前进时切换回新问题),它工作正常......
...直到我转到 UITabView
上包含所有内容的不同选项卡(例如,更改设置然后恢复测试)
标签更改的那一刻,就像NSLayoutConstraint
出口不再存在。更改它们的命令仍在处理中(我已在控制台中验证了这一点),但它们什么也不做。
QuestionView
的高度以匹配tableView
的新顶部位置,而不是移动@ 987654326@ 到 QuestionView
的底部,如预期的那样)
我已经尝试实现UITabViewController
,这样我就可以调用tabBar(_:didSelect:)
,并在我切换回该选项卡时用MyViewController()
的全新实例替换视图控制器(它第一次加载,但是当我尝试切换选项卡时,它会在访问任何IBOutlet
s 时找到nil
...即使我没有点击测试视图的选项卡并在替换现有视图时由item.tag
过滤控制器)
关于如何解决这个问题的任何建议?
【问题讨论】:
"这是我的代码的相关部分" ...您可能认为这是相关部分,但事实并非如此。您还没有在其他任何地方展示您可能正在做的任何事情(例如在viewDidAppear()
?)。使用标签栏控制器和两个视图控制器开始一个新项目。在第一个中,添加一个视图和一个按钮,将视图的顶部约束连接到@IBOutlet
s,只需要测试它的最少代码。
回到选项卡后只需更新约束
顺便说一句...@IBOutlet weak var tableViewTopAlternateConstraint: NSLayoutConstraint! // Inactive at start
---它是如何“在开始时不活动”的?
@DonMag 如果您在 Interface Builder 中选择了非活动约束,则未选中“已安装”复选框。因此,两个约束中的第一个是唯一有效的约束(并且 IB 不会记录它们之间的冲突,即使 tableView
否则会有两个冲突的值)。
@Kaji - 取消选中“已安装”意味着 “不要在运行时安装此约束”...这显然不是您想要的。
【参考方案1】:
首先,不要将@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
【讨论】:
感谢您的见解!我正在处理的程序仍然存在问题,但是我从一个新项目中的新构建开始,并内置了所有讨论过的组件,并且概念验证工作正常。基于此,我对此进行了复选标记,并可能会看到将我的代码移植到概念验证应用程序设置中,以查看我是否可以确定潜在的问题。以上是关于在 UITabView 中切换选项卡时,视图控制器与 IBOutlets 中的约束失去连接的主要内容,如果未能解决你的问题,请参考以下文章
切换选项卡时未调用 NSFetchedResultsControllerDelegate 方法
IllegalArgumentException:快速切换 ActionBar 选项卡时没有找到片段 id 的视图