Сделать часть UITextView не удаляемой? - PullRequest
9 голосов
/ 25 февраля 2012

У меня есть UITextView, и мне нужно сделать определенную часть не удаляемой.Это первые 10 символов текста представлений.

Надеюсь, вы можете помочь, я просто хочу, чтобы, если пользователь нажимает клавишу удаления на клавиатуре, он просто останавливается, когда достигает, скажем, 10-го символа.

Надеюсь, что вы можете помочь, спасибо.

РЕДАКТИРОВАТЬ:

Progress1 Спасибо за ваши ответы, ребята, позвольте мне немного подробнее.

Допустим, префикс «123456789:».Я хочу иметь возможность печатать в любом месте после этого префикса, хотя он вообще не может быть редактируемым, поэтому '123456789:' не должен изменяться вообще.Ответ Fichek делает это отлично, однако префикс не всегда есть, так как я могу определить, когда его нет в текстовом представлении?Я думал, что заявление if сделало это, но, похоже, нет.

Ответы [ 3 ]

14 голосов
/ 25 февраля 2012

Вы можете использовать метод делегата textView:shouldChangeTextInRange:replacementText: Чтобы указать текстовому представлению, принимать или нет удаление.

Как указано в документации:

диапазон : текущий диапазон выбора.Если длина диапазона равна 0, диапазон отражает текущую точку вставки. Если пользователь нажимает клавишу Delete, длина диапазона равна 1, и пустой символ строки заменяет этот одиночный символ .

Редактировать

Вот реализация, в которой пользователь не может удалить первые десять символов.Но он сможет вставлять туда символы.

- (BOOL)textView:(UITextView *)textView shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (range.length==1 && string.length == 0) {
        // Deleting text
        if (range.location <= 9) {
            return NO;
        }
    }
    return YES;
}

Вот реализация, в которой он вообще не может изменить первые десять символов.

- (BOOL)textView:(UITextView *)textView shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (range.location <= 9) {
        return NO;
    }
    return YES;
}
8 голосов
/ 25 февраля 2012
Последнее редактирование

sch дает достойный ответ, но я хочу предложить немного более гибкий подход.

Вы должны иметь в виду систему копирования / вставки. Пользователь может выделить весь текст в текстовом поле и попытаться вставить все значение, которое может быть вполне приемлемым, но if (range.location <= 9) { return NO; } отклонит его. Для этого я собираю строку, которая будет результатом успешного редактирования, а затем проверяю, будет ли эта строка начинаться с желаемого префикса.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSString *resultString = [textField.text stringByReplacingCharactersInRange:range withString:string];
    NSLog(@"resulting string would be: %@", resultString);
    NSString *prefixString = @"blabla";
    NSRange prefixStringRange = [resultString rangeOfString:prefixString];
    if (prefixStringRange.location == 0) {
        // prefix found at the beginning of result string
        return YES;
    }
    return NO;
}

Редактировать: Если вы хотите проверить, начинается ли текущая строка в текстовом поле с префикса, вы можете использовать rangeOfString: таким же образом:

NSRange prefixRange = [textField.text rangeOfString:prefixString];
if (prefixRange.location == 0) {
    // prefix found at the beginning of text field
}
1 голос
/ 22 мая 2013

для полного решения вам необходимо обработать несколько случаев, включая операции вырезания и вставки, которые могут начинаться в не редактируемой части и распространяться на часть, которую пользователь может редактировать. Я добавил переменную, чтобы контролировать, допустима ли операция, которая включает в себя не редактируемую часть, но распространяется на редактируемую часть. Если он действителен, диапазон корректируется, чтобы влиять только на редактируемую часть.

// if a nil is returned, the change is NOT allowed
- (NSString *)allowChangesToTextView:(UITextView *)textView inRange:(NSRange)changeRange withReplacementText:(NSString *)text
                       immutableUpTo:(NSInteger)lastReadOnlyChar adjustRangeForEdits:(BOOL)adjustRangeForEdits;
{
    NSString *resultString = @"";

    NSString *currentText = textView.text;
    NSInteger textLength = [currentText length];

    // if trying to edit the first part, possibly prevent it.
    if (changeRange.location <= lastReadOnlyChar)
    {
        // handle typing or backspace in protected range.
        if (changeRange.length <= 1)
        {
            return nil;
        }

        // handle all edits solely in protected range
        if ( (changeRange.location + changeRange.length) <= lastReadOnlyChar)
        {
            return nil;
        }

        // if the user wants to completely prevent edits that extend into the
        // read only substring, return no
        if (!adjustRangeForEdits)
        {
            return nil;
        }

        // the range includes read only part but extends into editable part.
        // adjust the range so that it does not include the read only portion.

        NSInteger prevLastChar = changeRange.location + changeRange.length - 1;
        NSRange newRange =  NSMakeRange(lastReadOnlyChar +  1, prevLastChar - (lastReadOnlyChar +  1) + 1);

        resultString = [textView.text stringByReplacingCharactersInRange:newRange withString:text];

        return resultString;
    }

    // the range does not include the immutable part.  Make the change and return the string
    resultString = [currentText stringByReplacingCharactersInRange:changeRange withString:text];
    return resultString;
}

и вот как он вызывается из метода делегата текстового представления:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    // did the user press enter?
    if ([text isEqualToString:@"\n"])
    {
        [textView resignFirstResponder];
        return NO;
    }

    NSInteger endOfReadOnlyText = [self.spotTextLastSet length] - 1;
    NSString *newText = [self allowChangesToTextView:textView inRange:range withReplacementText:text
                                       immutableUpTo:endOfReadOnlyText adjustRangeForEdits:YES];

    if (newText == nil)
    {
        // do not allow!
        [TipScreen showTipTitle:@"Information" message:@"The first part of the text is not editable.  Please add your comments at the end."
                      ForScreen:@"editWarning"];
        return NO;
    }

    // lets handle the edits ourselves since we got the result string.
    textView.scrollEnabled = NO;
    textView.text = newText;


    // move the cursor to change range start + length of replacement text
    NSInteger newCursorPos = range.location + [text length];
    textView.selectedRange = NSMakeRange(newCursorPos, 0);
    textView.scrollEnabled = YES;

    return NO;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...