Ограничить количество символов в uitextview
Я даю текстовое представление для твита некоторой строки.
Я применяю следующий метод для ограничения количества символов до 140.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
if([text isEqualToString:@"\b"]){
DLog(@"Ohoooo");
return YES;
}else if([[textView text] length] > 140){
return NO;
}
return YES;
}
Код работает хорошо, кроме первого условия, что backspace не работает.
предположим, что я достиг предела в 140 символов, чтобы метод дал мне ложь, и пользователь не может вставить больше символов, но после этого, когда я пытаюсь удалить некоторые символы, текстовое представление ведет себя так, как будто оно отключено.
Итак, вопрос о том, как удалить символы из textview.text
или снова включить текстовое представление.
Ответы
Ответ 1
Вместо этого вы должны искать пустую строку, поскольку ссылка на яблоко говорит
Если пользователь нажимает клавишу "Удалить", длина диапазона равна 1, а пустой строковый объект заменяет этот единственный символ.
Я думаю, что проверка, которую вы действительно хотите сделать, это что-то вроде [[textView text] length] - range.length + text.length > 140
, для учета операций вырезания/вставки.
Ответ 2
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
return textView.text.length + (text.length - range.length) <= 140;
}
Это позволяет пользователям вырезать текст или удалять строки длиннее одного символа (т.е. Если они выбирают и затем нажимают клавишу Backspace), либо выделять диапазон и вставлять строки короче или длиннее его.
Версия Swift 4.0
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
return textView.text.count + (text.count - range.length) <= 140
}
Ответ 3
для быстрой 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
}
Ответ 4
Однако вы также можете использовать ниже рабочий код.
- (void)textViewDidChange:(UITextView *)textView{
NSInteger restrictedLength=140;
NSString *temp=textView.text;
if([[textView text] length] > restrictedLength){
textView.text=[temp substringToIndex:[temp length]-1];
}
}
Ответ 5
ue this
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int limit = 139;
return !([textField.text length]>limit && [string length] > range.length);
}
это будет вводить только 140 char, и вы можете удалить их, если нужно
Ответ 6
Swift:
// 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;
}
Ответ 7
В Swift 5 и iOS 12 попробуйте следующую реализацию метода textView(_:shouldChangeTextIn:replacementText:)
который является частью протокола UITextViewDelegate
:
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
) в rangeOfTextToReplace
(Range<String.Index>
). Посмотрите этот видеоурок, чтобы понять, почему это преобразование важно. - Чтобы этот код работал правильно, вы также должны установить значение
textField
smartInsertDeleteType
в UITextSmartInsertDeleteType.no
. Это предотвратит возможную вставку (нежелательного) дополнительного пространства при выполнении операции вставки.
Полный пример кода ниже показывает, как реализовать textView(_:shouldChangeTextIn:replacementText:)
в UIViewController
:
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
}
}
Ответ 8
Хотя мне нужно условие if-else
, поэтому это сработало для меня:
- (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;
}
Внутри кнопка отключена. Но если вы хотите, чтобы пользователь не мог опубликовать пустой тест, просто поставьте условие на нажатие кнопки:
- (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
}
Ответ 9
Проблема с некоторыми из приведенных выше ответов: Например, у меня есть текстовое поле, и я должен установить ограничение на 15 символов, а затем останавливается после ввода 15-го символа. но они не позволяют удалять. То есть кнопка удаления также не работает. Поскольку я столкнулся с той же проблемой. Вышел с решением, приведенным ниже. Работает идеально для меня
- (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;
}
}
У меня есть текстовое поле, чей тег я установил "6"
и я ограничил max char limit = 30;
отлично работает в каждом случае
Ответ 10
@Tim Gostony Swift Версия:
// 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;
}
Ответ 11
Здесь мы идем для наилучшего соответствия.
Отобразите оставшееся количество символов: осталось 'n'.
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
}
Ответ 12
Попробуйте следующее: -
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
print("chars \(textView.text.characters.count) \( text)")
if(textView.text.characters.count > 20 && range.length == 0) {
print("Please summarize in 20 characters or less")
return false;
}
return true;
}
Ответ 13
Если вы также хотите вставить код до максимального количества символов, одновременно сократив переполнение и обновив метку счетчика:
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
}
С расширением:
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
}
}
Ответ 14
Запишите код ниже в textView:shouldChangeTextInRange:replacementText:
:
if ([textView.text length]>=3 && ![text isEqualToString:@""]) {
return NO;
}
return YES;
Ответ 15
Use the following code...
- (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;
}
}
Ответ 16
Swift - однострочный код
Просто ограничьте текст числом сразу после любых изменений:
textView.text = String(textView.text.prefix(250))