微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

未调用委托函数

如何解决未调用委托函数

我有两个视图控制器(ViewControllerActionViewController)和一个管理器(Brain),第二个视图控制器在用户访问时显示通过在情节提要中创建的显示转场点击按钮并返回到第一个,我在第二个视图控制器中使用了 self.dismiss。

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

问题是 ViewController 中的委托函数从未运行,我阅读了其他 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
    }
}

ActionViewController


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 和第一个上使用相同的实例。像这样:

在第一个视图控制器上

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 步:选择您的节目转场并在故事板中提供一个标识符,如下所示

enter image description here

第 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,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,isPositive: true)
        self.dismiss(animated: true)
}

这应该可以完成工作

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。