簡體   English   中英

我應該如何訪問存儲在保存容器視圖的視圖控制器中的IBOutlet? (快速4)

[英]How should I access an IBOutlet stored in the view controller holding my container view? (Swift 4)

在我的應用程序中,我想在主視圖控制器中存儲多個容器視圖。 從那里我希望能夠從主視圖控制器和容器視圖中修改容器視圖的約束。

我做了一個簡單的Xcode項目,並制作了一個GIF示例,展示了我想做的事情。

模擬器GIF

故事板

“重置”按鈕存儲在我的主視圖控制器中的容器視圖中。 容器視圖使用約束垂直和水平居中。 “向上”,“向右”,“向下”和“向左”按鈕可修改容器視圖的現有約束。 我希望能夠使用容器視圖內的“重置”按鈕來修改容器視圖的約束。

每當我嘗試從容器視圖內部訪問/修改存儲在主視圖控制器中的約束IBOutlet時,它都會崩潰,並顯示“致命錯誤:意外發現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
    }
}

容器視圖嵌入有嵌入的序列。 您可以執行以下操作:

  1. 在“ 文檔大綱”中找到嵌入的序列,並為其賦予一個標識符,例如"embedResetView"
  2. 如果segue.identifier"embedResetView" ,則在prepareForSeguesegue.identifier兩個約束傳遞給目標(重置)視圖中的屬性。 約束是對象,因此它們通過引用傳遞。

     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 } } } 
  3. 當按下reset按鈕時,在這些約束條件中修改constant屬性。

     class ContainerViewController: UIViewController { weak var horizontalConstraint: NSLayoutConstraint? weak var verticalConstraint: NSLayoutConstraint? @IBAction func resetButtonPressed(_ sender: Any) { horizontalConstraint?.constant = 0 verticalConstraint?.constant = 0 } } 

您可以使用委托模式在視圖控制器之間傳遞事件或數據。

首先,您應該在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
        }
    }
}

之后,您應該在主ViewController類中實現ContainerViewControllerDelegate。 例如,您可以使用相同文件中的擴展名來執行此操作,如下所示:

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
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM