ตั้งค่าความยาวอักขระสูงสุดของ UITextField ใน Swift


88

ฉันรู้ว่ามีหัวข้ออื่น ๆ เกี่ยวกับเรื่องนี้ แต่ดูเหมือนจะหาวิธีนำไปใช้ไม่ได้

ฉันพยายาม จำกัด UITextField ให้เหลือเพียง 5 ตัวอักษร

โดยเฉพาะอย่างยิ่งตัวอักษรและตัวเลขและ - และ และ _

ฉันเคยเห็นรหัสนี้

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange,
                       replacementString string: String) -> Bool
{
    let maxLength = 4
    let currentString: NSString = textField.text
    let newString: NSString =
             currentString.stringByReplacingCharactersInRange(range, withString: string)
    return newString.length <= maxLength
}

และ

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

    let length = count(textField.text.utf16) + count(string.utf16) - range.length
    return length <= 10 
}

ฉันไม่รู้ว่าจะใช้งานได้จริงหรือ "ฟิลด์ข้อความ" ใดที่ฉันควรเปลี่ยนเป็น UITextField ที่กำหนดเองของฉัน


การใช้งาน Swift 4 stackoverflow.com/a/46513151/2303865
Leo Dabus

ด่วนแจ้งเตือน - เพื่อลดระยะStringในสวิฟท์วันนี้คุณจนสามารถเพียง .prefix (n)
Fattie

คำตอบ:


136
  1. ตัวควบคุมมุมมองของคุณควรเป็นไปตามUITextFieldDelegateด้านล่าง:

    class MyViewController: UIViewController, UITextFieldDelegate {
    
    }
    
  2. ตั้งค่าผู้รับมอบสิทธิ์ของฟิลด์ข้อความของคุณ: myTextField.delegate = self

  3. ใช้วิธีการในตัวควบคุมมุมมองของคุณ: textField(_:shouldChangeCharactersInRange:replacementString:)

ทั้งหมดเข้าด้วยกัน:

class MyViewController: UIViewController,UITextFieldDelegate  //set delegate to class 

@IBOutlet var mytextField: UITextField             //  textfield variable 

override func viewDidLoad() {
    super.viewDidLoad()
    mytextField.delegate = self                  //set delegate
}


func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange,
                       replacementString string: String) -> Bool
{
    let maxLength = 4
    let currentString: NSString = textField.text
    let newString: NSString =
             currentString.stringByReplacingCharactersInRange(range, withString: string)
    return newString.length <= maxLength
}

สำหรับ Swift 4

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let maxLength = 1
    let currentString: NSString = (textField.text ?? "") as NSString
    let newString: NSString =
        currentString.replacingCharacters(in: range, with: string) as NSString
    return newString.length <= maxLength
}

อนุญาตให้ป้อนเฉพาะชุดอักขระที่ระบุลงในช่องข้อความที่กำหนด

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
  var result = true
  
  if mytextField == numberField {
    if count(string) > 0 {
      let disallowedCharacterSet = NSCharacterSet(charactersInString: "0123456789.-").invertedSet
      let replacementStringIsLegal = string.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
      result = replacementStringIsLegal
    }
  }
 
  return result
}

วิธีตั้งโปรแกรมช่องข้อความ iOS ที่ป้อนเฉพาะตัวเลขที่มีความยาวสูงสุด


ขอบคุณมากสำหรับการตอบกลับที่รวดเร็ว! หากฉันตั้งค่าฟิลด์ข้อความนี้เป็นผู้รับมอบสิทธิ์ฉันจะสามารถแก้ไขฟิลด์ข้อความอื่นได้หรือไม่
ishkur88

ใช่และคุณจะได้รับฟิลด์ข้อความที่เป็นปัญหา (กำลังแก้ไข) เป็นพารามิเตอร์แรกtextFieldในวิธีการ func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
Aladin

แต่ฉันจะใส่พารามิเตอร์ที่สองไว้ที่ไหน ฉันไม่อ้างอิง myTextField อีกหลังจากที่ตั้งค่าเป็นผู้รับมอบสิทธิ์
ishkur88

เช่นถ้าฉันต้องการสร้างช่องข้อความอื่น 0-9 สำหรับหมายเลขโทรศัพท์เท่านั้น
ishkur88

ทุกครั้งที่มีการแก้ไขฟิลด์ข้อความจะมีการเรียกกลับshouldChangeCharactersInRangeซึ่งมีไว้สำหรับฟิลด์ข้อความทั้งหมดคุณจะได้รับการโทรกลับในที่เดียวกันshouldChangeCharactersInRangeและภายในวิธีนี้คุณสามารถรู้ได้ว่าฟิลด์ข้อความใดกำลังถูกแก้ไขด้วยพารามิเตอร์ที่ส่งผ่านที่textFieldคุณสามารถยกตัวอย่างเช่น แท็กสำหรับแต่ละฟิลด์ข้อความและทดสอบภายในshouldChangeCharactersInRangeและสำหรับแต่ละฟิลด์ข้อความดำเนินการตรวจสอบความถูกต้องของเนื้อหา
Aladin

118

Modern Swift

โปรดทราบว่าโค้ดตัวอย่างออนไลน์ส่วนใหญ่เกี่ยวกับปัญหานี้ล้าสมัยอย่างมาก

วางสิ่งต่อไปนี้ลงในไฟล์ Swift ในโครงการของคุณ (คุณสามารถตั้งชื่อไฟล์อะไรก็ได้เช่น "Handy.swift")

ในที่สุดสิ่งนี้จะแก้ไขปัญหาที่โง่ที่สุดใน iOS:

enter image description here

ตอนนี้ช่องข้อความของคุณมีไฟล์.maxLength.

การตั้งค่านั้นในสตอรีบอร์ดระหว่างการพัฒนาหรือตั้งค่าเป็นรหัสในขณะที่แอปกำลังทำงานอยู่เป็นเรื่องปกติดี

// simply have this in any Swift file, say, Handy.swift

import UIKit
private var __maxLengths = [UITextField: Int]()
extension UITextField {
    @IBInspectable var maxLength: Int {
        get {
            guard let l = __maxLengths[self] else {
               return 150 // (global default-limit. or just, Int.max)
            }
            return l
        }
        set {
            __maxLengths[self] = newValue
            addTarget(self, action: #selector(fix), for: .editingChanged)
        }
    }
    func fix(textField: UITextField) {
        let t = textField.text
        textField.text = t?.prefix(maxLength)
    }
}

มันง่ายมาก


เชิงอรรถ - ทุกวันนี้คุณสามารถตัดทอนความStringรวดเร็วได้อย่างปลอดภัย.prefix(n)


เวอร์ชันเดียวที่ง่ายกว่าเดิม ...

ข้างต้นแก้ไขช่องข้อความทั้งหมดในโครงการของคุณ

หากคุณต้องการให้ช่องข้อความใดช่องหนึ่งจำกัด เพียงแค่พูดว่า "4" เท่านั้นเท่านี้ ...

class PinCodeEntry: UITextField {
    
