[英]Dismiss or remove previous modally presented view controller as soon as the next one appear modally
我的目標包括很多視圖需要根據每個用戶操作以模態方式呈現不同的視圖。 這就是我想要做的更清晰的視圖層次結構和更好的用戶體驗。
- Root View Controller以模態方式呈現First View Controller
- 當我單擊第一視圖控制器上的按鈕時,第二視圖控制器以模態方式顯示在它上面。
- 第二個視圖控制器出現后,我想從視圖層次結構中解除或刪除第一個視圖控制器。
我能這樣做嗎? 如果是這樣 ,我該怎么辦?
如果沒有 ,解決這個問題的正確方法是什么,我將在每個視圖上呈現許多模態呈現的視圖控制器。 我想即使我想要忽略當前的觀點,前一個觀點仍然會在當前觀點被忽略時出現。
更新:
VC1(Root)> VC 2(模態存在)> VC 3( 在VC 2上以模態存在)
當我關閉VC3
, VC2
仍然在視圖內存上。 因此,我不想在我解除VC3
立即出現VC2
,而是希望通過從視圖層次結構中刪除或解除VC2
來查看VC1
。
想要 :在圖像中,當我解雇藍色時,我不希望在我的視圖記憶中看到粉紅色,我想在藍色出現時立即將其刪除。
這就是我想要做的。
任何幫助?謝謝。
所以,我們假設你有一個類似於的故事板:
應該發生的是:
在第三個ViewController按鈕的動作中:
@IBAction func tapped(_ sender: Any) {
presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)
}
正如你所看到的,通過訪問presentingViewController當前視圖控制器,你可以關閉該視圖控制器以前的層次結構:
提供此視圖控制器的視圖控制器。
通過實現presentingViewController?.presentingViewController?
這意味着:呈現當前的ViewController :)
這看起來有點混亂,但很簡單。
所以輸出應該是這樣的(我為viewControllers添加了背景顏色-as vc1:orange,vc2:black和vc3:light orange-以使其顯得清晰):
編輯:
如果要求在中間刪除ViewController(在本例中為第二個ViewController),則dismiss(animated:completion :)會自動執行此操作:
如果連續呈現多個視圖控制器,從而構建一堆呈現的視圖控制器,則在堆棧中較低的視圖控制器上調用此方法會解除其直接子視圖控制器以及堆棧上該子視圖上方的所有視圖控制器。 發生這種情況時,只有最頂層的視圖以動畫方式被刪除; 任何中間視圖控制器都可以從堆棧中刪除。 最頂層的視圖使用其模態過渡樣式被忽略,這可能與堆棧中較低的其他視圖控制器使用的樣式不同。
參考你在問什么:
我想即使我想要忽略當前的觀點,前一個觀點仍然會在當前觀點被忽略時出現。
我認為在UI上顯而易見(我發現它沒問題),但正如在dismiss
文檔討論中所提到的,第三個和第二個都將從堆棧中刪除。 那是正確的方法。
你想要的是一個“放松segue”:
https://developer.apple.com/library/archive/technotes/tn2298/_index.html
它允許您同時關閉多個視圖控制器,而無需知道堆棧中有多少個。
在VC1中,您將實現一個名為(例如) unwindToRoot
的IBAction
。 然后在VC3的故事板中,將“完成”按鈕連接到“ Exit
對象,然后選擇unwindToRoot
操作。
按下該按鈕后,系統將關閉所需的所有視圖控制器,以便將您帶回VC1。
這比調用presentingViewController?.presentingViewController?.dismiss()
更好,因為VC3不需要知道它下面的視圖控制器層次結構。
以下是我對不同角度的看法,
- Root View Controller提供第二視圖控制器
- 將FirstView添加到第二個視圖
- 按下按鈕時關閉FirstView控制器。
第二視圖控制器,
class ViewController: UIViewController, FirstViewControllerProtocol {
weak var firstViewController: FirstViewController?
override func viewDidLoad() {
super.viewDidLoad()
print("Not initiated: \(firstViewController)")
firstViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "FirstViewController") as? FirstViewController
addChildViewController(firstVC!)
firstViewController?.delegate = self
view.addSubview((firstViewController?.view)!)
print("Initiated: \(firstViewController)")
}
func dismiss() {
firstViewController?.view.removeFromSuperview()
firstViewController?.removeFromParentViewController()
}
}
FirstViewController,
protocol FirstViewControllerProtocol {
// Use protocol/delegate to communicate within two view controllers
func dismiss()
}
class FirstViewController: UIViewController {
var delegate: FirstViewControllerProtocol?
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func dismiss(_ sender: Any) {
delegate?.dismiss()
}
deinit {
print("BYE")
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.