Обмежте кількість символів у uitextview


80

Я даю текстове подання, щоб твітувати якийсь рядок.

Я застосовую наступний метод, щоб обмежити кількість символів до 140.

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
   return [[textView text] length] <= 140;
}

Код працює добре, крім першої умови, що зворотний простір не працює. припустимо, що я досяг обмеження в 140 символів, так що метод дасть мені помилку, і користувач не може вставити більше символів, але після цього, коли я намагаюся видалити деякі символи, текстовий режим поводиться так, як він вимкнений.

Тож питання: "Як видалити символи з textview.textтекстового подання або ввімкнути його знову?"


Перевірте цю відповідь
Hemang

Відповіді:


67

Натомість вам слід шукати порожній рядок, як сказано в посиланні на apple

Якщо користувач натискає клавішу Delete, довжина діапазону дорівнює 1, а порожній рядок замінює цей єдиний символ.

Я думаю, що перевірка, яку ви насправді хочете зробити, - це щось на зразок [[textView text] length] - range.length + text.length > 140обліку операцій вирізання / вставки.


спасибі, але можу бути більш конкретним. Я не можу зрозуміти технічну специфікацію apple
harshalb

просто скажи мені, що я повинен поставити в першу умову. Я готуюся для цього майже 4 години
harshalb

9
Я думаю, що перевірка, яку ви насправді хочете зробити, - це щось на зразок [[textView text] length] - range.length + text.length > 140обліку операцій вирізання / вставки.
Девід Гелхар,

2
[[textView text] length] - range.length + text.length> 140 має бути [[textView text] length] - range.length + text.length <140
Кузон

Кузон, не якщо ви повертаєте true за замовчуванням і хочете повернути false, якщо перевищили межу 140 символів.
камінь

165
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    return textView.text.length + (text.length - range.length) <= 140;
}

Це стосується того, що користувачі вирізають текст або видаляють рядки довші за один символ (тобто, якщо вони вибирають, а потім натискають зворотний простір), або виділяють діапазон і вставляють рядки, коротші чи довші за нього.

Версія Swift 4.0

 func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    return textView.text.count + (text.count - range.length) <= 140
}

це IBA-дія? як підключити його до розглянутого TextView як типи користувачів?
учень

1
Потрібно зробити свій контролер подання UITextViewDelegate, а потім підключити власника файлу як делегата текстового подання
Тім,

Я вважав, що було б справедливішим задати наступне запитання: у мене проблеми з двома UITextviews, які потребують обмежень символів в одному контролері. Будь ласка, допоможіть? stackoverflow.com/questions/25272413/…
учень

Це слід позначити як правильну відповідь. Дякую
Hernan Arber

Це призведе до аварійного завершення роботи, якщо ви вставите текст, який занадто довгий, щоб вмістити його (тому falseбуде повернено), а потім ви спробуєте скасувати дію.
Раймундас Сакалаускас

18

для швидкого 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
}

10

Однак ви також можете використовувати нижче робочий код.

- (void)textViewDidChange:(UITextView *)textView{

    NSInteger restrictedLength=140;

    NSString *temp=textView.text;

    if([[textView text] length] > restrictedLength){
        textView.text=[temp substringToIndex:[temp length]-1];
    }
}

Як правило, не кращий спосіб редагувати щось після встановлення. Краще перевірити це в "shouldChangeCharactersInRange", щоб запобігти редагуванню тексту.
Benjamin Piette

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«S 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
    }

}

5

Стрімкий:

// 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;
}

countElementsбуло замінено на countшвидкий 1.2
Тім Віндзор Браун

1
а в Swift 2 ви повинні передати textView.text.characters.count або будь-яке інше кодування, яке ви хочете: developer.apple.com/swift/blog/?id=30
Heckscheibe

4

ue це

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{

    int limit = 139;

    return !([textField.text length]>limit && [string length] > range.length);

}

це введе лише 140 символів, і ви можете видалити їх, якщо потрібно


4

Обмежте переповнення, а не весь текст!

Повертаючись falseу ...shouldChangeTextInRange...методі делегата, ви фактично обмежуєте весь текст, і вирішення таких ситуацій може бути настільки важким:

  • Скопіюйте та вставте
  • Виділіть область тексту та відредагуйте
  • Використовуючи автоматичну пропозицію
  • Використання голосового введення (голосова команда або диктант)

Отже, ви можете:

Просто обмежте переповнення тексту

Видаливши зайві символи:

textView.text = String(textView.text.prefix(140))

Ви можете це зробити навіть на льоту ! поставивши цей код усередині дії з textViewабо textFieldз .editingChangedподією.


Красиво розмістивши це в роботах делегата UITextView func textViewDidChange(_ textView: UITextView) {...}, лише обрізавши кінець довгого вставленого тексту
Джосселін,

2

Хоча мені потрібна була 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
}

1

Проблема з деякою з наведених вище відповідей полягає в тому, що, наприклад, у мене є текстове поле, і я повинен встановити обмеження на 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", і я обмежив максимальне обмеження символів = 30; чудово працює у кожному випадку


1

Швидка версія @Tim Gostony:

// 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;
}

1

Тут ми ідемо до найкращої форми. Відобразити кількість символів, що залишились: залишилося '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
}

1

Якщо ви також прагнете мати можливість вставити код до максимальної кількості символів, одночасно вирізавши переповнення та оновивши мітку підрахунку:

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
    }
}

1

Спробуйте це: -

 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
}

0

Напишіть нижче код у textView:shouldChangeTextInRange:replacementText:методі:

if ([textView.text length]>=3 && ![text isEqualToString:@""]) {
    return NO;
}
return YES;

0

Свіфт5:

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
}

0

Використовуйте наступний код.

- (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;
    }
}

якщо умова використовується для видалення символів з текстового подання
Vikas Grandhi

0

Ось найпростіший спосіб обмежити користувачеві швидке введення кількості символів у UITextFieldабо UITextViewв iOS

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool 
{
   return textField.text!.count < limit ? true : false
}

Примітка: тут ліміт може бути будь-яким від 1до nвідповідно до вашої вимоги, наприклад: якщо ви працюєте над номером телефону, limitзначення буде, 10 якщо ви хочете застосувати те саме для UITextViewсправедливого методу буде змінено, і на місці, де textfieldви будете використовуватиtextview

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.