Podaję widok tekstu, aby opublikować jakiś ciąg.
Stosuję następującą metodę, aby ograniczyć liczbę znaków do 140 długości.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
return [[textView text] length] <= 140;
}
Kod działa dobrze, z wyjątkiem pierwszego warunku, że nie działa backspace. przypuszczam, że osiągnąłem limit 140 znaków, więc metoda da mi fałsz i użytkownik nie może wstawić więcej znaków, ale po tym, gdy próbuję usunąć niektóre znaki, widok tekstu zachowuje się tak, jakby był wyłączony.
Zatem pytanie brzmi: „Jak usunąć znaki z textview.text
widoku tekstu lub ponownie go włączyć?”
ios
iphone
uitextview
uitextviewdelegate
harshalb
źródło
źródło
Odpowiedzi:
Zamiast tego powinieneś szukać pustego ciągu, jak mówi odniesienie do jabłka
Myślę, że czek, który faktycznie chcesz wykonać, to coś w rodzaju
[[textView text] length] - range.length + text.length > 140
uwzględnienia operacji wytnij / wklej.źródło
[[textView text] length] - range.length + text.length > 140
uwzględnienia operacji wytnij / wklej.- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { return textView.text.length + (text.length - range.length) <= 140; }
Dotyczy to użytkowników wycinania tekstu lub usuwania ciągów dłuższych niż pojedynczy znak (tj. Jeśli wybierają, a następnie wciskają klawisz Backspace) lub podświetlania zakresu i wklejania ciągów krótszych lub dłuższych od niego.
Wersja Swift 4.0
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { return textView.text.count + (text.count - range.length) <= 140 }
źródło
false
zostanie zwrócony), a następnie spróbujesz cofnąć akcję.dla swift 4:
//MARK:- TextView Delegate func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { //300 chars restriction return textView.text.count + (text.count - range.length) <= 300 }
źródło
Jednak możesz również użyć poniższego działającego kodu.
- (void)textViewDidChange:(UITextView *)textView{ NSInteger restrictedLength=140; NSString *temp=textView.text; if([[textView text] length] > restrictedLength){ textView.text=[temp substringToIndex:[temp length]-1]; } }
źródło
W przypadku Swift 5 i iOS 12 wypróbuj następującą implementację
textView(_:shouldChangeTextIn:replacementText:)
metody, która jest częściąUITextViewDelegate
protokołu:func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { guard let rangeOfTextToReplace = Range(range, in: textView.text) else { return false } let substringToReplace = textView.text[rangeOfTextToReplace] let count = textView.text.count - substringToReplace.count + text.count return count <= 10 }
range
(NSRange
) narangeOfTextToReplace
(Range<String.Index>
). Obejrzyj ten samouczek wideo, aby zrozumieć, dlaczego ta konwersja jest ważna.textField
„ssmartInsertDeleteType
wartościUITextSmartInsertDeleteType.no
. Zapobiegnie to ewentualnemu wstawieniu (niechcianej) dodatkowej przestrzeni podczas wykonywania operacji wklejania.Pełny przykładowy kod poniżej pokazuje, jak zaimplementować
textView(_:shouldChangeTextIn:replacementText:)
wUIViewController
:import UIKit class ViewController: UIViewController, UITextViewDelegate { @IBOutlet var textView: UITextView! // Link this to a UITextView in Storyboard override func viewDidLoad() { super.viewDidLoad() textView.smartInsertDeleteType = UITextSmartInsertDeleteType.no textView.delegate = self } func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { guard let rangeOfTextToReplace = Range(range, in: textView.text) else { return false } let substringToReplace = textView.text[rangeOfTextToReplace] let count = textView.text.count - substringToReplace.count + text.count return count <= 10 } }
źródło
Szybki:
// MARK: UITextViewDelegate let COMMENTS_LIMIT = 255 func textView(textView: UITextView, shouldChangeTextInRange range:NSRange, replacementText text:String ) -> Bool { return count(comments.text) + (count(text) - range.length) <= COMMENTS_LIMIT; }
źródło
countElements
został zastąpiony przezcount
swift 1.2z tego
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { int limit = 139; return !([textField.text length]>limit && [string length] > range.length); }
spowoduje to wprowadzenie tylko 140 znaków i możesz je usunąć w razie potrzeby
źródło
Ogranicz przepełnienie, a nie cały tekst!
Wracając
false
w...shouldChangeTextInRange...
metodzie delegata, w rzeczywistości ograniczasz cały tekst, a obsługa następujących sytuacji może być bardzo trudna:Więc możesz:
Po prostu ogranicz przepełnienie tekstu
Usuwając dodatkowe znaki:
textView.text = String(textView.text.prefix(140))
Możesz to zrobić nawet w locie ! umieszczając ten kod wewnątrz działania z
textView
lubtextField
z.editingChanged
imprezy.źródło
func textViewDidChange(_ textView: UITextView) {...}
działa pięknie, przycinając tylko koniec długo wklejonego tekstuChociaż potrzebowałem
if-else
warunku, więc to zadziałało:- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { BOOL status = textView.text.length + (text.length - range.length) <= 15; if (status) { [self.btnShare setEnabled:YES]; [self.btnShare setAlpha:1]; } else { [self.btnShare setEnabled:NO]; [self.btnShare setAlpha:0.25]; } return status; }
W zasadzie przycisk jest wyłączony. Ale jeśli chcesz, aby użytkownik nie mógł opublikować pustego testu, po prostu umieść warunek na kliknięciu przycisku:
- (void)btnShare_click:(id)sender { NSString *txt = [self.txtShare.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; if ([txt length] == 0) { [self.btnShare setEnabled:NO]; [self.btnShare setAlpha:0.25f]; [[[UIAlertView alloc]initWithTitle:nil message:@"Please enter some text to share." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; return; } . . . . . . // rest of your code }
źródło
Problem z niektórymi odpowiedziami podanymi powyżej jest taki, że na przykład mam pole tekstowe i muszę ustawić limit 15 znaków, a następnie zatrzymuje się po wpisaniu 15 znaku. ale nie pozwalają na usunięcie. Oznacza to, że przycisk usuwania również nie działa. Ponieważ miałem ten sam problem. Wyszedł z rozwiązaniem, podanym poniżej. Działa idealnie dla mnie
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if(textField.tag==6) { if ([textField.text length]<=30) { return YES; } else if([@"" isEqualToString:string]) { textField.text=[textField.text substringToIndex:30 ]; } return NO; } else { return YES; } }
Mam pole tekstowe, którego tag ustawiłem na „6” i ograniczyłem maksymalny limit znaków = 30; działa dobrze w każdym przypadku
źródło
Szybka wersja @Tima Gostony'ego:
// restrict the input for textview to 500 func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { return count(textView.text) + (count(text) - range.length) <= 500; }
źródło
Tutaj dążymy do najlepszego dopasowania. Wyświetl liczbę pozostałych znaków: pozostało „n” znaków.
var charCount = 0; let maxLength = 150 func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { if text == "" // Checking backspace { if textView.text.characters.count == 0 { charCount = 0 characterCount.text = String(format: "%i Characters Left", maxLength - charCount) return false } charCount = (textView.text.characters.count - 1) characterCount.text = String(format: "%i Characters Left", maxLength - charCount) return true } else { charCount = (textView.text.characters.count + 1) characterCount.text = String(format: "%i Characters Left", maxLength - charCount) if charCount >= maxLength + 1 { charCount = maxLength characterCount.text = String(format: "%i Characters Left", maxLength - charCount) return false; } } return true }
źródło
Jeśli chcesz również wkleić kod do maksymalnej liczby znaków, jednocześnie odcinając przepełnienie i aktualizując etykietę licznika:
let maxChar: Int let countLabel: UILabel func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { let oldChar = textView.text.count - range.length let oldRemainingChar = maxChar - oldChar let newChar = oldChar + text.count let newRemainingChar = maxChar - newChar let replaceChar = newRemainingChar > 0 ? text.count : oldRemainingChar if let textRange = textView.textRange(for: range), replaceChar > 0 || range.length > 0 { textView.replace(textRange, withText: String(text.prefix(replaceChar))) countLabel.text = String(describing: maxChar - textView.text.count) } return false }
Z rozszerzeniem:
extension UITextInput { func textRange(for range: NSRange) -> UITextRange? { var result: UITextRange? if let start = position(from: beginningOfDocument, offset: range.location), let end = position(from: start, offset: range.length) { result = textRange(from: start, to: end) } return result } }
źródło
Wypróbuj to: -
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { print("chars \(textView.text.count) \( text)") if(textView.text.count > 20 && range.length == 0) { print("Please summarize in 20 characters or less") return false } return true }
źródło
Wpisz poniższy kod w
textView:shouldChangeTextInRange:replacementText:
metodzie:if ([textView.text length]>=3 && ![text isEqualToString:@""]) { return NO; } return YES;
źródło
Swift5:
let maxChars = 255 func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { if maxChars - aTextView.text.count == 0 { if range.length != 1 { return false } } return true }
źródło
Użyj poniższego kodu.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { if(text.length == 0) { return YES; } else if(self.txtViewComments.text.length > 255) { return NO; } else { return YES; } }
źródło
Oto najprostsze rozwiązanie do ograniczania użytkownika, aby wprowadzić liczbę w charakterze
UITextField
lubUITextView
w iOS swiftfunc textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { return textField.text!.count < limit ? true : false }
Uwaga: tutaj limit może być dowolny, od
1
don
zgodnie z wymaganiami, na przykład: jeśli pracujesz na numerze telefonu,limit
wartość będzie,10
jeśli chcesz zastosować to samo,UITextView
tylko metoda zostanie zmieniona iw miejscu, wtextfield
którym będziesz używanytextview
źródło