UITextField ความยาวสูงสุด


120

เมื่อฉันได้ลองHow to you set the maximum number of characters that can be enter a UITextField using swift? ฉันเห็นว่าถ้าฉันใช้อักขระทั้ง 10 ตัวฉันก็ไม่สามารถลบตัวละครได้ด้วย

สิ่งเดียวที่ฉันทำได้คือยกเลิกการดำเนินการ (ลบอักขระทั้งหมดพร้อมกัน)

มีใครรู้วิธีไม่บล็อกแป้นพิมพ์ (เพื่อที่ฉันจะไม่สามารถเพิ่มตัวอักษร / สัญลักษณ์ / ตัวเลขอื่น ๆ ได้ แต่ฉันสามารถใช้ backspace ได้)

คำตอบ:


295

ด้วย Swift 5 และ iOS 12 ให้ลองใช้textField(_:shouldChangeCharactersIn:replacementString:)วิธีการต่อไปนี้ซึ่งเป็นส่วนหนึ่งของUITextFieldDelegateโปรโตคอล:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let textFieldText = textField.text,
        let rangeOfTextToReplace = Range(range, in: textFieldText) else {
            return false
    }
    let substringToReplace = textFieldText[rangeOfTextToReplace]
    let count = textFieldText.count - substringToReplace.count + string.count
    return count <= 10
}
  • ส่วนที่สำคัญที่สุดของรหัสนี้คือการแปลงจากrange( NSRange) เป็นrangeOfTextToReplace( Range<String.Index>) ดูวิดีโอบทแนะนำนี้เพื่อทำความเข้าใจว่าเหตุใดการแปลงนี้จึงมีความสำคัญ
  • เพื่อให้การทำงานรหัสนี้ถูกต้องคุณควรตั้งค่าtextField's มูลค่าให้กับsmartInsertDeleteType UITextSmartInsertDeleteType.noวิธีนี้จะป้องกันไม่ให้มีการแทรกช่องว่างเพิ่มเติม (ที่ไม่ต้องการ) ที่เป็นไปได้เมื่อดำเนินการวาง

โค้ดตัวอย่างที่สมบูรณ์ด้านล่างแสดงวิธีการนำไปใช้textField(_:shouldChangeCharactersIn:replacementString:)ในUIViewController:

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var textField: UITextField! // Link this to a UITextField in Storyboard

    override func viewDidLoad() {
        super.viewDidLoad()

        textField.smartInsertDeleteType = UITextSmartInsertDeleteType.no
        textField.delegate = self
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard let textFieldText = textField.text,
            let rangeOfTextToReplace = Range(range, in: textFieldText) else {
                return false
        }
        let substringToReplace = textFieldText[rangeOfTextToReplace]
        let count = textFieldText.count - substringToReplace.count + string.count
        return count <= 10
    }

}

คุณเพิ่งใส่รหัสนี้ในคลาสตัวควบคุมมุมมองของคุณหรือไม่? หรือฉันต้องทำการเชื่อมต่อ?
Isaac Wasserman

ถ้ามีใครต้องวางเงื่อนไขบ้าง.. ทำได้แบบนี้ .. if (textField .isEqual (mobileNumberTextfield)) {guard let text = textField.text else {return true} let newLength = text.characters.count + string.characters.count - range.length return newLength <= limitLength; } กลับจริง;
Narasimha Nallamsetty

6
สำหรับ Swift 4 text.characters.countนั้นเลิกใช้แล้วtext.count
Mohamed Salah

47

ฉันทำแบบนี้:

func checkMaxLength(textField: UITextField!, maxLength: Int) {
    if (countElements(textField.text!) > maxLength) {
        textField.deleteBackward()
    }
}

รหัสใช้งานได้สำหรับฉัน แต่ฉันทำงานกับสตอรี่บอร์ด ใน Storyboard ฉันจะเพิ่มการดำเนินการสำหรับฟิลด์ข้อความในตัวควบคุมมุมมองในการ edit เปลี่ยนแปลง


1
countElements ถูกเปลี่ยนเป็นการนับใน Swift 2 แต่การเปลี่ยนแปลงนั้นเหมาะกับฉัน!
John

1
ขอบคุณตอนนี้คุณสามารถใช้ textField.text? .characters.count ได้เนื่องจาก countElements มีการเปลี่ยนแปลง
Anibal R.

1
Tks มันใช้งานได้ดีกับการเปลี่ยนแปลงนี้: countElements (textField.text!) ใน Swift 2 คือ textField.text? .characters.count
kha

33

อัปเดตสำหรับ Swift 4

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

15

เพิ่มรายละเอียดเพิ่มเติมจากคำตอบของ @Martin

// linked your button here
@IBAction func mobileTFChanged(sender: AnyObject) {
    checkMaxLength(sender as! UITextField, maxLength: 10)
}

// linked your button here
@IBAction func citizenTFChanged(sender: AnyObject) {
    checkMaxLength(sender as! UITextField, maxLength: 13)
}

