Як відхилити клавіатуру для UITextView за допомогою клавіші повернення?


381

У бібліотеці ІБ вступ повідомляє нам, що при returnнатисканні клавіші клавіатура для UITextViewзникне. Але насправді returnключ може діяти лише як \ \ n '.

Я можу додати кнопку і використовувати, [txtView resignFirstResponder]щоб приховати клавіатуру.

Але чи є спосіб додати дії для returnклавіші на клавіатурі, щоб мені не потрібно було додавати UIButton?


Дотримуйтесь інструкцій у цьому дописі в блозі: iphonedevelopertips.com/cocoa/…
ManojN

Відповіді:


354

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

Навіть тоді, якщо ви хочете це зробити, застосуйте textView:shouldChangeTextInRange:replacementText:метод UITextViewDelegateі перевірте, чи є текст заміни \n, прихойте клавіатуру.

Можуть бути й інші способи, але я не знаю жодного.


1
Дякуємо, і метод працює добре. Причина використання UITextView полягає в тому, що він може містити текст у декількох рядках. І зараз я використовую це як вікно для повідомлень.
Чілі Чжун

28
Досить просто змінити ключ повернення на "зроблено", використовуючи [textField setReturnKeyType: UIReturnKeyDone];або за допомогою
конструктора

9
Гаразд, тепер я розумію, що Apple, закінчуючи багаторядковим текстовим полем, - це зробити
готовим

7
Це не дуже вдалий спосіб вирішити цю проблему, оскільки ви обмежуєте використання користувачем enter для виходу з клавіатури. Мабуть, найкращим способом є додавання кнопки, яка виконує метод resignFirstResponder.
Еле

5
@Casebash. Здається, що встановлення ключа повернення на "виконано" не вирішує проблему в Xcode 6.4, Swift 2.0. Я встановлюю ключ за допомогою ІБ.
MB_iOSDeveloper

504

Зрозуміло, що я опублікую фрагмент прямо тут:

Переконайтеся, що ви оголосили підтримку 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
}

75
Біда в тому , що це на самому ділі не спосіб виявлення того, що користувач натиснув на зворотний ключ . Користувач може вставити символ повернення в текстове поле, і ви отримаєте те саме повідомлення делегата. В основному ви неправильно використовуєте подання тексту. Спосіб відхилення клавіатури - це (1) взагалі цього не робити (як при складанні повідомлення в додатку Mail) або (2) мати кнопку Готово в іншому місці інтерфейсу (як у додатку Notes). Наприклад, ви можете прикріпити таку кнопку як перегляд аксесуарів до клавіатури.
мат

@ Сем V цей фрагмент був класною людиною. це працює для мене. спасибі тонна людина. Чи є якийсь фрагмент для відхилення цифрової клавіатури. з повагою shishir
Shishir.bobby

Чудовий. Просто нагадування про те, що в деяких ситуаціях, щоб позбутися клавіатури, спробуйте по черзі ... [self.view endEditing: ТАК];
Fattie

@Vojto, відмінно працює на iPad. Ви, ймовірно, не встановили делегата.
Вінсент

4
Проблема полягає в тому, що клавіатура може приховувати частину інтерфейсу, який використовується для відхилення. Це дійсно абсурдно, що в IOS немає кнопки на кожній клавіатурі, призначеної для відхилення клавіатури, щоб користувач міг це зробити, якщо захоче.
Sani 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
}

6
Я можу змінити його так: NSRange resultRange = [текстовий діапазонOfCharacterFromSet: [NSCharacterSet newlineCharacterSet] параметри: NSBackwardsSearch]; Оскільки це все-таки хакер, здається, перевірка кінця рядка на повернення може бути більш безпечним маршрутом.
maxpower

@maxpower Дуже хороший коментар. Також краще перевірити замінений текст, наприклад NSString *replacedText = [textView.text stringByReplacingCharactersInRange:range withString:text].
Рудольф Адамкович

Уявіть, що користувач вставляє текст, скопійований з інших місць, який містить новий рядок. Вони, ймовірно, будуть заплутані, коли замість додавання тексту програма просто відхиляє клавіатуру.
Микола Рухе

44

Я знаю, що на це відповіли багато разів, але ось два мої центи на питання.

