Begrenzen Sie die Anzahl der Zeichen in uitextview


78

Ich gebe eine Textansicht, um eine Zeichenfolge zu twittern.

Ich wende die folgende Methode an, um die Anzahl der Zeichen auf 140 zu beschränken.

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

Der Code funktioniert einwandfrei, mit Ausnahme der ersten Bedingung, dass die Rücktaste nicht funktioniert. Angenommen, ich habe das Limit von 140 Zeichen erreicht, sodass die Methode falsch ausgibt und der Benutzer keine weiteren Zeichen einfügen kann. Wenn ich danach versuche, einige Zeichen zu löschen, verhält sich die Textansicht so, wie sie deaktiviert ist.

Die Frage lautet also: "Wie lösche ich Zeichen aus der Textansicht textview.textoder aktiviere sie wieder?"


Überprüfen Sie diese Antwort
Hemang

Antworten:


66

Sie sollten stattdessen für eine leere Zeichenfolge zu suchen, wie der Apfel Referenz sagt

Wenn der Benutzer die Entf-Taste drückt, beträgt die Länge des Bereichs 1, und ein leeres Zeichenfolgenobjekt ersetzt dieses einzelne Zeichen.

Ich denke, die Überprüfung, die Sie tatsächlich durchführen möchten, ist so etwas wie [[textView text] length] - range.length + text.length > 140, um Ausschneide- / Einfügevorgänge zu berücksichtigen.


danke aber kann genauer sein Ich kann die technische Spezifikation von apple
harshalb

Sag mir einfach, was ich in die erste Bedingung setzen soll. Ich gooling dafür für fast 4 Stunden
harshalb

9
Ich denke, die Überprüfung, die Sie tatsächlich durchführen möchten, ist so etwas wie [[textView text] length] - range.length + text.length > 140, um Ausschneide- / Einfügevorgänge zu berücksichtigen.
David Gelhar

2
[[textView text] length] - range.length + text.length> 140 sollte [[textView text] length] - range.length + text.length <140
Kuzon

Kuzon, nicht, wenn Sie standardmäßig true zurückgeben und false zurückgeben möchten, wenn Sie das Limit von 140 Zeichen überschreiten.
Stein

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

Dies ermöglicht es Benutzern, Text auszuschneiden oder Zeichenfolgen zu löschen, die länger als ein einzelnes Zeichen sind (dh wenn sie die Rücktaste auswählen und dann drücken), oder einen Bereich hervorzuheben und Zeichenfolgen einzufügen, die kürzer oder länger als diese sind.

Swift 4.0 Version

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

Ist das eine IBAction? Wie verbinde ich es als Benutzertyp mit der betreffenden Textansicht?
Lerner

1
Müssen Sie Ihren Ansichts-Controller zu einem UITextViewDelegate machen und dann den Eigentümer der Datei als Delegierten der Textansicht verbinden
Tim

Ich dachte, es wäre fairer, eine Folgefrage zu stellen: Ich habe Probleme mit zwei UITextviews, für die Zeichenbeschränkungen im selben Controller erforderlich sind. Würdest du bitte helfen? stackoverflow.com/questions/25272413/…
Lernender

Dies sollte als die richtige Antwort markiert werden. Vielen Dank
Hernan Arber

Dies führt zu einem Absturz, wenn Sie einen Text einfügen, der zu lang ist, um zu passen (daher zurückgegeben falsewird), und dann versuchen, die Aktion rückgängig zu machen.
Raimundas Sakalauskas

18

für schnell 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

Sie können jedoch auch den folgenden Arbeitscode verwenden.

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

    NSInteger restrictedLength=140;

    NSString *temp=textView.text;

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

Im Allgemeinen nicht die bevorzugte Methode, um etwas zu bearbeiten, nachdem es festgelegt wurde. Überprüfen Sie dies besser in "shouldChangeCharactersInRange", um zu verhindern, dass Text bearbeitet wird.
Benjamin Piette

6

