You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 3:从ViewController2修改ViewController1按钮标题不生效问题求助

Why Your Button Title Isn't Updating (And How to Fix It)

Hey there, let's break down what's going wrong here and get your button title updating properly!

The Root of the Problem

Take a look at this line in your ViewController2's dismissHandler:

dismiss(animated: true, completion:{ ViewController1().setButtonText() })

When you call ViewController1(), you're creating a brand new, completely separate instance of ViewController1—not referencing the one that's already displayed on your screen. This new instance never gets presented, so when you call setButtonText() on it, you're modifying a button that no one can see. That's why you only see changes when you re-show the original ViewController1 or trigger its internal buttons: you're finally interacting with the correct instance.

Fix 1: Use a Closure (Simple & Direct)

Closures are a clean way to pass a callback from ViewController2 back to the original ViewController1. Here's how to implement it:

Update ViewController2

Add a closure property to hold the callback, then call it when dismissing:

class ViewController2: UIViewController {
    // Add a closure to trigger the title update
    var onTitleSaved: (() -> Void)?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        newTitleTextField.placeholder = "Set New Title"
        dismissButton.setTitle("Save and Dismiss", for: .normal)
        dismissButton.addTarget(self, action: #selector(dismissHandler), for: .touchUpInside)
    }
    
    @objc func dismissHandler(){
        // First update your Title.buttonA with the text field input
        Title.buttonA = newTitleTextField.text ?? ""
        
        dismiss(animated: true) {
            // Call the closure to notify ViewController1 to update the button
            self.onTitleSaved?()
        }
    }
}

Update ViewController1

Pass the setButtonText method to the closure when presenting ViewController2:

class ViewController1: UIViewController {
    @IBOutlet weak var buttonA: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        buttonA.setTitle("FirstEdit", for: .normal)
        newViewController.addTarget(self, action: #selector(newVCHandler), for: .touchUpInside)
    }

    @objc func newVCHandler(){
        let vc2 = ViewController2()
        // Assign the closure to trigger our setButtonText method
        vc2.onTitleSaved = { [weak self] in
            self?.setButtonText()
        }
        present(vc2, animated: true, completion: nil)
    }

    func setButtonText(){
        buttonA.setTitle("\(Title.buttonA)", for: .normal)
    }
}

The [weak self] prevents a memory leak (since ViewController1 holds ViewController2, and the closure would otherwise hold ViewController1 in a cycle).

Fix 2: Use Delegation (Great for Complex Interactions)

If you need to pass more data or have multiple callbacks later, delegation is a standard iOS pattern:

Step 1: Define a Delegate Protocol

protocol ViewController2Delegate: AnyObject {
    func didFinishUpdatingTitle()
}

Step 2: Add Delegate Property to ViewController2

class ViewController2: UIViewController {
    weak var delegate: ViewController2Delegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // ... existing viewDidLoad code
    }
    
    @objc func dismissHandler(){
        Title.buttonA = newTitleTextField.text ?? ""
        dismiss(animated: true) {
            self.delegate?.didFinishUpdatingTitle()
        }
    }
}

Step 3: Conform ViewController1 to the Delegate

class ViewController1: UIViewController, ViewController2Delegate {
    // ... existing code

    @objc func newVCHandler(){
        let vc2 = ViewController2()
        vc2.delegate = self
        present(vc2, animated: true, completion: nil)
    }

    // Implement the delegate method
    func didFinishUpdatingTitle() {
        setButtonText()
    }

    // ... existing setButtonText code
}

Why These Fixes Work

Both approaches ensure you're calling setButtonText() on the actual instance of ViewController1 that's displayed on screen, not a throwaway new instance. This way, the button title updates immediately when you dismiss ViewController2.

内容的提问来源于stack exchange,提问作者Skiddswarmik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:42:18