Как отклонить клавиатуру для UITextView с клавишей возврата?

382

В библиотеке IB введение говорит нам, что при returnнажатии клавиши клавиатура для UITextViewисчезнет. Но на самом деле returnключ может действовать только как \ n.

Я могу добавить кнопку и использовать, [txtView resignFirstResponder]чтобы скрыть клавиатуру.

Но есть ли способ добавить действие для returnклавиши на клавиатуре, чтобы мне не нужно было добавлять UIButton?

Холодный чжун
источник
Следуйте инструкциям в этом блоге: iphonedevelopertips.com/cocoa/…
ManojN

Ответы:

354

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

Даже тогда, если вы хотите сделать это, реализуйте textView:shouldChangeTextInRange:replacementText:метод UITextViewDelegateи в этой проверке, если текст замены \n, скрыть клавиатуру.

Могут быть и другие способы, но я не знаю ни одного.

lostInTransit
источник
1
Спасибо, и метод работает хорошо. Причиной использования UITextView является то, что он может содержать текст в несколько строк. И теперь я использую это как окно сообщения.
Chilly Zhong
28
Достаточно просто изменить ключ возврата на «готово», используя любой из них [textField setReturnKeyType: UIReturnKeyDone];или используя построитель интерфейса
Casebash
9
Хорошо, теперь я понимаю, что Apple заканчивает работу с многострочным текстовым полем, добавляя
готовый
8
Это не очень хороший способ решить эту проблему, потому что вы запрещаете пользователю использовать ввод для выхода с клавиатуры. Вероятно, лучший способ - добавить кнопку, которая выполняет метод resignFirstResponder.
Ele
5
@Casebash. Кажется, что установка ключа возврата в «готово» не решает проблему в Xcode 6.4, Swift 2.0. Я установил ключ с помощью IB.
MB_iOSDeveloper
505

Я подумал, что вместо этого выложу фрагмент:

Убедитесь, что вы объявили о поддержке UITextViewDelegateпротокола.

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

    if([text isEqualToString:@"\n"]) {
        [textView resignFirstResponder];
        return NO;
    }

    return YES;
}

Обновление Swift 4.0:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" {
        textView.resignFirstResponder()
        return false
    }
    return true
}
samvermette
источник
75
Проблема в том, что на самом деле это не способ обнаружить, что пользователь нажал клавишу возврата . Пользователь может вставить символ возврата в текстовое поле, и вы получите то же сообщение делегата. В основном вы неправильно используете текстовое представление. Способ отклонить клавиатуру: (1) вообще не делать этого (как при составлении сообщения в приложении «Почта») или (2) иметь кнопку «Готово» в другом месте интерфейса (как в приложении Notes). Например, к клавиатуре можно прикрепить такую ​​кнопку, как вид аксессуара.
Мэтт
@ Сэм V, этот фрагмент был классным человеком. меня устраивает. спасибо тонна человек. Есть ли какой-нибудь фрагмент для снятия числовой клавиатуры. С уважением Shishir
Shishir.bobby
Великолепный. Просто напоминание о том, что в некоторых ситуациях, чтобы избавиться от клавиатуры, попробуйте вдоль линий ... [self.view endEditing: YES];
Толстяк
@ Войто, отлично работает на iPad. Вы, вероятно, не установили делегата.
Винсент
4
Проблема в том, что клавиатура может скрывать часть интерфейса, которая используется для отклонения. Действительно абсурдно, что в IOS нет кнопки на каждой клавиатуре, предназначенной для отклонения клавиатуры, чтобы пользователь мог сделать это, если пожелает.
Сани Elfishawy
80

Я знаю, что на этот вопрос уже дан ответ, но мне не очень нравится использовать строковый литерал для новой строки, так что вот что я сделал.

- (BOOL)textView:(UITextView *)txtView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if( [text rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]].location == NSNotFound ) {
        return YES;
    }

    [txtView resignFirstResponder];
    return NO;
}

