Swift:通过编程方式更改另一个ViewController的值

问题描述 投票:0回答:2

我正在尝试通过委派第二个ViewController中的按钮来更改一个ViewController的值。但是到目前为止,它仅显示一条消息,而不会更改该值。

我在定义视图的这个类中:

class CounterView: UIView {

    public var creditPointValue = Int()

    let label = UILabel()


    override init(frame: CGRect) {
        super.init(frame: frame)
        self.translatesAutoresizingMaskIntoConstraints = false
        backgroundColor = .cyan

        self.addSubview(label)
        label.text = "Credit Points: \(creditPointValue)"
        label.translatesAutoresizingMaskIntoConstraints = false;
        label.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        label.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true

    }

    func changeCreditPointValue(value:Int){
        creditPointValue = creditPointValue + value
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

我正在此ViewController中使用该视图,并且要操作变量“ creditPointValue”:

protocol AddCreditsDelegate {
    func addCreditsToCounter()
}

class ViewController: UIViewController {

    var delegate: AddCreditsDelegate?

    var counterView = CounterView()

    let label = UILabel()

    let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        view.backgroundColor = .white

        view.addSubview(button)
        button.backgroundColor = .red
        button.setTitle("View2", for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.addTarget(self, action: #selector(changeView), for: .touchUpInside)
        button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }

    override func viewDidAppear(_ animated: Bool) {
        view.addSubview(counterView)
        counterView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        counterView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        counterView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        //counterView.frame.size.height = 30
        counterView.bottomAnchor.constraint(equalTo: counterView.topAnchor, constant: 50).isActive = true


    }

    @objc func changeView(){
        delegate?.addCreditsToCounter()
        navigationController?.pushViewController(ViewController2(), animated: true)
    }
}

在第二个ViewController中,我试图通过单击添加到视图的按钮来更改值:

class ViewController2: UIViewController {

    let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        view.addSubview(button)
               button.backgroundColor = .red
               button.setTitle("add Credits", for: .normal)
               button.translatesAutoresizingMaskIntoConstraints = false
               button.addTarget(self, action: #selector(addCreditsButton), for: .touchUpInside)
               button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
               button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }

    @objc func addCreditsButton(){
        addCreditsToCounter()
    }    
}

extension ViewController2 : AddCreditsDelegate{
    func addCreditsToCounter() {
        let vc = ViewController()
        vc.delegate = self
        vc.counterView.creditPointValue += 5
        print("pressed")
    }
}

到目前为止,每次单击按钮时,只有“按下”的消息会打印出来,我什至不知道我尝试使用委派的方法是否朝着正确的方向前进。

ios swift swift-protocols
2个回答
0
投票

[每次调用ViewController时都不应该创建新的ViewController2.addCreditsToCounter实例,您已经具有在ViewController中创建ViewController2实例的ViewController.changeView。只需使用委托在ViewController中存储对ViewController2的弱引用。在这种情况下,ViewController(不是ViewController2)应符合AddCreditsDelegate。首先,替换

protocol AddCreditsDelegate {
    func addCreditsToCounter()
}

with

protocol AddCreditsDelegate: AnyObject {
    func addCreditsToCounter()
}

然后将weak var delegate: AddCreditsDelegate?添加到ViewController2并删除ViewController.delegate。删除ViewController2.addCreditsToCounterViewController2应该不符合AddCreditsDelegate。这意味着在ViewController2.addCreditsButton中,您应该调用delegate?.addCreditsToCounter(),而不是addCreditsToCounter()

[ViewController应该符合AddCreditsDelegate

extension ViewController: AddCreditsDelegate {
    func addCreditsToCounter() {
        counterView.creditPointValue += 5
        print("pressed")
    }
}

并且不要忘记初始化ViewController2.delegate。将您的ViewController.changeView实现替换为

let controller = ViewController2()
controller.delegate = self
navigationController?.pushViewController(controller, animated: true)

0
投票

您在此处创建新实例

  let vc = ViewController()

代替您需要

@objc func changeView() {  
 let sec = ViewController2(),
 sec.delegate = self
 navigationController?.pushViewController( animated: true)
}

然后在SecondVC中声明此内容

weak var delegate:ViewController?

最后

    func addCreditsToCounter() {  
        delegate?.counterView.creditPointValue += 5
        print("pressed")
    }
© www.soinside.com 2019 - 2024. All rights reserved.