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



我正在尝试通过单击带有委派的第二个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")
}
}

我正在这个视图控制器中使用该视图,我想操作变量"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)
}
}

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

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

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

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

protocol AddCreditsDelegate {
func addCreditsToCounter()
}

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)

在此处创建新实例

let vc = ViewController()

相反,你需要

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

然后在第二VC中声明这一点

weak var delegate:ViewController?

最后

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

相关内容

最新更新