    override func didMoveToSuperview() {
        
        super.didMoveToSuperview()
        addTarget(self, action: #selector(fixMe), for: .editingChanged)
    }
    
    @objc private func fixMe() { text = text?.prefix(4) }
}

วุ้ย นั่นคือทั้งหมดที่มีให้

(เพียง BTW นี่เป็นเคล็ดลับที่มีประโยชน์มากที่คล้ายกันเกี่ยวกับการ UIText ดู , https://stackoverflow.com/a/42333832/294884 )


สำหรับโปรแกรมเมอร์ OCD (อย่างผม) ...

ตามที่ @LeoDabus เตือนให้.prefixส่งคืนสตริงย่อย หากคุณห่วงใยอย่างไม่น่าเชื่อสิ่งนี้

let t = textField.text
textField.text = t?.prefix(maxLength)

อยากจะเป็น

if let t: String = textField.text {
    textField.text = String(t.prefix(maxLength))
}

สนุก!


2
ดูเหมือนว่าเชื่อถือได้! ขอขอบคุณ.
J. Doe

13
ทั้งหมดนี้ต้องทำเพื่อให้บรรลุบางสิ่งที่ธรรมดาและเรียบง่ายจนทำให้ใจฉันเต้นแรง พวกเขาไม่สามารถให้ textField.maxLength ในตัวง่ายๆแก่เราได้ ... อย่างไรก็ตามโซลูชันของคุณดีมากขอบคุณ!
mylovemhz

1
ว้าวเคล็ดลับที่ดีที่สุดที่ฉันเคยมีกับ SO ฉันจะโหวต 100 ถ้าทำได้!
jonathan3087

2
วิธีแก้ปัญหามีประโยชน์ แต่แผนที่ของฟิลด์ข้อความที่ด้านบนจะสร้างวงจรการเก็บรักษา
Angel G.Olloqui

3
คำเตือนสำหรับผู้ใช้วิธีนี้! โซลูชันนี้มีปัญหาบางประการ หนึ่งในนั้นคือหากผู้ใช้พิมพ์ที่จุดเริ่มต้นของ textField คุณจะอนุญาตให้พวกเขาพิมพ์อักขระใหม่และตัวสุดท้ายจะถูกลบออกไปเคอร์เซอร์จะข้ามไปยังอักขระสุดท้ายในฟิลด์ ปัญหาอีกประการหนึ่งคือหากคุณตั้งค่าข้อความโดยใช้โปรแกรมจะทำให้คุณสามารถกำหนดข้อความที่ใหญ่กว่าขีด จำกัด ปัญหาอื่นเกิดขึ้นหากคุณเลิกทำการเปลี่ยนแปลง (CMD + Z ด้วยแป้นพิมพ์ภายนอก) ซึ่งจะขัดข้องหากคุณพยายามเพิ่มตัวเลขเกินขีด จำกัด ก่อนหน้านี้
juancazalla

25

Swift 4 เพียงใช้:

public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    return range.location < 10
}

นี่ควรเป็นคำตอบที่เลือก เรียบง่ายและใช้งานได้ดี
user832

9
มันไม่ทำงาน จะเกิดอะไรขึ้นถ้าคุณแตะตรงกลางสตริงและคุณสามารถพิมพ์ได้มากกว่า X ตัวอักษร
Slavcho

แทนที่จะเป็น range.location <10 คุณสามารถใช้ textField.text.length <10 โซลูชันนี้เรียบง่ายและสวยงาม
Saqib Saud

คุณสามารถใช้วิธีนี้: if textField.text? .count> = 12 {return false}
СергейБилык

1
มันใช้ไม่ได้เมื่อผ่านข้อความหากคุณต้องการทำงานในอดีตที่ผ่านมาคุณควรเพิ่มstring.count < MAX_LENGTH
Reza Dehnavi

12

เช่นเดียวกับที่ Steven Schmatz ทำ แต่ใช้ Swift 3.0:

//max Length
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
               replacementString string: String) -> Bool
{
    let maxLength = 4
    let currentString: NSString = textField.text! as NSString
    let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString
    return newString.length <= maxLength
}

1
คำตอบที่ดี. ชื่นชม.
Hasya

ขอบคุณ @Hasya
Pavlos

8

สำหรับ Swift 5:
เพียงเขียนหนึ่งบรรทัดเพื่อตั้งค่าความยาวถ่านสูงสุด:

 self.textField.maxLength = 10

รายละเอียดเพิ่มเติมคลิกที่นี่

เครดิต: http://www.swiftdevcenter.com/max-character-limit-of-uitextfield-and-allowed-characters-swift/


แม้ว่าโซลูชันนี้อาจดูตรงไปตรงมา แต่ก็มีโค้ดอีกมากมายที่จำเป็นในการใช้งานสิ่งนี้ คำตอบนี้ไม่ได้มีประโยชน์มากนักและการเพิ่มคำอธิบายและการรวมโค้ดส่วนอื่น ๆ ที่เกี่ยวข้องอาจเป็นประโยชน์
FontFamily

6

ฉันคิดว่าส่วนขยายมีประโยชน์มากกว่าสำหรับสิ่งนี้ ดูคำตอบแบบเต็มได้ที่นี่

private var maxLengths = [UITextField: Int]()

// 2
extension UITextField {

  // 3
  @IBInspectable var maxLength: Int {
    get {
      // 4
      guard let length = maxLengths[self] else {
        return Int.max
      }
      return length
    }
    set {
      maxLengths[self] = newValue
      // 5
      addTarget(
        self,
        action: #selector(limitLength),
        forControlEvents: UIControlEvents.EditingChanged
      )
    }
  }