Обновление Swift 4.0:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if (text as NSString).rangeOfCharacter(from: CharacterSet.newlines).location == NSNotFound {
    return true
}
txtView.resignFirstResponder()
return false
}
ribeto
источник
6
Я мог бы изменить его следующим образом: NSRange resultRange = [text rangeOfCharacterFromSet: [NSCharacterSet newlineCharacterSet] options: NSBackwardsSearch]; Поскольку в любом случае это хак, кажется, что проверка конца строки для возврата может быть более безопасным маршрутом.
maxpower
@maxpower Очень хороший комментарий. Кроме того, лучше сверяться с замененным текстом, например NSString *replacedText = [textView.text stringByReplacingCharactersInRange:range withString:text].
Рудольф Адамкович
Представьте себе пользователя, вставляющего некоторый текст, скопированный из другого места, который содержит новую строку. Вероятно, они будут сбиты с толку, когда вместо добавления текста приложение просто отклоняет клавиатуру.
Николай Рюэ
44

Я знаю, что на это отвечали много раз, но вот мои два цента на проблему.

Я нашел ответы samvermette и ribeto очень полезными, а также комментарий maxpower в ответе ribeto . Но есть проблема с этими подходами. Проблема, матовое упоминает в samvermette «s ответ , и это то , что если пользователь хочет , чтобы вставить что - то с разрывом строки внутри него, клавиатура пряталась без вставки ничего.

Таким образом, мой подход представляет собой смесь трех вышеупомянутых решений и проверяет, является ли введенная строка новой строкой, когда длина строки равна 1, поэтому мы проверяем, что пользователь печатает вместо вставки.

Вот что я сделал:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    NSRange resultRange = [text rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:NSBackwardsSearch];
    if ([text length] == 1 && resultRange.location != NSNotFound) {
        [textView resignFirstResponder];
        return NO;
    }

    return YES;
}
josebama
источник
Это лучшее решение для этой проблемы. Ответ samvermette не учитывает ситуацию, когда пользователь хочет вставить текст.
marcopaivaf
36

Более элегантный способ - убрать клавиатуру, когда пользователь нажимает где-то за рамкой клавиатуры.

Сначала установите представление ViewController для класса «UIControl» в инспекторе идентичности в UIBuilder. Удерживая клавишу «Control», перетащите представление в файл заголовка ViewController и свяжите его как действие с событием «Touch Up Inside», например:

ViewController.h

-(IBAction)dismissKeyboardOnTap:(id)sender;

В основном файле ViewController ViewController.m:

-(IBAction)dismissKeyboardOnTap:(id)sender
    {
         [[self view] endEditing:YES];
    }

Вы можете требовать двойного касания или длительного касания, используя аналогичные приемы. Возможно, вам понадобится установить ваш ViewController как UITextViewDelegate и подключить TextView к ViewController. Этот метод работает как для UITextView, так и для UITextField.

Источник: Ранчо Большого Ботаника

РЕДАКТИРОВАТЬ: Я также хотел бы добавить, что если вы используете UIScrollView, вышеупомянутая техника может работать не так легко через Interface Builder. В этом случае вы можете использовать UIGestureRecognizer и вызвать вместо него метод [[self view] endEditing: YES] внутри него. Примером может быть:

-(void)ViewDidLoad{
    ....
    UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc] 
        initWithTarget:self action:@selector(tap:)];
    [self.view addGestureRecognizer: tapRec];
    ....
}

-(void)tap:(UITapGestureRecognizer *)tapRec{
    [[self view] endEditing: YES];
}

Когда пользователь нажимает за пределами клавиатуры и не нажимает пробел, клавиатура отклоняется.

TMilligan
источник
1
Мне нравится идея, GestureRecognizerно огромная проблема заключается в том, что все кнопки или элемент управления в представлении больше не активируются.
эксперт
35

Добавьте этот метод в свой контроллер представления.

Свифт :

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" {
        textView.resignFirstResponder()
        return false
    }
    return true
}

Этот метод также может быть полезен для вас:

/**
Dismiss keyboard when tapped outside the keyboard or textView

:param: touches the touches
:param: event   the related event
*/
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    if let touch = touches.anyObject() as? UITouch {
        if touch.phase == UITouchPhase.Began {
            textField?.resignFirstResponder()
        }
    }
}
Александр Волков
источник
2
Не забудьте подтвердить протокол UITextViewDelegate :)
swiftBoy
Я не думаю, что это хорошая идея переопределить прикосновения Began и не звонить super.touchesBegan(touches:withEvent:).
TGO
Чтобы выразить симметричность этого кода, вы должны написать else { return true }.
значение имеет значение
@ значение - не имеет значения
Александр Волков
@AlexanderVolkov Вы не согласны с тем, что это симметричная ситуация, вы не знаете, что я имею в виду, вы не верите в ценность семантически правильного кода или ...?
значение имеет значение
26
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if([text isEqualToString:@"\n"])
        [textView resignFirstResponder];
    return YES;
}

