IvanPavliuk
IvanPavliuk

Reputation: 1800

How to create a new field in UITextField extension?

I am new to Swift and maybe it's a stupid question, but I can't find an answer to it.

I have created an extension:

extension UITextField {

  var placeholderLabel: UILabel {

    get {
      return self.placeholderLabel
    }

    set {
      self.placeholderLabel = newValue
    }

  }

}

When the property is set, the application crashes.

Upvotes: 0

Views: 1124

Answers (2)

Haim
Haim

Reputation: 570

You can use NSMapTable like this:

extension UITextField {

  private static var placeholderLabelMap: NSMapTable<UITextField, UILabel> = .weakToStrongObjects()
  
  var placeholderLabel: UILabel? {
    get {
      return UITextField.placeholderLabelMap.object(forKey: self)
    }
    set {
      UITextField.placeholderLabelMap.setObject(newValue, forKey: self)
    }
  }

}

The advantage of Sandeep's answer might be thread safety. You can see this Stack Overflow topic for comparison between the approaches.

Upvotes: 0

Sandeep Bhandari
Sandeep Bhandari

Reputation: 20379

You can't have a stored property in extension.

Extensions are not allowed to add a property to existing class because adding a property structure of the class will change. And because Objective C, Swift or any other programming language that am aware of could not afford it, it won't allow you to add the stored property to extension.

Isn't there any work around then ??

This is what you can do to save the label as stored property in your extension :)

import Foundation
import UIKit


fileprivate var ascociatedObjectPointer : UInt8 = 99

extension UITextField {
    var myLabel : UILabel {
        get {
            return objc_getAssociatedObject(self, &ascociatedObjectPointer) as! UILabel
        }
        set {
            objc_setAssociatedObject(self, &ascociatedObjectPointer, myLabel, .OBJC_ASSOCIATION_RETAIN)
        }
    }
}

How it works ??

Simple by writing setter and getter for the variable which you are posing or pretending to be stored property and by internally holding a pointer which has nothing to do with the existing class, hence it won't affect the structure of existing class.

Hope it helps.

Upvotes: 2

Related Questions