  func limitLength(textField: UITextField) {
    // 6
    guard let prospectiveText = textField.text
      where prospectiveText.characters.count > maxLength else {
        return
    }

    let selection = selectedTextRange
    // 7
    text = prospectiveText.substringWithRange(
      Range<String.Index>(prospectiveText.startIndex ..< prospectiveText.startIndex.advancedBy(maxLength))
    )
    selectedTextRange = selection
  }

}

4

วิธีแก้ปัญหาอื่น ๆ ที่โพสต์ไว้ข้างต้นจะสร้างวงจรการเก็บรักษาเนื่องจากแผนที่ช่องข้อความ นอกจากนี้maxLengthคุณสมบัติควรเป็นโมฆะหากไม่ได้ตั้งค่าแทนเทียมInt.maxสร้างและเป้าหมายจะถูกตั้งค่าหลายครั้งหาก maxLength มีการเปลี่ยนแปลง

นี่คือโซลูชันที่อัปเดตสำหรับ Swift4 พร้อมแผนที่ที่อ่อนแอเพื่อป้องกันการรั่วไหลของหน่วยความจำและการแก้ไขอื่น ๆ

private var maxLengths = NSMapTable<UITextField, NSNumber>(keyOptions: NSPointerFunctions.Options.weakMemory, valueOptions: NSPointerFunctions.Options.strongMemory)

extension UITextField {

    var maxLength: Int? {
        get {
            return maxLengths.object(forKey: self)?.intValue
        }
        set {
            removeTarget(self, action: #selector(limitLength), for: .editingChanged)
            if let newValue = newValue {
                maxLengths.setObject(NSNumber(value: newValue), forKey: self)
                addTarget(self, action: #selector(limitLength), for: .editingChanged)
            } else {
                maxLengths.removeObject(forKey: self)
            }
        }
    }

    @IBInspectable var maxLengthInspectable: Int {
        get {
            return maxLength ?? Int.max
        }
        set {
            maxLength = newValue
        }
    }

    @objc private func limitLength(_ textField: UITextField) {
        guard let maxLength = maxLength, let prospectiveText = textField.text, prospectiveText.count > maxLength else {
            return
        }
        let selection = selectedTextRange
        text = String(prospectiveText[..<prospectiveText.index(from: maxLength)])
        selectedTextRange = selection
    }
}

ขอบคุณสำหรับคำตอบคุณช่วยอธิบาย maxLengths ได้ไหม
Keyhan Kamangar

4

วิธีง่ายๆโดยไม่ต้องใช้ผู้รับมอบสิทธิ์:

TEXT_FIELD.addTarget(self, action: #selector(editingChanged(sender:)), for: .editingChanged)


@objc private func editingChanged(sender: UITextField) {

        if let text = sender.text, text.count >= MAX_LENGHT {
            sender.text = String(text.dropLast(text.count - MAX_LENGHT))
            return
        }
}

2
คำตอบที่ฉันกำลังมองหา: D
Ankur Lahiry

1
นี่คือวิธีแก้ปัญหาที่เรียบง่ายและสวยงามโดยไม่มีรหัสสำเร็จรูป
zeeshan

3

My Swift 4 เวอร์ชัน shouldChangeCharactersIn

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

        guard let preText = textField.text as NSString?,
            preText.replacingCharacters(in: range, with: string).count <= MAX_TEXT_LENGTH else {
            return false
        }

        return true
    }

นี่ควรเป็นคำตอบที่ได้รับการยอมรับ ทำงานได้อย่างสมบูรณ์ไม่มีจุดบกพร่อง
10623169

2

ฉันมีบางอย่างที่จะเพิ่มในคำตอบของ Aladin:

  1. ตัวควบคุมมุมมองของคุณควรเป็นไปตาม UITextFieldDelegate

    class MyViewController: UIViewController, UITextViewDelegate {
    
    }
    
  2. ตั้งค่าผู้รับมอบสิทธิ์ของฟิลด์ข้อความของคุณ: ในการตั้งค่าผู้รับมอบสิทธิ์คุณสามารถควบคุมการลากจากฟิลด์ข้อความไปยังตัวควบคุมมุมมองของคุณในกระดานเรื่องราว ฉันคิดว่าวิธีนี้ดีกว่าที่จะตั้งเป็นรหัส

  3. ใช้วิธีการในตัวควบคุมมุมมองของคุณ: textField(_:shouldChangeCharactersInRange:replacementString:)


2

ฉันให้คำตอบเพิ่มเติมตาม @Frouo ฉันคิดว่าคำตอบของเขาเป็นวิธีที่สวยงามที่สุด เนื่องจากเป็นการควบคุมทั่วไปที่เราสามารถใช้ซ้ำได้ และไม่มีปัญหาการรั่วไหลที่นี่.

    private var kAssociationKeyMaxLength: Int = 0

    extension UITextField {

        @IBInspectable var maxLength: Int {
            get {
                if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLength) as? Int {
                    return length
                } else {
                    return Int.max
                }
            }
            set {
                objc_setAssociatedObject(self, &kAssociationKeyMaxLength, newValue, .OBJC_ASSOCIATION_RETAIN)
                self.addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
            }
        }

//The method is used to cancel the check when use Chinese Pinyin input method.
        //Becuase the alphabet also appears in the textfield when inputting, we should cancel the check.
        func isInputMethod() -> Bool {
            if let positionRange = self.markedTextRange {
                if let _ = self.position(from: positionRange.start, offset: 0) {
                    return true
                }
            }
            return false
        }


        func checkMaxLength(textField: UITextField) {

            guard !self.isInputMethod(), let prospectiveText = self.text,
                prospectiveText.count > maxLength
                else {
                    return
            }

            let selection = selectedTextRange
            let maxCharIndex = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
            text = prospectiveText.substring(to: maxCharIndex)
            selectedTextRange = selection
        }



    }

2

เพียงแค่ตรวจสอบด้วยจำนวนอักขระในสตริง

