2017-06-13 64 views
0

我已更改標籤中帶有「••••••••••••••」的secureTextEntry = true中的字符串。它的工作原理是完美的,但我怎麼能改變整個字符串,除了字符串中的最後4個字符?secureTextEntry單獨部分 - swift

+0

所以,你希望所有的字符爲「•」,除了最後4 –

+0

是嗎?將字符串應用於UILabel或UITextField? – murphguy

回答

1

這裏的情況將取決於你如何使用這個字符串:在一個UILabel,或爲UITextField。無論哪種方式,這裏的最好的事情是通過擴展字符串做如下所示:

extension String { 

    init(withSecureShowOnlyLast4 values : String) { 
     self.init() 
     let array = [Character](values.characters) 
     if array.count <= 4 { 
      self = values 
     } else { 
      var first = array.count - 4 
      var lastFour : [Character] = [] 
      while first <= (array.count - 1) { 
       lastFour.append(array[first]) 
       first += 1 
      } 
      self = String(Array(repeating: "•", count: array.count - 4) + lastFour) 
     } 
    } 

} 



let pass : String = "fesnjufodpsk" 

let obfs = String(withSecureShowOnlyLast4: pass) //prints : ••••••••dpsk 

根據您需要這個,這是我怎麼會使用它:

的UILabel:

這是一個自定義類,以確保您想要的數據安全保存。

class SafeLabel : UILabel { 

    var makeSafe : Bool = false 
    private var safeKey : String? 
    private var alternateSet = Bool() 

    override var text: String? { 
     didSet { 
      if makeSafe && !alternateSet { 
       alternateSet = true 
       safeKey = text 
       self.text = nil 
      } else if alternateSet { 
       alternateSet = false 
      } 
     } 

     willSet { 
      if makeSafe && !alternateSet { 
       self.safeKey = text 
      } 
     } 
    } 

    var safe : String { 
     get { 
      guard let sa = safeKey else { 
       return "" 
      } 
      guard makeSafe else { 
       return sa 
      } 
      return String(withSecureShowOnlyLast4: sa) 
     } 
    } 
} 
let lab = SafeLabel() 

lab.makeSafe = true 

lab.text = "9j3od3dkuhosfg" 

print(lab.safe) //prints ••••••••••osfg 

請注意使用.makeSafe,它可以一起刪除打印和使用數據(不刪除它們)。

爲UITextField:

對於這個類我會用textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool方法來修改字符串。在這裏,我會繼承TextField的像這樣,並更改了保護線是這樣的:很顯然這裏

class SafeField : UITextField { 

    var makeSafe : Bool = false 
    private var safeKey : String? 
    private var alternateSet = Bool() 

    override var text: String? { 
     didSet { 
      if makeSafe && !alternateSet { 
       alternateSet = true 
       safeKey = text 
       self.text = nil 
      } else if alternateSet { 
       alternateSet = false 
      } 
     } 

     willSet { 
      guard text != nil else { 
       if let t = safeKey, t.characters.count == 1 || t.isEmpty { 
        self.safeKey = nil 
       } else { 
        isDeletingEntry() 
       } 
       return 
      } 
      if makeSafe && !alternateSet, let t = text { 
       if let s = safeKey { 
        self.safeKey = s + t 
       } else { 
        self.safeKey = t 
       } 
      } 
     } 
    } 

    var safe : String { 
     get { 
      guard let sa = safeKey else { 
       return "" 
      } 
      guard makeSafe else { 
       return sa 
      } 
      return String(withSecureShowOnlyLast4: sa) 
     } 
    } 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
    } 

    private func isDeletingEntry() { 
     if let old = safeKey { 
      let new = String(old.characters.dropLast()) 
      self.text = new 
     } 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
} 


class View: UIView, UITextFieldDelegate { 
    //Of course, this can be a ViewController, or anything that can handle the 
    //code bellow 
    var safe : SafeField = { 
     var s = SafeField() 
     s.makeSafe = true 
     return s 
    }() 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     addSubview(safe) 
     safe.frame = .zero 
     safe.delegate = self 
    } 

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 

     guard safe != textField else { 

      if string.characters.isEmpty { 
       safe.text = nil 
      } else { 
       safe.text = string 
      } 

      return false 
     } 

     return true 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

} 

你需要檢索因爲text的值時,總是硬編碼nil使用的safe代替text,我認爲這不應該成爲一個問題,因爲混淆的標籤在UI開發中總是少數。要從TextField獲取值,您需要將makeSafe變量設置爲false,以便檢索字符串的未混淆值。以安全性作爲主要關注點,這裏的優勢在於,您可以設置代碼,以根據需要設置和取消設置makeSafe變量,而無需擔心某些內容或某人直接從其他文件訪問它的值。

當然,如果您使用鍵盤元素或某種協議直接修改UILabel,只需將SafeLabel的文本變量替換爲SafeField中的文本變量即可。 (如果您使用的定製協議,一定要檢查標籤確實是一個SafeLabel通過可選的澆鑄:

func protocolMethod(label: UILabel, doSomething: Bool) { 
     guard let lab = label as? SafeLabel else { 
     //do your stuff 
     return 
     } 
    //Here you can manipulate lab as a SafeLabel and modify it according to the SafeLabel SubClass 
    } 
0

可以刪除label.isSecureTextEntry = true,而是使用:

var string = label.text! 
var result = String() 

if string.characters.count > 4{ 
    for i in 1...string.characters.count - 4{ 
     result += "•" 
    } 
    string = string[string.index(string.startIndex, offsetBy: string.characters.count-4)..<string.endIndex] 
    string = result + string 
} 

label.text = string