Я вважав, що відповіді samvermette та ribeto дуже корисні, а також коментар maxpower у відповіді рібето . Але з тими підходами є проблема. Проблема, яку мат згадує у відповіді самвермета, полягає в тому, що якщо користувач хоче вставити щось із розривом рядка всередині нього, клавіатура ховається, нічого не вставляючи.

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

Це найкраще рішення цієї проблеми. відповідь samvermette не враховує ситуацію, коли користувач хоче вставити текст.
marcopaivaf

36

Більш елегантний спосіб - відхилити клавіатуру, коли користувач натискає десь поза рамкою клавіатури.

Спочатку встановіть подання ViewController на клас "UIControl" у інспектора ідентичності UIBuilder. Контрольно перетягніть подання у файл заголовка 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.

Джерело: Ranch Big Nerd

EDIT: Я також хотів би додати, що якщо ви використовуєте UIScrollView, вищезазначена методика може не працювати так легко через 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];
}

Якщо користувач натисне за межі клавіатури і не натисне простір для введення, клавіатура буде відхилена.


1
Мені подобається ідея, GestureRecognizerале величезна проблема полягає в тому, що всі кнопки або елементи керування на зображенні більше не можна натискати.
експерт

34

Додайте цей метод у свій контролер перегляду.

Швидкий :

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

Я не думаю, що це гарна ідея перекривати дотики Біга і не телефонувати super.touchesBegan(touches:withEvent:).
ТГО

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

У переглядіDidLoad

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

17

Я знайшов відповідь josebama найбільш повною та чистою відповіддю, доступною у цій темі.

Нижче представлений синтаксис 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

Використання навігаційного контролера для розміщення панелі для відхилення клавіатури:

у файлі .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". Ключ "return" є з причини чому в UITextView, тобто для переходу до наступного рядка курсу.

Найкраще рішення, на мою думку, - імітувати додаток для повідомлень iPhone - це додати панель інструментів (і кнопку) на клавіатурі.

Я отримав код із наступного повідомлення в блозі:

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

Кроки:

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

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

-Створіть дію, яка пов'язує елемент кнопки з відставкоюFirstResponder таким чином:

- (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файлу та створіть дію (Надіслана подія: Торкніться всередині), наприклад:

    (IBAction)ExitKeyboard:(id)sender;
  • У ViewController.mповинен виглядати так:

    (IBAction)ExitKeyboard:(id)sender {
        [self.view endEditing:TRUE];
    }
  • Запустіть додаток, і коли ви клацнете від TextView, клавіатура зникає

Ви також повинні додати: - (недійсний) 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


Помилка, яку він використовує, \nі ключ повернення виявляється на основі, \nтому він перевіряє ключ повернення. Єдина відмінність полягає в тому, що ви використовуєте сповіщення, а не використовуєте textViewDelegates.
GoodSp33d

Тепер я думаю, що перевірка на [NSCharacterSet newlineCharacterSet]замість \ n може бути кращим способом.
ToddB

5

Швидкий код

Реалізуйте 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()
            }
        }
    }
}

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


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: ТАК]; раз ??
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
на сьогодні найкраща відповідь. Я просто виправив просту синтаксичну помилку, звичайно редагую її за бажанням. Дякую!
Fattie

2

Добре. Кожен дав відповіді хитрощами, але я думаю, що правильний спосіб досягти цього - шляхом

Підключення наступної дії до події " Здійснилося завершення при виході " в Interface Builder. (клацніть правою кнопкою миші TextFieldта перетягніть cntrl з пункту "Здійснився вихід при виході " на наступний метод.

-(IBAction)hideTheKeyboard:(id)sender
{
    [self.view endEditing:TRUE];
}

6
-1 Питання стосується UITextView, а не UITextField мого друга
Yogi

2
більшість із цих відповідей є голосами, оскільки вони відповідають різним сценаріям різних розробників.
карбон

Якщо ви використовуєте UITextField, це так зробити. До речі, ви повинні використовувати ТАК / НІ для БУЛЬТІВ об'єктивних С, а не ПРАВИЛЬНИХ / ЛІЖНИХ.
Джон Шиер

1
@jshier: ІСТИНА / ФАЛЬС також добре
Yogi

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
}

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

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