yourtextView.delegate=self;

Также добавьте UITextViewDelegate

Не забудьте подтвердить протокол

Если вы не добавили, if([text isEqualToString:@"\n"])вы не можете редактировать

Винееш ТП
источник
2
-1 Это просто худшая версия ответа самверметта. Вы пропустили возврат, NOесли текст равен @"\n".
devios1
17

Существует другое решение при использовании с uitextview. Вы можете добавить панель инструментов как InputAccessoryView в «textViewShouldBeginEditing», и с помощью кнопки «Готово» на этой панели инструментов вы можете отклонить клавиатуру, код для этого следующий:

В viewDidLoad

toolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)]; //toolbar is uitoolbar object
toolBar.barStyle = UIBarStyleBlackOpaque;
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(btnClickedDone:)];
[toolBar setItems:[NSArray arrayWithObject:btnDone]];

В методе textviewdelegate

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
     [textView setInputAccessoryView:toolBar];
     return YES;
}

В действии кнопки «Готово», которая находится на панели инструментов, следующее:

-(IBAction)btnClickedDone:(id)sender
{
    [self.view endEditing:YES];
}
g212gs
источник
17

Я нашел ответ Джозебамы самым полным и чистым ответом, доступным в этой теме.

Ниже приведен синтаксис Swift 4 для него:

func textView(_ textView: UITextView, shouldChangeTextIn _: NSRange, replacementText text: String) -> Bool {
    let resultRange = text.rangeOfCharacter(from: CharacterSet.newlines, options: .backwards)
    if text.count == 1 && resultRange != nil {
        textView.resignFirstResponder()
        // Do any additional stuff here
        return false
    }
    return true
}
Пунит Кохли
источник
Цель resultRangeсостоит в том, чтобы проверить, содержит ли текст только новые строки, которые избегают жесткого кода "\ n".
Цинхуа,
6

быстрый

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" {
        textView.resignFirstResponder()
    }
    return true
}

и настроить

Эдуардо Оливерос Акоста
источник
Откуда этот снимок экрана?
Сэм
6

Использование контроллера навигации для размещения панели для отклонения клавиатуры:

в .h файле:

UIBarButtonItem* dismissKeyboardButton;

в .m файле:

- (void)viewDidLoad {
    dismissKeyboardButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissKeyboard)];
}

-(void)textViewDidBeginEditing:(UITextView *)textView {
    self.navigationItem.rightBarButtonItem = dismissKeyboardButton;
}

-(void)textFieldDidBeginEditing:(UITextField *)textField {
    self.navigationItem.rightBarButtonItem = dismissKeyboardButton;
}

-(void)dismissKeyboard {
    [self.textField resignFirstResponder];
    [self.textView resignFirstResponder];
    //or replace this with your regular right button
    self.navigationItem.rightBarButtonItem = nil;
}
Алекс Стоун
источник
5

Как и матовый комментарий к samvermette, мне также не нравится идея обнаружения "\ n". Клавиша «возврата» существует по причине в UITextView, то есть, конечно, для перехода к следующей строке.

Лучшее решение, на мой взгляд, состоит в том, чтобы имитировать приложение для сообщений iPhone - добавить панель инструментов (и кнопку) на клавиатуре.

Я получил код из следующего сообщения в блоге:

http://www.iosdevnotes.com/2011/02/iphone-keyboard-toolbar/

шаги:

-Добавить панель инструментов в ваш файл XIB - установите высоту 460

-Добавить элемент кнопки панели инструментов (если еще не добавлен). Если вам нужно выровнять его по правому краю, также добавьте элемент кнопки гибкой панели в XIB и переместите элемент кнопки панели инструментов

-Создайте действие, которое связывает ваш элемент кнопки с resignFirstResponder следующим образом:

- (IBAction)hideKeyboard:(id)sender {
    [yourUITextView resignFirstResponder];
}

-Затем:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

- (void)keyboardWillShow:(NSNotification *)notification {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];

    CGRect frame = self.keyboardToolbar.frame;
    frame.origin.y = self.view.frame.size.height - 260.0;
    self.keyboardToolbar.frame = frame;

    [UIView commitAnimations];
}