func checkMaxLength(textField: UITextField!, maxLength: Int) {
    // swift 1.0
    //if (count(textField.text!) > maxLength) {
    //    textField.deleteBackward()
    //}
    // swift 2.0
    if (textField.text!.characters.count > maxLength) {
        textField.deleteBackward()
    }
}

1
count (textField.text!) ทำให้เกิดข้อผิดพลาด คุณต้องใช้ textField.text! .characters.count
Regis St-Gelais

1
ขอบคุณ @ RegisSt-Gelais เป็นคำตอบเก่าอยู่แล้วฉันอัปเดตแล้ว
Sruit A.Suk

11

ใน Swift 4

จำกัด อักขระ 10 ตัวสำหรับช่องข้อความและอนุญาตให้ลบ (backspace)

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if textField ==  userNameFTF{
            let char = string.cString(using: String.Encoding.utf8)
            let isBackSpace = strcmp(char, "\\b")
            if isBackSpace == -92 {
                return true
            }
            return textField.text!.count <= 9
        }
        return true
    }

8
func checkMaxLength(textField: UITextField!, maxLength: Int) {
        if (textField.text!.characters.count > maxLength) {
            textField.deleteBackward()
        }
}

การเปลี่ยนแปลงเล็กน้อยสำหรับ IOS 9


8

สวิฟต์ 3

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

            let nsString = NSString(string: textField.text!)
            let newText = nsString.replacingCharacters(in: range, with: string)
            return  newText.characters.count <= limitCount
    }

8

คุณสามารถขยาย UITextField และเพิ่ม@IBInspectableวัตถุสำหรับจัดการได้:

SWIFT 5

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)
        }
    }
    @objc func fix(textField: UITextField) {
        if let t = textField.text {
            textField.text = String(t.prefix(maxLength))
        }
    }
}

และหลังจากนั้นกำหนดในตัวตรวจสอบแอตทริบิวต์

ใส่คำอธิบายภาพที่นี่

ดูคำตอบดั้งเดิมของ Swift 4


2
รหัสดีสะอาด แต่ด้วยเหตุผลบางประการสิ่งนี้ทำให้เกิดพฤติกรรมการแก้ไขแปลก ๆ เมื่อคุณใช้อิโมจิ เคอร์เซอร์จะข้ามไปที่ท้ายบรรทัดทุกครั้งที่คุณพยายามแก้ไข
Phontaine Judd

5

หากคุณต้องการเขียนทับตัวอักษรสุดท้าย:

let maxLength = 10

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

    if range.location > maxLength - 1 {
        textField.text?.removeLast()
    }

    return true
}

4

ฉันโพสต์วิธีแก้ปัญหาโดยใช้IBInspectableดังนั้นคุณสามารถเปลี่ยนค่าความยาวสูงสุดได้ทั้งในตัวสร้างอินเทอร์เฟซหรือทางโปรแกรม ตรวจสอบได้ที่นี่


3

คุณสามารถใช้ใน swift 5 หรือ swift 4 เช่น ภาพเหมือนร้อง ใส่คำอธิบายภาพที่นี่

  1. เพิ่ม textField ใน View Controller
  2. เชื่อมต่อกับข้อความไปยัง ViewController
  3. เพิ่มรหัสในมุมมอง ViewController

     class ViewController: UIViewController , UITextFieldDelegate {
    
      @IBOutlet weak var txtName: UITextField!
    
      var maxLen:Int = 8;
    
     override func viewDidLoad() {
        super.viewDidLoad()
    
        txtName.delegate = self
       }
    
     func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
         if(textField == txtName){
            let currentText = textField.text! + string
            return currentText.count <= maxLen
         }
    
         return true;
       }
    }

คุณสามารถดาวน์โหลดแบบฟอร์ม Full Source GitHub: https://github.com/enamul95/TextFieldMaxLen


1

ระวังข้อผิดพลาดการเลิกทำสำหรับ UITextField ที่กล่าวถึงในโพสต์นี้: ตั้งค่าความยาวอักขระสูงสุดของ UITextField

นี่คือวิธีที่คุณแก้ไขได้อย่างรวดเร็ว

if(range.length + range.location > count(textField.text)) {
        return false;
}

หากคุณต้องการสนับสนุนอีโมจิและการใช้งานดังกล่าว: if (range.length + range.location> count (textField.text.utf16)) {return false; }
AlexD

1
Here is my version of code. Hope it helps!

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        let invalidCharacters = NSCharacterSet(charactersInString: "0123456789").invertedSet

        if let range = string.rangeOfCharacterFromSet(invalidCharacters, options: nil, range:Range<String.Index>(start: string.startIndex, end: string.endIndex))
        {
            return false
        }

        if (count(textField.text) > 10  && range.length == 0)
        {
            self.view.makeToast(message: "Amount entry is limited to ten digits", duration: 0.5, position: HRToastPositionCenter)
            return false
        }
        else
        {

        }

        return true
    }

