簡體   English   中英

未調用委托 function

[英]Delegate function not called

我有兩個視圖控制器( ViewControllerActionViewController )和一個管理器( 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.

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