Swift:以编程方式通过委派更改另一个 ViewController 的值
Swift: Change value of another ViewController with delegation programmatically
我正在尝试通过单击第二个 ViewController 中的一个按钮来更改一个 ViewController 的值。
但到目前为止,它只打印了一条消息,并没有改变值。
我有这个 class 我在其中定义了一个视图:
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")
}
}
到目前为止,每次我单击按钮时只打印消息 "pressed",我什至不知道我尝试使用委托的方法是否朝着正确的方向前进。
您在这里创建一个新实例
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")
}
您不应该在每次调用 ViewController2.addCreditsToCounter
时都创建一个新的 ViewController
实例,您已经有一个 ViewController
在 [=18= 中创建了一个 ViewController2
实例].只需使用委托在 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)
我正在尝试通过单击第二个 ViewController 中的一个按钮来更改一个 ViewController 的值。 但到目前为止,它只打印了一条消息,并没有改变值。
我有这个 class 我在其中定义了一个视图:
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")
}
}
到目前为止,每次我单击按钮时只打印消息 "pressed",我什至不知道我尝试使用委托的方法是否朝着正确的方向前进。
您在这里创建一个新实例
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")
}
您不应该在每次调用 ViewController2.addCreditsToCounter
时都创建一个新的 ViewController
实例,您已经有一个 ViewController
在 [=18= 中创建了一个 ViewController2
实例].只需使用委托在 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)