我正在尝试通过单击带有委派的第二个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.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)
在此处创建新实例
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")
}