我想實作的要求非常簡單和常見,但我無法讓它發揮作用。我的示例代碼盡可能簡短,并應實作以下目標:
- 啟動主視圖。
- 在主視圖上注冊一個觸摸事件。這將啟動子視圖。(此呼叫定義了一個函式,該函式應在完成后啟動。)
- 子視圖打開。這個子視圖有一個回傳按鈕。
- 按下此按鈕時,控制元件應回傳主視圖。
- 在主行程中,完成函式應該啟動。
- 在主行程中,執行子視圖呼叫(2)之后的陳述句。
但我得到的執行順序是這樣的:
- 預期的步驟 1(在主視圖開始時)
- 預期的第 2 步(在主選單中點擊后)
- 預期的步驟 3(在子視圖開始時)
- 預期的第 6 步(在陳述句呼叫子視圖之后)
- 預期的步驟 5(在完成引數的函式中)
- 預期步驟 4(按下回傳按鈕后)
第 3 步和第 4 步是用 self.present... 和 self.dismiss... 實作的,因為我需要在我的專案中以編程方式實作這些步驟(這比這個演示版本更復雜)。這些方法確實有效。我的問題只是執行順序。
如果這個問題的答案是等待和異步:不幸的是我不能使用它,因為我僅限于 Xcode 10 和 Swift 4。但我希望上面的問題也必須可以用舊方法解決。很可能我只是對這個程序缺乏基本的了解,因為我是這個開發平臺的新手。
現在我的 Swift 代碼。主視圖控制器代碼:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("Intended step 1 (at main view start)")
}
@IBAction func gotoSubView(_ sender: UITapGestureRecognizer) {
print("Intended step 2 (after tap in main)")
let nextViewController =
self.storyboard?.instantiateViewController(withIdentifier:
"SubViewController") as! SubViewController
self.present(nextViewController, animated:true,
completion:IntendedAfterReturn)
print("Intended step 6 (after statement calling subview)")
}
func IntendedAfterReturn() {
print("Intended step 5 (in function of completion. parameter)")
}
}
子視圖控制器代碼:
import UIKit
class SubViewController: UIViewController {
@IBOutlet weak var btnReturn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
print("Intended step 3 (at sub view start)")
}
@IBAction func backToMain(_ sender: UIButton) {
print("Intended step 4 (after return Button is pressed)")
self.dismiss(animated: true, completion: nil)
}
}
uj5u.com熱心網友回復:
該函式present(_:animated:completion:)不允許您提供在用戶關閉模式時運行的完成處理程式。當顯示模態的影片完成時(當呈現的模態完全在螢屏上時),它會呼叫完成處理程式。
您要么需要向您的第一個視圖控制器的 viewDidAppear 方法添加一個處理程式(加上邏輯來區分第一次被呼叫和用戶從子視圖控制器回傳)
或者您需要向子視圖控制器添加一個委托屬性,告訴呼叫者用戶已關閉子視圖控制器。(我推薦這種方法。使用 viewDidAppear 很脆弱。)
uj5u.com熱心網友回復:
鄧肯關于添加委托屬性的建議是讓我找到解決方案的正確答案。我想在這里分享上面問題中使用委托機制增強的代碼,以防它可以幫助遇到類似問題的人。為了理解委托/協議機制,我找到了 Sean Allen 的一個很棒的解釋視頻:https ://www.youtube.com/watch?v=DBWu6TnhLeY
現在又是代碼。主視圖控制器代碼:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("Intended step 1 (at main view start)")
}
@IBAction func gotoSubView(_ sender: UITapGestureRecognizer)
{
print("Intended step 2 (after tap in main)")
let nextViewController = self.storyboard?.instantiateViewController(withIdentifier: "SubViewController") as! SubViewController
nextViewController.selectionDelegate = self
self.present(nextViewController, animated:true, completion:nil)
}
}
extension ViewController: SubViewSelectionDelegate {
func IntendedAfterReturn(text: String) {
print("Intended step 5 (Text from subview is: \(text))")
}
func IntendedAfterReturnAlso(text: String) {
print("Intended step 6 (Text from subview is: \(text))")
}
}
子視圖控制器代碼:
import UIKit
protocol SubViewSelectionDelegate {
// Since we have only a primitive example here with 1 button, the function parameter would even not be necessary. But we include a parameter for demonstration.
func IntendedAfterReturn(text: String)
func IntendedAfterReturnAlso(text: String)
}
class SubViewController: UIViewController {
var selectionDelegate: SubViewSelectionDelegate!
@IBOutlet weak var btnReturn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
print("Intended step 3 (at sub view start)")
}
@IBAction func backToMain(_ sender: UIButton) {
print("Intended step 4 (after return Button is pressed)")
selectionDelegate.IntendedAfterReturn(text: "For first action after return button tap")
selectionDelegate.IntendedAfterReturnAlso(text: "For second action after return button tap")
self.dismiss(animated: true, completion: nil)
}
}
現在,當我運行程式時,輸出如下:
- 預期的步驟 1(在主視圖開始時)
- 預期的第 2 步(在主選單中點擊后)
- 預期的步驟 3(在子視圖開始時)
- 預期步驟 4(按下回傳按鈕后)
- 預期的步驟 5(子視圖中的文本是:對于回傳按鈕點擊后的第一個操作)
- 預期的步驟 6(子視圖中的文本是:對于回傳按鈕點擊后的第二個操作)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/415455.html
標籤:
