[英]Delegate function not called
我有兩個視圖控制器( ViewController和ActionViewController )和一個管理器( Brain ),當用戶通過在 storyboard 中創建的顯示序列點擊按鈕時,會顯示第二個視圖 controller 並返回第一個視圖,我使用 self.dismiss在第二個視圖中 controller。
用戶在ActionViewController上輸入需要在ViewController中檢索的數字。 所以我創建了Brain來使用委托模式。
問題是ViewController中的委托 function 從未運行,我閱讀了其他 SO 答案,但沒有任何效果。 我使用 print 語句來知道代碼不再運行的位置,唯一沒有運行的塊是ViewController中的 didUpdatePrice
這是代碼
視圖控制器
class ViewController: UIViewController, BrainDelegate {
var brain = Brain()
@IBOutlet var scoreLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
brain.delegate = self
scoreLabel.layer.cornerRadius = 25
scoreLabel.layer.masksToBounds = true
}
func didUpdateScore(newScore: String) {
print("the new label is \(newScore)")
scoreLabel.text = newScore
}
}
動作視圖控制器
class ActionViewController: UIViewController {
var brain = Brain()
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func addButtonTapped(_ sender: Any) {
brain.newAction(actualScore: 0, newActionValue: 5, isPositive: true)
self.dismiss(animated: true)
}
}
腦
protocol BrainDelegate {
func didUpdateScore(newScore: String)
}
struct Brain {
var delegate: BrainDelegate?
func newAction(actualScore: Int, newActionValue: Int, isPositive: Bool) {
let newScore: Int
if isPositive {
newScore = actualScore + newActionValue
} else {
newScore = actualScore - newActionValue
}
print("the new score is \(newScore)")
delegate?.didUpdateScore(newScore: String(newScore))
}
}
首先,在Brain
上,您應該使用 class,而不是 struct。 那是因為當你使用 struct 時,將變量傳遞給另一個會復制,它不會使用相同的引用。 而 class 只會復制參考。
這意味着您的Brain
結構將丟失分配給.delegate = self
的委托
其次,您需要在第二個 viewController 和第一個上使用相同的實例。 像這樣:
在第一個 viewController
var brain = Brain()
// this one is the one that you will put your "brain.delegate = self"
在第二個 viewController 上,您需要將此變量從第一個 viewController 注入到第二個。 那就是在兩者上保持相同的實例。 這將使委托可調用。
要使用 storyboard 執行此操作,您將在第一個 ViewController 上執行此操作:
// this function should be called when the next viewController should open.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.destination) {
case let vc as MyViewController:
vc.brain = self.brain
default:
break
}
}
super.prepare(for: segue, sender: sender)
}
在第二個 viewController 中,使用:
var brain: Brain?
您根本不需要額外的Brain
類/結構,您可以通過簡單的協議和協議的默認擴展來實現它。
第 1 步: Select 您的節目轉場,並為 storyboard 中的節目提供標識符,如下所示
第 2 步:在您的 ViewController 中添加prepare(for segue
方法
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "testIdentifier" {
guard let destinationViewController = segue.destination as? ActionViewController else { return }
destinationViewController.delegate = self
}
}
第 3 步:在ActionViewController
中聲明一個名為delegate
的弱屬性
class ActionViewController: UIViewController {
weak var delegate: BrainDelegate? = nil
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func addButtonTapped(_ sender: Any) {
delegate?.newAction(actualScore: 0, newActionValue: 5, isPositive: true)
self.dismiss(animated: true)
}
}
第 4 步:將class
子句添加到您的BrainDelegate
(類綁定協議),以便您可以持有對委托的弱引用
protocol BrainDelegate: class {
func didUpdateScore(newScore: String)
func newAction(actualScore: Int, newActionValue: Int, isPositive: Bool)
}
第 5 步:
向BrainDelegate
添加默認擴展並提供newAction(actualScore:
extension BrainDelegate {
func newAction(actualScore: Int, newActionValue: Int, isPositive: Bool) {
let newScore: Int
if isPositive {
newScore = actualScore + newActionValue
} else {
newScore = actualScore - newActionValue
}
print("the new score is \(newScore)")
self.didUpdateScore(newScore: String(newScore))
}
}
第 6 步:在您的ActionViewController
中簡單地觸發委托方法
@IBAction func addButtonTapped(_ sender: Any) {
delegate?.newAction(actualScore: 0, newActionValue: 5, isPositive: true)
self.dismiss(animated: true)
}
這應該做的工作
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.