Versuchen Sie unter Swift 5 und iOS 12 die folgende Implementierung einer textView(_:shouldChangeTextIn:replacementText:)Methode, die Teil des UITextViewDelegateProtokolls ist:

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
}
  • Der wichtigste Teil dieses Codes ist die Konvertierung von range( NSRange) nach rangeOfTextToReplace( Range<String.Index>). In diesem Video-Tutorial erfahren Sie , warum diese Konvertierung wichtig ist.
  • Damit dieser Code ordnungsgemäß funktioniert, sollten Sie auch den Wert von textField' smartInsertDeleteTypeauf setzen UITextSmartInsertDeleteType.no. Dies verhindert das mögliche Einfügen eines (unerwünschten) zusätzlichen Speicherplatzes beim Ausführen eines Einfügevorgangs.

Der komplette Beispielcode unten zeigt , wie zur Umsetzung textView(_:shouldChangeTextIn:replacementText:)in ein 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

Schnell:

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

countElementswurde ersetzt durch countin Swift 1.2
Tim Windsor Brown

1
und in Swift 2 müssen Sie textView.text.characters.count oder eine beliebige Codierung eingeben: developer.apple.com/swift/blog/?id=30
Heckscheibe

4

ue das

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

    int limit = 139;

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

}

Dies gibt nur 140 Zeichen ein und Sie können sie bei Bedarf löschen


3

Begrenzen Sie den Überlauf, nicht den gesamten Text!

Wenn Sie falsedie ...shouldChangeTextInRange...Delegate-Methode zurückgeben, beschränken Sie tatsächlich den gesamten Text, und die folgenden Situationen können so schwierig sein:

  • Kopieren und Einfügen
  • Wählen Sie einen Bereich des Textes aus und bearbeiten Sie ihn
  • Mit Auto vorschlagen
  • Verwendung der Spracheingabe (Sprachbefehl oder Diktat)

Also kannst du:

Begrenzen Sie einfach den Textüberlauf

Durch Entfernen zusätzlicher Zeichen:

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

Sie können es sogar im laufenden Betrieb tun ! indem Sie diesen Code in die Aktion des textViewoder textFieldmit dem .editingChangedEreignis einfügen .


2

Obwohl ich eine if-elseBedingung brauchte , funktionierte dies für mich:

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

Anfangs ist die Schaltfläche deaktiviert. Wenn Sie jedoch möchten, dass der Benutzer keinen leeren Test veröffentlichen kann, setzen Sie einfach eine Bedingung auf den Klick auf die Schaltfläche:

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

Das Problem mit einigen der oben gegebenen Antworten ist, dass ich beispielsweise ein Textfeld habe und ein Limit von 15 Zeichen festlegen muss, das nach Eingabe des 15. Zeichens beendet wird. aber sie erlauben nicht zu löschen. Das ist die Löschtaste funktioniert auch nicht. Da stand ich vor dem gleichen Problem. Kam mit der unten angegebenen Lösung heraus. Funktioniert perfekt für mich

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

Ich habe ein Textfeld, dessen Tag ich auf "6" gesetzt und das maximale Zeichenlimit auf 30 begrenzt habe. funktioniert in jedem Fall gut


1

@ Tim Gostony's Swift Version:

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

Hier gehen wir für die beste Passform. Anzahl der verbleibenden Zeichen anzeigen: 'n' Zeichen übrig.

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

Wenn Sie auch in der Lage sein möchten, Code bis zur maximalen Zeichenanzahl einzufügen, während Sie den Überlauf abschneiden und eine Anzahlbezeichnung aktualisieren:

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
}

Mit der Erweiterung:

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

Probieren Sie es aus: -

 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

Schreiben Sie den folgenden Code in die textView:shouldChangeTextInRange:replacementText:Methode:

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

0

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
}

0

Verwenden Sie den folgenden 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;
    }
}

wenn Bedingung zum Löschen von Zeichen aus der
Textansicht verwendet wird

0

Hier ist die einfachste Lösung, um den Benutzer auf die Eingabe der Zeichenanzahl in UITextFieldoder UITextViewin iOS Swift zu beschränken

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

Hinweis: Hier kann das Limit von 1bis nzu Ihren Anforderungen reichen, z. B.: Wenn Sie an einer Telefonnummer arbeiten limit, wird der Wert geändert , 10 wenn Sie dieselbe UITextViewMethode anwenden möchten. Die Methode wird geändert und an dem Ort verwendet, an dem textfieldSie verwendet werdentextview

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.