title: Making UITextField component with limited access
body: <p>I want to make a small SDK for Adding a credit card form. Idea is to make SDK so application can use TextField component from SDK but with limited access. For example, an application can enter text, change UI but I want to disable direct access to read text. I want to expose only the last 4 digits. The application shouldn't access secure data like all 16 digits of the card. I'm not sure how I can disable reading text property from UITextField in this case</p>
  <p>EDIT:</p>
  <p>Thanks Vadim and Bill for your answers</p>
  <p>Here is the code that I wrote based on your suggestions:</p>
  <pre><code>public protocol CreditCardInputProtocol {
      var lastFourDigits: String? { get }
      var binNumber: String? { get }
      var isCardValid: Bool { get }
  }
  
  class CreditCardTextField: UIView {
      
      private var textField = UITextField()
      
      public var textFieldBackgroudColor: UIColor = .clear
      
      public var bottomLineHeight: Float = 1
      public var bottomLineColor: UIColor = .gray
      
      public lazy var bottomLine: UIView = {
          let bottomView = UIView(frame: CGRect(x: 0, y: textField.frame.height, width: textField.frame.width, height: CGFloat(bottomLineHeight)))
          bottomView.backgroundColor = bottomLineColor
          
          return bottomView
      }()
      
      public lazy var font: UIFont = {
          guard let fontTmp = UIFont(name: &quot;HelveticaNeue&quot;, size: 14) else {
              return UIFont.systemFont(ofSize: 14)
          }
          return fontTmp
      }()
      
      public var isCardValid: Bool {
          if textField.text?.count == 16 {
              return true
          }
          return false
      }
      
      public var binNumber: String? {
          guard let text = textField.text,
                text.count &gt;= 6 else {
              return nil
          }
          return &quot;\(text.prefix(6))&quot;
      }
      
      public var lastFourDigits: String? {
          guard let text = textField.text,
                text.count == 16 else {
              return nil
          }
          return &quot;\(text.suffix(4))&quot;
      }
      
      public func configurateView(_ frame: CGRect) -&gt; UIView {
          textField = UITextField(frame: frame)
          textField.delegate = self
          textField.keyboardType = .numberPad
          textField.borderStyle = .none
          textField.backgroundColor = textFieldBackgroudColor
          textField.font = font
          textField.addSubview(bottomLine)
          
          return textField
      }
      
  }
  
  extension CreditCardTextField: UITextFieldDelegate {
      func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -&gt; Bool {
          
          if string.isBackSpaceCharacter {
              return true
          }else if textField.text?.count == 16 || !string.isNumber {
              return false
          }
          return true
      }
  }
  
  extension String {
      var isBackSpaceCharacter: Bool {
          if let char = self.cString(using: String.Encoding.utf8) {
              let isBackSpace = strcmp(char, &quot;\\b&quot;)
              if (isBackSpace == -92) {
                  return true
              }
          }
          return false
      }
      var isNumber: Bool {
          let aSet = NSCharacterSet(charactersIn:&quot;0123456789&quot;).inverted
          let compSepByCharInSet = self.components(separatedBy: aSet)
          let numberFiltered = compSepByCharInSet.joined(separator: &quot;&quot;)
          return self == numberFiltered
      }
  }
  </code></pre>
  <p>This is how it is called right now</p>
  <pre><code>class ViewController: UIViewController, CreditCardInputProtocol {
  
  var lastFourDigits: String?
  var binNumber: String?
  var isCardValid: Bool = false
  
  var cardField = CreditCardTextField()
  
  override func viewDidLoad() {
      super.viewDidLoad()
  
      cardField.bottomLineHeight = 0.5
      
      let tf = cardField.configurateView(CGRect(x: 100, y: 100, width: 150, height: 35))
      view.addSubview(tf)
      
  }
  </code></pre>
  <p>Do you have any suggestions on how to improve it?
  This part needs to be customized a lot. The application needs to have ability to change a lot of the UI stuff here. This class will also need to support card number, expiration date, and CVV. So there will be 3 types of text fields there with 3 different validation...</p>