2

I'm writing a protocol that has a readOnly label. I want to extend it and give it a default implementation where the conforming type is a UITextView.

Code:

protocol CountingView {

    var keyboardLabel : UILabel {get}   
}

extension CountingView where Self : UITextView {

    var keyboardLabel : UILabel {
        get {
            let label = UILabel()
            label.textColor = UIColor.white
            label.translatesAutoresizingMaskIntoConstraints = false

            return label
        }
        private (set) {
            keyboardLabel = newValue
        }
    }
}

However when I add the private before the set I get the following error.

Expected 'get', 'set', 'willSet', or 'didSet' keyword to start an accessor definition

I looked up other questions with this error but didn't find them related to mine.

mfaani
  • 33,269
  • 19
  • 164
  • 293
  • 2
    Extensions *cannot* add stored properties. Your setter will call itself recursively. Compare https://stackoverflow.com/questions/44063181/protocol-extension-in-swift-3. – Martin R May 22 '17 at 14:50
  • @MartinR ummm. OK. You mean the answers here are incorrect? – mfaani May 22 '17 at 14:53
  • Well, your *question* is how to make `private(set)` *compile.* The answers seem to be correct. My point is that even if you make it compile then your *implementation* of the setter `keyboardLabel = newValue` won't work as intended. – Martin R May 22 '17 at 14:54

2 Answers2

6

You just have the private in the wrong place:

private(set) var keyboardLabel : UILabel {
    get {
        let label = UILabel()
        label.textColor = UIColor.white
        label.translatesAutoresizingMaskIntoConstraints = false

        return label
    }
    set {
        keyboardLabel = newValue
    }
}
GetSwifty
  • 7,568
  • 1
  • 29
  • 46
0

Simply make your computed property private as this:

public private(set) var keyboardLabel : UILabel {
    get {
        let label = UILabel()
        label.textColor = UIColor.white
        label.translatesAutoresizingMaskIntoConstraints = false

        return label
    }

    set {
        keyboardLabel = newValue
    }
}
nayem
  • 7,285
  • 1
  • 33
  • 51
  • God, you create a new label object when calling the getter every time? – Itachi Sep 05 '21 at 09:48
  • @Itachi, it was not the question itself. There is better way of doing this. But the OP wanted to know how `private(set)` works in general. – nayem Sep 06 '21 at 04:52