Swift: Изменить значение другого ViewController с делегированием программно - PullRequest
0 голосов
/ 15 февраля 2020

Я пытаюсь изменить значение одного 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")
    }
}

Пока каждый раз, когда я нажимаю кнопку, печатается только сообщение «нажата» и я даже не знаю, иду ли я в правильном направлении с моим подходом, пытаясь использовать делегирование.

Ответы [ 2 ]

0 голосов
/ 15 февраля 2020

Не следует создавать новый экземпляр ViewController каждый раз, когда вы вызываете ViewController2.addCreditsToCounter, у вас уже есть ViewController, который создает экземпляр ViewController2 в ViewController.changeView. Просто сохраните слабую ссылку на ViewController в ViewController2, используя делегат. В таком случае ViewController (не ViewController2) должно соответствовать AddCreditsDelegate. Прежде всего, замените

protocol AddCreditsDelegate {
    func addCreditsToCounter()
}

на

protocol AddCreditsDelegate: AnyObject {
    func addCreditsToCounter()
}

Затем добавьте weak var delegate: AddCreditsDelegate? к ViewController2 и удалите ViewController.delegate. Удалить ViewController2.addCreditsToCounter, ViewController2 не должно соответствовать 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 голосов
/ 15 февраля 2020

Вы создаете новый экземпляр здесь

  let vc = ViewController()

, вместо этого вам нужно

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

Затем объявите это внутри SecondV C

weak var delegate:ViewController?

Наконец

    func addCreditsToCounter() {  
        delegate?.counterView.creditPointValue += 5
        print("pressed")
    }
...