- (void)keyboardWillHide:(NSNotification *)notification {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];

    CGRect frame = self.keyboardToolbar.frame;
    frame.origin.y = self.view.frame.size.height;
    self.keyboardToolbar.frame = frame;

    [UIView commitAnimations];
}
друг
источник
Не по теме. Хотя ваше решение элегантно, оно не отвечает на оригинальный вопрос: «Как отклонить клавиатуру для UITextView с клавишей возврата?». Существуют ситуации, когда UITextView используется для имитации переноса слов UITextField, а не для ввода нескольких строк.
SwiftArchitect
2
Хотя это не по теме, это очень полезно. Я также хочу, чтобы UITextView вводился с несколькими строками и закрывал клавиатуру, когда захочу.
Yeung
5

Просто решил эту проблему по-другому.

  • Создайте кнопку, которая будет помещена в фоновом режиме
  • Из Инспектора атрибутов измените тип кнопки на пользовательский, и кнопка станет прозрачной.
  • Разверните кнопку, чтобы охватить весь вид, и убедитесь, что кнопка находится позади всех других объектов. Простой способ сделать это - перетащить кнопку в верхнюю часть списка в представлении.
  • Контролем перетащите кнопку в viewController.hфайл и создайте действие (Отправленное событие: Touch Up Inside), например:

    (IBAction)ExitKeyboard:(id)sender;
  • В ViewController.mдолжен выглядеть так:

    (IBAction)ExitKeyboard:(id)sender {
        [self.view endEditing:TRUE];
    }
  • Запустите приложение, и когда вы щелкнете мышью из TextView, клавиатура исчезнет
Uvichy
источник
Вы также должны добавить: - (void) textViewDidEndEditing: (UITextView *) textView {[self.TextView resignFirstResponder]; }
Самурай
5

Добавить наблюдателя в viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(textViewKeyPressed:) name: UITextViewTextDidChangeNotification object: nil];

а затем используйте селектор, чтобы проверить «\ n»

-(void) textViewKeyPressed: (NSNotification*) notification {

  if ([[[notification object] text] hasSuffix:@"\n"])
  {
    [[notification object] resignFirstResponder];
  }
}

Он использует «\ n» и не проверяет ключ возврата, но я думаю, что это нормально.

ОБНОВИТЬ

Смотрите ответ Рибто ниже, который использует [NSCharacterSet newlineCharacterSet]вместо\n

ToddB
источник
Ошибка, которую он использует, \nи ключ возврата обнаруживается на основе, \nпоэтому он проверяет наличие ключа возврата. Разница лишь в том, что вы используете уведомления, а не textViewDelegates.
GoodSp33d
Теперь я думаю, что проверка [NSCharacterSet newlineCharacterSet]вместо \ n может быть лучшим способом.
ToddB
5

Swift Code

Реализуйте UITextViewDelegate в своем классе / Смотрите так:

class MyClass: UITextViewDelegate  { ...

установите делегата textView на себя

myTextView.delegate = self

А затем реализовать следующее:

  func textViewDidChange(_ textView: UITextView) {
    if textView.text.characters.count >= 1 {

        if let lastChar = textView.text.characters.last {

            if(lastChar == "\n"){

              textView.text = textView.text.substring(to: textView.text.index(before: textView.text.endIndex))
              textView.resignFirstResponder()
            }
        }
    }
}

РЕДАКТИРОВАТЬ Я обновил код, потому что это никогда не хорошая идея, чтобы изменить пользовательский ввод в текстовом поле для обходного пути и не сбрасывать состояние после завершения кода взлома.

Фритьоф Шефер
источник
4

Попробуй это :

 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
    if ([text isEqualToString:@"\n"]) {
        [self.view endEditing:YES];
    }

    return YES;

}
Набиль Эль
источник
4

// Вы можете использовать это ...

Шаг 1. Первый шаг - убедиться, что вы заявили о поддержке UITextViewDelegateпротокола. Это делается в вашем заголовочном файле, в качестве примера можно привести заголовок

EditorController.h:

@interface EditorController : UIViewController  {
  UITextView *messageTextView;
}

@property (nonatomic, retain) UITextView *messageTextView;

@end

Шаг 2. Далее вам нужно зарегистрировать контроллер в качестве делегата UITextView. Продолжая из приведенного выше примера, вот как я инициализировал UITextViewс EditorControllerделегатом…

