Guest2819
Guest2819

Reputation: 53

UIView IBOutlet not changing when change called from a different class

I have an XIB with a UILabel to it. I have referenced the UILabel to a UIView class that I have created. I can change the label using label.text = "hi" when initializing the view. When I try and call a change from another class it doesn't change the UILabel on screen (but if I print label.text it shows as what I set it to). I cannot make the UILabel load the text when initializing as the text could be changed by the user at any time. (switchText() is called from a UITableCell)

2nd class

class Second {
    func switchText() {
        let first = First()
        DispatchQueue.main.async {
            first.label.text = "bye"
        }
    }
}

1st class

class First: UIView {
    let kCONTENT_XIB_NAME = "First"
    
    @IBOutlet var label: UILabel!
    @IBOutlet var contentView: UIView!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
    
    func commonInit() {
        Bundle.main.loadNibNamed(kCONTENT_XIB_NAME, owner: self, options: nil)
        contentView.fixInView(self)
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
    }
}

Also, in my XIB I have my UIView hooked up to File's Owner and contentView inside my UIView class. My label outlet goes to file's owner and then to the UIView class where it is declared as label.

Upvotes: 0

Views: 153

Answers (1)

David Mempin
David Mempin

Reputation: 55

You are not really changing the text on your First() class. What your switchText() function does is create another reference of the class named First and then set the text of the label for that new reference.

let first = First()
DispatchQueue.main.async {
    first.label.text = "bye"
}

What you can do is make your switchText() function conform to a protocol then call it on your First() class through a delegate.

protocol SecondClassDelegate {
    func didSwitchText(editedText: String)
}

class Second {
    var delegate: SecondClassDelegate!

    func switchText() {
        delegate.didSwitchText("bye")
    }
}

Now you can add this to your First() class

class First: SecondClassDelegate {
    func didSwitchText(editedText: String) {
        label.text = editedText
    }
}

Just don't forget to set the delegate wherever you're setting your Second() class

let second = Second()
second.delegate = self

I suggest reading about this for a better understanding of delegates. https://www.appcoda.com/swift-delegate/

Upvotes: 1

Related Questions