未调用委托函数

Delegate function not called

我有两个视图控制器(ViewControllerActionViewController)和一个管理器(Brain),当用户点击故事板中创建的显示转场的按钮并返回到第一个时,会显示第二个视图控制器,我在第二个视图中使用 self.dismiss控制器。

用户在 ActionViewController 中输入了需要在 ViewController 中检索的数字。所以我创建了 Brain 来使用委托模式。

问题是 ViewController 中的委托函数永远不会 运行,我阅读了其他 SO 答案,但没有任何效果。我使用 print 语句知道代码在哪里不再是 运行ning,唯一不是 运行ning 的块是 ViewController[= 中的 didUpdatePrice 13=]

这是代码

ViewController

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

动作ViewController


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 时,将变量传递给另一个将制作一个副本,它不会使用相同的引用。 class 只会复制引用。

这意味着您的 Brain 结构将失去在 .delegate = self

上分配的委托

其次,您需要在第二个 viewController 和第一个上使用相同的实例。像这样:

第一个viewController

var brain = Brain()
// this one is the one that you will put your "brain.delegate = self"

在第二个 viewController 上,您需要将这个变量从第一个 viewController 注入到第二个中。那就是在两者上保持相同的实例。这将使委托可调用。

要使用故事板执行此操作,您将在第一个 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 class/struct,你可以通过简单的协议和协议的默认扩展来实现。

第 1 步: Select 您的节目转场并在故事板中提供一个标识符,如下所示

第 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(Class 绑定协议)以便您可以对代表

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

这应该可以完成工作