- (id) init {
    if (self = [super init]) {
        // define the area and location for the UITextView
        CGRect tfFrame = CGRectMake(10, 10, 300, 100);
        messageTextView = [[UITextView alloc] initWithFrame:tfFrame];
        // make sure that it is editable
        messageTextView.editable = YES;

        // add the controller as the delegate
        messageTextView.delegate = self;
    }

Шаг 3. И теперь последняя часть головоломки - принять меры в ответ на shouldCahngeTextInRangeсообщение следующим образом:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range 
  replacementText:(NSString *)text
{
    // Any new character added is passed in as the "text" parameter
    if ([text isEqualToString:@"\n"]) {
        // Be sure to test for equality using the "isEqualToString" message
        [textView resignFirstResponder];

        // Return FALSE so that the final '\n' character doesn't get added
        return FALSE;
    }
    // For any other character return TRUE so that the text gets added to the view
    return TRUE;
}
Абхишек Патхак
источник
3

Вы также можете скрыть клавиатуру при касании на экране просмотра:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     UITouch * touch = [touches anyObject];
     if(touch.phase == UITouchPhaseBegan) {
        [txtDetail resignFirstResponder];
      }
 }
Хитеш Вагела
источник
ИМХО, это очень хороший подход, намного лучше, чем с кнопкой, охватывающей весь вид.
WebOrCode
3

Быстрый ответ:

override func viewDidLoad() {
    super.viewDidLoad()
    let tapGestureReconizer = UITapGestureRecognizer(target: self, action: "tap:")
    view.addGestureRecognizer(tapGestureReconizer)
}

func tap(sender: UITapGestureRecognizer) {
    view.endEditing(true)
}
Глауко Невес
источник
3

Я использовал этот код для смены респондента.

 - (BOOL)textView:(UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
    {
        if ([text isEqualToString:@"\n"]) {
            //[textView resignFirstResponder];
            //return YES;
            NSInteger nextTag = textView.tag + 1;
            // Try to find next responder
            UIResponder* nextResponder = [self.view viewWithTag:nextTag];
            if (nextResponder) {
                // Found next responder, so set it.
                [nextResponder becomeFirstResponder];
            } else {
                // Not found, so remove keyboard.
                [textView resignFirstResponder];
            }
            return NO; 


            return NO;
        }
        return YES;

    }
Авижит Нагаре
источник
почему бы не использовать [self.view endEditing: YES]; один раз??
ajay_nasa
3

Вопрос состоит в том, как сделать это с помощью клавиши возврата, но я думаю, что это может помочь кому-то с намерением просто заставить клавиатуру исчезнуть при использовании UITextView:

private func addToolBarForTextView() {
    let textViewToolbar: UIToolbar = UIToolbar()
    textViewToolbar.barStyle = .default
    textViewToolbar.items = [
        UIBarButtonItem(title: "Cancel", style: .done,
                  target: self, action: #selector(cancelInput)),
        UIBarButtonItem(barButtonSystemItem: .flexibleSpace,
                  target: self, action: nil),
        UIBarButtonItem(title: "Post Reply", style: .done,
                  target: self, action: #selector(doneInput))
    ]
    textViewToolbar.sizeToFit()
    yourTextView.inputAccessoryView = textViewToolbar
}

@objc func cancelInput() { print("cancel") }
@objc func doneInput() { print("done") }

override func viewDidLoad() {
    super.viewDidLoad()
    addToolBarForTextView()
}

Вызовите addToolBarForTextView () в viewDidLoad или другом методе жизненного цикла.

Кажется, это было идеальное решение для меня.

Ура,

Мурат

Мурат Ясар
источник
1
Для 2019 года теперь скопируйте и вставьте, без синтаксических ошибок и текущего именования
Fattie
1
безусловно, лучший ответ здесь. Я просто исправил простую синтаксическую ошибку, конечно, отредактируйте, как хотите. Спасибо!
Толстяк
2

Хорошо. Все дали ответы с хитростями, но я думаю, что правильный путь для достижения этой цели -

Подключение следующего действия к событию « Закончено ли при выходе » в Interface Builder. (щелкните правой кнопкой мыши TextFieldи перетащите cntrl из пункта « Закончилось ли при выходе ») следующим способом.

-(IBAction)hideTheKeyboard:(id)sender
{
    [self.view endEditing:TRUE];
}
carbonr
источник
6
-1 Вопрос касается UITextView, а не UITextField, мой друг
Йог
2
большинство из этих ответов здесь с голосами, потому что это подходит для различных сценариев разных разработчиков.
2012 года
Если вы используете UITextField, это способ сделать это. Кстати, вы должны использовать ДА / НЕТ для BOOL Objective C, а не ИСТИНА / ЛОЖЬ.
Джон Шир
1
@jshier: ИСТИНА / ЛОЖЬ тоже в порядке
Йог
2

Подобно другим ответам, использующим, UITextViewDelegateно более новый быстрый интерфейс isNewline:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if let character = text.first, character.isNewline {
        textView.resignFirstResponder()
        return false
    }
    return true
}
BROK3N S0UL
источник
1
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range  replacementText:(NSString *)text
{
    if (range.length==0) {
        if ([text isEqualToString:@"\n"]) {
            [txtView resignFirstResponder];
            if(textView.returnKeyType== UIReturnKeyGo){

                [self PreviewLatter];
                return NO;
            }
            return NO;
        }
    }   return YES;
}
Риндзю Джайн
источник
1
+ (void)addDoneButtonToControl:(id)txtFieldOrTextView
{
    if([txtFieldOrTextView isKindOfClass:[UITextField class]])
    {
        txtFieldOrTextView = (UITextField *)txtFieldOrTextView;
    }
    else if([txtFieldOrTextView isKindOfClass:[UITextView class]])
    {
        txtFieldOrTextView = (UITextView *)txtFieldOrTextView;
    }

    UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0,
                                                                          0,
                                                                          [Global returnDeviceWidth],
                                                                          50)];
    numberToolbar.barStyle = UIBarStyleDefault;


    UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"btn_return"]
                                                                style:UIBarButtonItemStyleBordered
                                                               target:txtFieldOrTextView
                                                               action:@selector(resignFirstResponder)];

    numberToolbar.items = [NSArray arrayWithObjects:btnDone,nil];
    [numberToolbar sizeToFit];

    if([txtFieldOrTextView isKindOfClass:[UITextField class]])
    {
         ((UITextField *)txtFieldOrTextView).inputAccessoryView = numberToolbar;
    }
    else if([txtFieldOrTextView isKindOfClass:[UITextView class]])
    {
         ((UITextView *)txtFieldOrTextView).inputAccessoryView = numberToolbar;
    }
}
Вену Гопал Тевари
источник
0

