mirror of
https://github.com/zhigang1992/ParkedTextField.git
synced 2026-04-24 04:15:28 +08:00
Fix compilation for Swift 3 on Xcode 9
This commit is contained in:
@@ -9,9 +9,9 @@
|
||||
import UIKit
|
||||
|
||||
open class ParkedTextField: UITextField {
|
||||
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
|
||||
/// Constant part of the text. Defaults to "".
|
||||
@IBInspectable open var parkedText: String {
|
||||
get {
|
||||
@@ -24,7 +24,7 @@ open class ParkedTextField: UITextField {
|
||||
if !text.isEmpty {
|
||||
let typed = text[text.startIndex..<text.characters.index(text.endIndex, offsetBy: -self.parkedText.characters.count)]
|
||||
text = typed + newValue
|
||||
|
||||
|
||||
prevText = text
|
||||
_parkedText = newValue
|
||||
|
||||
@@ -32,13 +32,13 @@ open class ParkedTextField: UITextField {
|
||||
} else {
|
||||
_parkedText = newValue
|
||||
}
|
||||
|
||||
|
||||
// Force update placeholder to get the new value of parkedText
|
||||
placeholder = placeholderText + parkedText
|
||||
}
|
||||
}
|
||||
var _parkedText = ""
|
||||
|
||||
|
||||
/// Variable part of the text. Defaults to "".
|
||||
@IBInspectable open var typedText: String {
|
||||
get {
|
||||
@@ -56,29 +56,29 @@ open class ParkedTextField: UITextField {
|
||||
textChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Placeholder before parkedText. Defaults to "".
|
||||
@IBInspectable open var placeholderText: String = "" {
|
||||
didSet {
|
||||
placeholder = placeholderText + parkedText
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// Constant part of the text. Defaults to the text field's font.
|
||||
open var parkedTextFont: UIFont! {
|
||||
didSet {
|
||||
parkedText += ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Constant part of the text. Defaults to the text field's textColor.
|
||||
@IBInspectable open var parkedTextColor: UIColor! {
|
||||
didSet {
|
||||
parkedText += ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Attributes wrapper for font and color of parkedText
|
||||
var parkedTextAttributes: [String: NSObject] {
|
||||
return [
|
||||
@@ -86,7 +86,7 @@ open class ParkedTextField: UITextField {
|
||||
NSForegroundColorAttributeName: parkedTextColor ?? textColor!
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
open override var placeholder: String? {
|
||||
didSet {
|
||||
if let placeholder = placeholder {
|
||||
@@ -99,33 +99,33 @@ open class ParkedTextField: UITextField {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum TypingState {
|
||||
case start, typed
|
||||
}
|
||||
var typingState = TypingState.start
|
||||
|
||||
|
||||
var beginningOfParkedText: UITextPosition? {
|
||||
get {
|
||||
return position(from: endOfDocument, offset: -parkedText.characters.count)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var prevText = ""
|
||||
|
||||
|
||||
|
||||
|
||||
// MARK: Initialization
|
||||
|
||||
|
||||
public required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
commonInit()
|
||||
}
|
||||
|
||||
|
||||
func commonInit() {
|
||||
|
||||
if let boldFont = font {
|
||||
@@ -133,20 +133,20 @@ open class ParkedTextField: UITextField {
|
||||
} else {
|
||||
parkedTextFont = font
|
||||
}
|
||||
|
||||
|
||||
parkedTextColor = textColor
|
||||
|
||||
|
||||
addTarget(self, action: #selector(ParkedTextField.textChanged(_:)), for: .editingChanged)
|
||||
|
||||
|
||||
text = ""
|
||||
prevText = text!
|
||||
|
||||
|
||||
typingState = .start
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// MARK: EditingChanged handler
|
||||
|
||||
|
||||
func textChanged(_ sender: UITextField) {
|
||||
switch typingState {
|
||||
case .start where text!.characters.count > 0:
|
||||
@@ -154,63 +154,64 @@ open class ParkedTextField: UITextField {
|
||||
updateAttributedTextWith(text!)
|
||||
prevText = text!
|
||||
goToBeginningOfParkedText()
|
||||
|
||||
|
||||
typingState = .typed
|
||||
|
||||
|
||||
case .typed:
|
||||
if text == parkedText {
|
||||
typingState = .start
|
||||
text = ""
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// If the parkedText has changed, don't update prevText.
|
||||
if text!.hasSuffix(parkedText) {
|
||||
prevText = text!
|
||||
}
|
||||
updateAttributedTextWith(prevText)
|
||||
goToBeginningOfParkedText()
|
||||
|
||||
|
||||
default:
|
||||
break
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Utilites
|
||||
func updateAttributedTextWith(_ text: String) {
|
||||
if let parkedTextRange = text.range(of: parkedText, options: NSString.CompareOptions.backwards, range: nil, locale: nil) {
|
||||
let nsRange = NSRangeFromRange(text, range: parkedTextRange)
|
||||
|
||||
let nsRange = text.nsRange(from: parkedTextRange)
|
||||
|
||||
let attributedString = NSMutableAttributedString(string: text)
|
||||
attributedString.addAttributes(parkedTextAttributes, range: nsRange)
|
||||
|
||||
|
||||
attributedText = attributedString
|
||||
}
|
||||
}
|
||||
|
||||
/// http://stackoverflow.com/questions/25138339/nsrange-to-rangestring-index
|
||||
func NSRangeFromRange(_ text:String, range : Range<String.Index>) -> NSRange {
|
||||
let utf16view = text.utf16
|
||||
let from = String.UTF16View.Index(range.lowerBound, within: utf16view)
|
||||
let to = String.UTF16View.Index(range.upperBound, within: utf16view)
|
||||
let loc = utf16view.startIndex.distance(to: from)
|
||||
let len = from.distance(to: to)
|
||||
return NSMakeRange(loc, len)
|
||||
}
|
||||
|
||||
|
||||
func goToBeginningOfParkedText() {
|
||||
if let position = beginningOfParkedText {
|
||||
goToTextPosition(position)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func goToTextPosition(_ textPosition: UITextPosition!) {
|
||||
selectedTextRange = textRange(from: textPosition, to: textPosition)
|
||||
}
|
||||
|
||||
|
||||
func bold(_ font: UIFont) -> UIFont {
|
||||
let descriptor = font.fontDescriptor.withSymbolicTraits(UIFontDescriptorSymbolicTraits.traitBold)
|
||||
return UIFont(descriptor: descriptor!, size: 0)
|
||||
}
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/30404532/805882
|
||||
fileprivate extension String {
|
||||
func nsRange(from range: Range<String.Index>) -> NSRange {
|
||||
let from = range.lowerBound.samePosition(in: utf16)
|
||||
let to = range.upperBound.samePosition(in: utf16)
|
||||
return NSRange(location: utf16.distance(from: utf16.startIndex, to: from),
|
||||
length: utf16.distance(from: from, to: to))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user