  1. เพิ่มผู้รับมอบสิทธิ์เพื่อดูตัวควบคุม ans เป็นผู้รับมอบสิทธิ์
    class YorsClassName : UITextFieldDelegate {

    }
  1. ตรวจสอบจำนวนตัวอักษรที่อนุญาตสำหรับฟิลด์ข้อความ
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if textField.text?.count == 1 {
        return false
    }
    return true
}

หมายเหตุ: ที่นี่ฉันตรวจสอบเฉพาะถ่านที่อนุญาตใน textField


2

อัปเดตสำหรับคำตอบ Fattieนี้

ขอบคุณ

extension UITextField {

    /// Runtime key
    private struct AssociatedKeys {
        /// max lenght key
        static var maxlength: UInt8 = 0
        /// temp string key
        static var tempString: UInt8 = 0
    }

    /// Limit the maximum input length of the textfiled
    @IBInspectable var maxLength: Int {
        get {
            return objc_getAssociatedObject(self, &AssociatedKeys.maxlength) as? Int ?? 0
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.maxlength, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            addTarget(self, action: #selector(handleEditingChanged(textField:)), for: .editingChanged)
        }
    }

    /// temp string
    private var tempString: String? {
        get {
            return objc_getAssociatedObject(self, &AssociatedKeys.tempString) as? String
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.tempString, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    /// When the text changes, process the amount of text in the input box so that its length is within the controllable range.
    @objc private func handleEditingChanged(textField: UITextField) {

        /// Special Processing for Chinese Input Method
        guard markedTextRange == nil else { return }

        if textField.text?.count == maxLength {

            /// SET lastQualifiedString where text length == max lenght
            tempString = textField.text
        } else if textField.text?.count ?? 0 < maxLength {

            /// clear lastQualifiedString when text lengeht > maxlength
            tempString = nil
        }

        /// keep current text range in arcgives
        let archivesEditRange: UITextRange?

        if textField.text?.count ?? 0 > maxLength {

            /// if text length > maxlength,remove last range,to move to -1 postion.
            let position = textField.position(from: safeTextPosition(selectedTextRange?.start), offset: -1) ?? textField.endOfDocument
            archivesEditRange = textField.textRange(from: safeTextPosition(position), to: safeTextPosition(position))
        } else {

            /// just set current select text range
            archivesEditRange = selectedTextRange
        }

        /// main handle string max length
        textField.text = tempString ?? String((textField.text ?? "").prefix(maxLength))

        /// last config edit text range
        textField.selectedTextRange = archivesEditRange
    }

    /// get safe textPosition
    private func safeTextPosition(_ optionlTextPosition: UITextPosition?) -> UITextPosition {

        /* beginningOfDocument -> The end of the the text document. */
        return optionlTextPosition ?? endOfDocument
    }
}

1

การทำงานใน Swift4

// ขั้นตอนที่ 1 ตั้งค่า UITextFieldDelegate

    class SignUPViewController: UIViewController , UITextFieldDelegate {

       @IBOutlet weak var userMobileNoTextFiled: UITextField!

        override func viewDidLoad() {
            super.viewDidLoad()

// ขั้นตอนที่ 2 ตั้งค่า delegate
userMobileNoTextFiled.delegate = self // set delegate}

     func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    //        guard let text = userMobileNoTextFiled.text else { return true }
    //        let newLength = text.count + string.count - range.length
    //        return newLength <= 10
    //    }

// ขั้นตอนที่ 3 โทร func

        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            let maxLength = 10          // set your need
            let currentString: NSString = textField.text! as NSString
            let newString: NSString =
                currentString.replacingCharacters(in: range, with: string) as NSString
            return newString.length <= maxLength
        }
    }

1

คำตอบนี้มีไว้สำหรับ Swift 4 และค่อนข้างตรงไปตรงมาพร้อมกับความสามารถในการปล่อย Backspace ผ่าน

func textField(_ textField: UITextField, 
               shouldChangeCharactersIn range: NSRange, 
               replacementString string: String) -> Bool {
    return textField.text!.count < 10 || string == ""
}

นี้ไม่ได้จัดการคัดลอกและวาง
cornr

1

ฉันใช้ขั้นตอนนี้ขั้นแรกตั้งค่า texfield ที่มอบหมายใน viewdidload

    override func viewDidLoad() {
        super.viewDidLoad()

        textfield.delegate = self

    }

จากนั้นจึง shouldChangeCharactersIn หลังจากที่คุณรวม UITextFieldDelegate

extension viewController: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
                let newLength = (textField.text?.utf16.count)! + string.utf16.count - range.length
                if newLength <= 8 { 
                    return true
                } else {
                    return false
                }
            }
    }

1

TextField Limit Character หลังจากบล็อกข้อความใน Swift 4

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