Я знаю, что это не точный ответ на этот вопрос, но я нашел эту ветку после поиска в интернете ответа. Я предполагаю, что другие разделяют это чувство.

Это моя разница в UITapGestureRecognizer, который я считаю надежным и простым в использовании - просто установите делегат TextView на ViewController.

Вместо ViewDidLoad я добавляю UITapGestureRecognizer, когда TextView становится активным для редактирования:

-(void)textViewDidBeginEditing:(UITextView *)textView{
    _tapRec = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];

    [self.view addGestureRecognizer: _tapRec];
    NSLog(@"TextView Did begin");
}

Когда я нажимаю вне TextView, представление завершает режим редактирования, и UITapGestureRecognizer удаляет себя, чтобы я мог продолжить взаимодействие с другими элементами управления в представлении.

-(void)tap:(UITapGestureRecognizer *)tapRec{
    [[self view] endEditing: YES];
    [self.view removeGestureRecognizer:tapRec];
    NSLog(@"Tap recognized, tapRec getting removed");
}

Надеюсь, это поможет. Это кажется таким очевидным, но я никогда не видел такого решения в Интернете - я что-то не так делаю?

КУП
источник
0

Не забудьте установить делегат для textView - иначе resignfirstresponder не будет работать.

Рон Холмс
источник
0

Попробуй это .

NSInteger lengthOfText = [[textView.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length];
Хирен Панчал
источник
0

Для Xcode 6.4., Swift 1.2. :

   override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)
    {
        super.touchesBegan(touches, withEvent: event)
        if let touch = touches.first as? UITouch
        {
            self.meaningTextview.resignFirstResponder()
        }
    }
MB_iOSDeveloper
источник
0

Вы должны добавить UIToolbarк верху UITextView, чтобы сделать проще, чем использоватьshouldChangeTextIn

В Swift 4

let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
        toolbar.barStyle = .default
        toolbar.items = [
            UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
            UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(doneAction))
        ]
        textView.inputAccessoryView = toolbar
@objc func doneAction(){
 self.textView.resignFirstResponder()
}
Жанг
источник
Безусловно, лучшее решение. Обратите внимание, что вместо установки кадра, просто используйтеtoolbar.sizeToFit()
Fattie