1
ฉันชอบส่วนขยาย Toast UIView :)
Regis St-Gelais

1

ฉันใช้โปรโตคอล / ส่วนขยายนี้ในแอปหนึ่งของฉันและอ่านได้ง่ายขึ้นเล็กน้อย ฉันชอบวิธีที่มันจดจำ backspaces และบอกคุณอย่างชัดเจนเมื่อตัวละครเป็น backspace

สิ่งที่ควรพิจารณา:

1. สิ่งใดก็ตามที่ใช้ส่วนขยายโปรโตคอลนี้จำเป็นต้องระบุขีด จำกัด ของอักขระโดยทั่วไปจะเป็น ViewController ของคุณ แต่คุณสามารถใช้การ จำกัด จำนวนอักขระเป็นคุณสมบัติที่คำนวณและส่งคืนอย่างอื่นได้ตัวอย่างเช่นการ จำกัด จำนวนอักขระในโมเดลของคุณ

2. คุณจะต้องเรียกใช้เมธอดนี้ภายในเมธอดผู้ร่วมประชุม shouldChangeCharactersInRange ของช่องข้อความของคุณ มิฉะนั้นคุณจะไม่สามารถบล็อกการป้อนข้อความโดยส่งคืนเท็จเป็นต้น

3. คุณอาจต้องการอนุญาตให้ใช้อักขระ backspace ผ่าน นั่นเป็นเหตุผลที่ฉันเพิ่มฟังก์ชันพิเศษในการตรวจจับแบ็คสเปซ เมธอด shouldChangeCharacters ของคุณสามารถตรวจสอบสิ่งนี้และส่งคืน 'จริง' ในช่วงต้นดังนั้นคุณจึงอนุญาตให้แบ็คสเปซได้เสมอ

protocol TextEntryCharacterLimited{
    var characterLimit:Int { get } 
}

extension TextEntryCharacterLimited{

    func charactersInTextField(textField:UITextField, willNotExceedCharacterLimitWithReplacementString string:String, range:NSRange) -> Bool{

        let startingLength = textField.text?.characters.count ?? 0
        let lengthToAdd = string.characters.count
        let lengthToReplace = range.length

        let newLength = startingLength + lengthToAdd - lengthToReplace

        return newLength <= characterLimit

    }

    func stringIsBackspaceWith(string:String, inRange range:NSRange) -> Bool{
        if range.length == 1 && string.characters.count == 0 { return true }
        return false
    }

}

หากคุณสนใจฉันมีที่เก็บ Github ที่ฉันได้ใช้พฤติกรรมการ จำกัด อักขระนี้และใส่ลงในกรอบงาน iOS มีโปรโตคอลที่คุณสามารถนำไปใช้เพื่อแสดงการ จำกัด จำนวนอักขระเหมือน Twitter ซึ่งจะแสดงให้คุณเห็นว่าคุณใช้อักขระเกินขีด จำกัด ไปแล้วเท่าใด

CharacterLimited Framework บน Github


1

เนื่องจากผู้รับมอบสิทธิ์เป็นความสัมพันธ์แบบ 1 ต่อ 1 และฉันอาจต้องการใช้ที่อื่นด้วยเหตุผลอื่นฉันจึงต้องการจำกัดความยาวของฟิลด์ข้อความโดยเพิ่มรหัสนี้ภายในการตั้งค่า:

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        setup()
    }

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

    func setup() {

        // your setup...

        setMaxLength()
    }

    let maxLength = 10

    private func setMaxLength() {
            addTarget(self, action: #selector(textfieldChanged(_:)), for: UIControlEvents.editingChanged)
        }

        @objc private func textfieldChanged(_ textField: UITextField) {
            guard let text = text else { return }
            let trimmed = text.characters.prefix(maxLength)
            self.text = String(trimmed)

        }

0

ฉันใช้สิ่งนี้;

จำกัด 3 ตัวอักษร

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

        if let txt = textField.text {
            let currentText = txt + string
            if currentText.count > 3 {
                return false
            }
            return true
        }
        return true
    }

0

สวิฟต์ 5

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let MAX_LENGTH = 4
        let updatedString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
        return updatedString.count <= MAX_LENGTH
    }

-3

คุณต้องตรวจสอบว่าสตริงที่มีอยู่บวกอินพุตมากกว่า 10 หรือไม่

   func textField(textField: UITextField!,shouldChangeCharactersInRange range: NSRange,    replacementString string: String!) -> Bool {
      NSUInteger newLength = textField.text.length + string.length - range.length;
      return !(newLength > 10)
   }

5
รหัสของคุณไม่ถูกต้อง 1. คุณต้องประกาศค่าคงที่หรือตัวแปรของคุณด้วย let หรือ var ใน Swift (ไม่ใช่ NSUInteger) 2. textField.text และสตริงเป็นประเภท String ความยาวไม่ใช่คุณสมบัติ / วิธีการของ String ใน Swift
Imanou Petit
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.