    if textField == self.txtDescription {
        let maxLength = 200
        let currentString: NSString = textField.text! as NSString
        let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString
        return newString.length <= maxLength
    }

    return true


}

1

ในกรณีนี้อย่าลืมป้องกันขนาดของช่วงก่อนที่จะใช้กับสตริง มิฉะนั้นคุณจะได้รับความผิดพลาดหากผู้ใช้ทำสิ่งนี้:

พิมพ์ข้อความที่มีความยาวสูงสุดแทรกบางสิ่ง (จะไม่ถูกแทรกเนื่องจากข้อจำกัดความยาว แต่ iOS ไม่รู้) เลิกทำการแทรก (คุณได้รับความผิดพลาดช่วงสาเหตุจะมากกว่าขนาดสตริงจริง)

นอกจากนี้การใช้ผู้ใช้ iOS 13 สามารถกระตุ้นสิ่งนี้โดยบังเอิญได้ด้วยท่าทางสัมผัส

ฉันขอแนะนำให้คุณเพิ่มสิ่งนี้ในโครงการของคุณ

extension String {
    func replace(with text: String, in range: NSRange) -> String? {
        guard range.location + range.length <= self.count else { return nil }
        return (self as NSString).replacingCharacters(in: range, with: text)
    }
}

และใช้มันดังนี้:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    guard let newText = textView.text.replace(with: text, in: range) else { return false }
    return newText.count < maxNumberOfCharacters
}

ไม่เช่นนั้นแอปของคุณจะขัดข้องอยู่ตลอดเวลา


0

นี่คือทางเลือก Swift 3.2+ ที่หลีกเลี่ยงการจัดการสตริงที่ไม่จำเป็น ในกรณีนี้ความยาวสูงสุดคือ 10:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let text = textField.text ?? ""

    return text.count - range.length + string.count <= 10
}

0

หากคุณมี textField หลายรายการที่มีการตรวจสอบความยาวต่างๆในหน้าเดียวฉันพบวิธีแก้ปัญหาที่ง่ายและสั้น

class MultipleTextField: UIViewController {

    let MAX_LENGTH_TEXTFIELD_A = 10
    let MAX_LENGTH_TEXTFIELD_B = 11

    lazy var textFieldA: UITextField = {
        let textField = UITextField()
        textField.tag = MAX_LENGTH_TEXTFIELD_A
        textField.delegate = self
        return textField
    }()
    lazy var textFieldB: UITextField = {
        let textField = UITextField()
        textField.tag = MAX_LENGTH_TEXTFIELD_B
        textField.delegate = self
        return textField
    }()
}

extension MultipleTextField: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        return (range.location < textField.tag) && (string.count < textField.tag)
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.