Swift에서 UI 텍스트 필드의 최대 문자 길이 설정
이에 대한 다른 주제가 있다는 것은 알지만, 어떻게 구현해야 할지 모르겠습니다.
UI 텍스트 필드를 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로 교체해야 합니까?
는 뷰컨트롤러가합야니다준해수다음을에 따라야 .
UITextFieldDelegate
아래와 같이:class MyViewController: UIViewController, UITextFieldDelegate { }
필드의 합니다.
myTextField.delegate = self
보기 컨트롤러에서 메소드를 구현합니다.
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
}
스위프트 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
}
스위프트 5용
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let maxLength = 1
let currentString = (textField.text ?? "") as NSString
let newString = currentString.replacingCharacters(in: range, with: string)
return newString.count <= maxLength
}
지정된 문자 집합만 지정된 텍스트 필드에 입력할 수 있음
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
var result = true
if mytextField == textField {
if count(string) > 0 {
let disallowedCharacterSet = NSCharacterSet(charactersInString: "0123456789.-").invertedSet
let replacementStringIsLegal = string.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
result = replacementStringIsLegal
}
}
return result
}
최대 길이의 숫자 입력만 사용하는 iOS 텍스트 필드를 프로그래밍하는 방법
모던 스위프트
온라인 예제 코드의 대부분은 매우 구식입니다.
프로젝트의 모든 Swift 파일(예: "Handy.swift")에 다음을 붙여넣습니다.
이것은 iOS에서 가장 어리석은 문제 중 하나를 해결합니다.
에 이제텍필에가 됩니다..maxLength
.
앱이 실행되는 동안 스토리보드나 코드에 해당 값을 설정해도 괜찮습니다.
// 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
}
}
그렇게 간단하다.
더 단순한 일회성 버전은...
위의 내용은 전체 프로젝트의 모든 텍스트 필드를 수정합니다.
특정 텍스트 필드 하나를 단순히 "4"로 제한하고 싶다면, 그게 바로...
class PinCodeEntry: UITextField {
override func didMoveToSuperview() {
super.didMoveToSuperview()
addTarget(self, action: #selector(fixMe), for: .editingChanged)
}
@objc private func fixMe() { text = text?.prefix(4) }
}
그게 다야.
(UITextView, https://stackoverflow.com/a/42333832/294884 와 관련하여 매우 유용한 유사한 팁이 있습니다.)
Swift 4에서는 다음을 사용합니다.
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return range.location < 10
}
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
}
대리인을 사용하지 않는 간단한 솔루션:
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
}
}
Swift 5의 경우:
최대 문자 길이를 설정하려면 한 줄만 작성하면 됩니다.
self.textField.maxLength = 10
자세한 내용은 UITextField의 최대 문자 제한 및 허용 문자 Swift를 참조하십시오. (또한 인정됨)
이것은 연장이 더 편리할 것 같습니다.여기에서 전체 답변을 확인하십시오.
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 마이 스위프트 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
}
이전에 게시된 다른 솔루션은 텍스트 필드 맵으로 인해 유지 주기를 생성합니다. 다가게, 그그.maxLength
속은인대이신설않정지은합경니다우어야되성위인 대신 설정하지 않으면 이어야 합니다.Int.max
변경되면 번 됩니다.
여기 메모리 누수를 방지하고 다른 수정 사항을 방지하기 위한 약한 맵을 가진 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
}
}
저는 @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 using
// the 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
}
}
문자열의 문자 수를 확인하기만 하면 됩니다.
컨트롤러를 볼 대리인을 추가하고 대리인을 할당합니다.
class YorsClassName : UITextFieldDelegate { }
텍스트 필드에 허용되는 문자 수 확인
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField.text?.count == 1 { return false } return true }
참고: 여기서는 textField에 허용되는 문자만 확인했습니다.
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
}
알라딘의 대답에 덧붙일 말이 있습니다.
뷰 컨트롤러가 다음을 준수해야 합니다.
UITextFieldDelegate
class MyViewController: UIViewController, UITextViewDelegate { }
텍스트 필드의 대리자를 설정합니다.
위임자를 설정하려면 텍스트 필드에서 스토리보드의 뷰 컨트롤러로 드래그를 제어할 수 있습니다.코드로 설정하는 것보다 이것이 더 낫다고 생각합니다.
보기 컨트롤러에서 메소드를 구현합니다.
textField(_:shouldChangeCharactersInRange:replacementString:)
패티의 답변에 대한 업데이트:
extension UITextField {
// Runtime key
private struct AssociatedKeys {
// Maximum length key
static var maxlength: UInt8 = 0
// Temporary 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)
}
}
// Temporary 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 the Chinese input method
guard markedTextRange == nil else { return }
if textField.text?.count == maxLength {
// Set lastQualifiedString where text length == maximum length
tempString = textField.text
} else if textField.text?.count ?? 0 < maxLength {
// Clear lastQualifiedString when text length > maxlength
tempString = nil
}
// Keep the current text range in arcgives
let archivesEditRange: UITextRange?
if textField.text?.count ?? 0 > maxLength {
// If text length > maximum length, remove last range and 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 maximum length
textField.text = tempString ?? String((textField.text ?? "").prefix(maxLength))
// Last configuration 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
}
}
텍스트 필드의 대리자를 설정합니다.
textField.delegate = self
보기 컨트롤러에서 메소드를 구현합니다.
// MARK: Text field delegate extension ViewController: UITextFieldDelegate { func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { return range.location < maxLength (maxLength can be any maximum length you can define) } }
불필요한 문자열 조작을 방지하는 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
}
이 대답은 Swift 4를 위한 것이며 백스페이스가 통과할 수 있도록 하는 기능으로 매우 간단합니다.
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
return textField.text!.count < 10 || string == ""
}
이것은 Swift 4에서 작동합니다.
1단계: UITextField 딜러 설정
class SignUPViewController: UIViewController , UITextFieldDelegate {
@IBOutlet weak var userMobileNoTextFiled: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
2단계: 딜러를 설정
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 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
}
}
저는 이 단계들을 사용합니다.먼저 view didload에서 대리자 텍스트 필드를 설정합니다.
override func viewDidLoad() {
super.viewDidLoad()
textfield.delegate = self
}
그런 다음 UITextFieldDelegate를 포함한 후 CharactersIn을 변경해야 합니다.
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
}
}
}
만약을 대비해서, 끈에 적용하기 전에 범위 크기를 지키는 것을 잊지 마세요.그렇지 않으면 사용자가 다음 작업을 수행할 경우 충돌이 발생합니다.
- 최대 길이 텍스트 입력
- 무언가를 삽입합니다(길이 제한으로 인해 아무것도 삽입되지 않지만 iOS는 이에 대해 알지 못합니다).
- 삽입 실행 취소(범위가 실제 문자열 크기보다 크기 때문에 충돌이 발생함)
또한, iOS 13을 사용하는 사용자는 실수로 제스처에 의해 이것을 트리거할 수 있습니다.
당신의 프로젝트에 이것을 추가하는 것을 제안합니다.
extension String {
func replace(with text: String, in range: NSRange) -> String? {
// NOTE: NSString conversion is necessary to operate in the same symbol steps
// Otherwise, you may not be able to delete an emoji, for example
let current = NSString(string: self)
guard range.location + range.length <= current.length else { return nil }
return current.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
// NOTE: You may wanna trim the new text instead,
// so the user will able to shove his long text at least partially
}
그렇지 않으면 앱에서 지속적으로 충돌이 발생할 수 있습니다.
한 페이지에 다양한 길이 검사가 있는 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)
}
}
lazy var textField: UITextField = {
let textField = UITextField()
textField.addTarget(self, #selector(handleOnEditing), for .editingChanged)
return textField
}()
//ViewDidLoad textField.delegate = self에서 Delegate
@objc func handleOnEditing() {
let text = textField.text ?? ""
let limit = 10
textField.text = String(text.prefix(limit))
}
이러한 답변을 스크롤할 때 제가 찾던 답변을 완전히 이해할 수 없었습니다(그러나 저였을 수도 있습니다).한 보기 내에서 두 개의 텍스트 필드에 최대 문자를 설정하려고 합니다(다른 텍스트 필드를 확장하면 더 많은 문자를 설정할 수 있음).제가 찾은 해결책 중 가장 깨끗한 것은 확장이었습니다.여기 코드가 있습니다. VC와 textField를 사용하여 Place things를 조정하십시오.
extension PlaceYourViewControllerHere: UITextFieldDelegate {
private var maxCharacters: Int = 24
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
}
if textField == placeFirstTextfieldHere { maxCharacters = 64 } else { maxCharacters = 255 }
let substringToReplace = textFieldText[rangeOfTextToReplace]
let count = textFieldText.count - substringToReplace.count + string.count
return count <= maxCharacters
}
}
편집: textField에서 대리자를 설정하는 것을 잊지 마십시오.
textField.delegate = self
언급URL : https://stackoverflow.com/questions/31363216/set-the-maximum-character-length-of-a-uitextfield-in-swift
'programing' 카테고리의 다른 글
수동으로 jQuery 자동 완료 트리거 (0) | 2023.09.04 |
---|---|
mysql 쿼리를 통해 하나의 열을 다른 열로 복사 (0) | 2023.09.04 |
fs.readFileSync() 파일을 캡처하지 않는 방법은 무엇입니까? (0) | 2023.09.04 |
json 수신 및 spring mvc 컨트롤러에서 객체 목록으로 역직렬화 (0) | 2023.09.04 |
현재 클래스의 이름을 가져오시겠습니까? (0) | 2023.09.04 |