在我的应用程序中,我希望在主视图控制器中存储多个容器视图。从那里我希望能够从主视图控制器和容器视图修改容器视图的约束。
我制作了一个简单的Xcode项目并制作了一个示例GIF,展示了我希望能够做到的事情。
"重置"按钮存储在我的主视图控制器的容器视图中。容器视图使用约束垂直和水平居中。 " Up"," Right"," Down"和" Left"按钮修改容器视图的现有约束。我希望能够使用"重置"修改容器视图的约束。容器视图内的按钮。
每次我尝试从容器视图中访问/修改存储在主视图控制器中的约束IBOutlets时,它会崩溃说"致命错误:意外地发现nil"。
实现此功能的最佳方法是什么?我全神贯注于你的建议。
提前致谢。
ViewController.swift(主视图控制器)
class ViewController: UIViewController {
@IBOutlet weak var ContainerViewVerticalConstraint: NSLayoutConstraint!
@IBOutlet weak var ContainerViewHorizontalConstraint: NSLayoutConstraint!
@IBAction func upButtonPressed(_ sender: Any) {
ContainerViewVerticalConstraint.constant = -100
}
@IBAction func rightButtonPressed(_ sender: Any) {
ContainerViewHorizontalConstraint.constant = 50
}
@IBAction func downButtonPressed(_ sender: Any) {
ContainerViewVerticalConstraint.constant = 100
}
@IBAction func leftButtonPressed(_ sender: Any) {
ContainerViewHorizontalConstraint.constant = -50
}
}
ContainerViewController.swift(容器视图)
class ContainerViewController: UIViewController {
@IBAction func resetButtonPressed(_ sender: Any) {
// Modify the constraints of the container view when this button is pressed
}
}
答案 0 :(得分:3)
容器视图嵌入了嵌入segue。您可以执行以下操作:
"embedResetView"
等标识符。在prepareForSegue
中,如果segue.identifier
为"embedResetView"
,则将两个约束传递给目标(重置)视图中的属性。约束是对象,因此它们通过引用传递。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "embedResetView" {
if let dvc = segue.destination as? ContainerViewController {
dvc.horizontalConstraint = ContainerViewHorizontalConstraint
dvc.verticalConstraint = ContainerViewVerticalConstraint
}
}
}
按下reset
按钮后,修改这些约束中的constant
属性。
class ContainerViewController: UIViewController {
weak var horizontalConstraint: NSLayoutConstraint?
weak var verticalConstraint: NSLayoutConstraint?
@IBAction func resetButtonPressed(_ sender: Any) {
horizontalConstraint?.constant = 0
verticalConstraint?.constant = 0
}
}
答案 1 :(得分:2)
您可以使用委托模式在视图控制器之间传递事件或数据。
首先,您应该在ContainerViewController中创建一个协议:
protocol ContainerViewControllerDelegate: class {
func containerControllerDidRequestViewReset()
}
之后,将一个委托属性添加到ContainerViewController:
weak var delegate: ContainerViewControllerDelegate?
在您的重置按钮功能中,调用协议方法:
@IBAction func resetButtonPressed(_ sender: Any) {
// Modify the constraints of the container view when this button is pressed
delegate?.containerControllerDidRequestViewReset()
}
然后,导航到您的Storyboard文件并从ViewController向ContainerViewController添加标识符,例如" ToContainerViewSegueID"。 在您的主ViewController类中实现以下方法:
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ToContainerViewSegueID" {
if let containerVC = segue.destination as? ContainerViewController {
containerVC.delegate = self
}
}
}
之后,您应该将ContainerViewControllerDelegate实现到主ViewController类中。例如,您可以使用相同的文件中的扩展名来执行此操作:
class ViewController: UIViewController {
//your code goes here
}
extension ViewController: ContainerViewControllerDelegate {
func containerControllerDidRequestViewReset() {
//here is a good place to reset your constraints values
ContainerViewVerticalConstraint.constant = 0
ContainerViewHorizontalConstraint.constant = 0
}
}