【问题标题】:How to dismiss keyboard for UITextView with return key?如何使用返回键关闭 UITextView 的键盘?
【发布时间】:2010-10-16 18:25:53
【问题描述】:

在IB的库中,介绍告诉我们当按下return键时,UITextView的键盘会消失。但实际上 return 键只能充当'\n'。

我可以添加一个按钮并使用[txtView resignFirstResponder] 隐藏键盘。

但是有没有办法为键盘中的 return 键添加操作,这样我就不需要添加UIButton

【问题讨论】:

标签: iphone objective-c keyboard uitextview iphone-softkeyboard


【解决方案1】:

我想我会在这里发布 sn-p:

确保声明支持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
}

【讨论】:

  • 问题在于,这并不是检测用户是否点击了返回的方法。用户可能会将返回字符粘贴到文本字段中,您会得到相同的委托消息。基本上你在滥用文本视图。关闭键盘的方法是 (1) 根本不这样做(如在邮件应用程序中撰写消息时)或 (2) 在界面的其他地方有一个完成按钮(如在 Notes 应用程序中)。例如,您可以将这样的按钮作为附件视图附加到键盘。
  • @Sam V 说 sn-p 很酷。这个对我有用。非常感谢。是否有任何用于解除数字键盘的 sn-p。关于shishir
  • 壮丽的。只是提醒一下,在某些情况下,要摆脱键盘,请尝试沿线... [self.view endEditing:YES];
  • @Vojto,在 iPad 上运行良好。您可能还没有设置委托。
  • 问题是键盘可能隐藏了用于关闭的界面的一部分。 IOS 没有在每个键盘上都有一个专门用于关闭键盘的按钮,因此用户可以根据需要这样做,这真的很荒谬。
【解决方案2】:

UITextView 没有任何方法可以在用户点击返回键时调用。如果您希望用户只能添加一行文本,请使用UITextField。按回车键并隐藏UITextView 的键盘不符合界面指南。

即便如此,如果您想这样做,请实现 UITextViewDelegatetextView:shouldChangeTextInRange:replacementText: 方法,并检查替换文本是否为 \n,隐藏键盘。

可能还有其他方法,但我不知道。

【讨论】:

  • 谢谢,这个方法效果很好。使用 UITextView 的原因是它可以容纳多行文本。现在我将它用作消息框。
  • 使用[textField setReturnKeyType: UIReturnKeyDone]; 或使用界面生成器将返回键更改为“完成”很容易
  • 好的,我现在明白 Apple 完成多行文本字段的方式是在菜单栏添加完成
  • 这不是解决此问题的好方法,因为您限制用户使用 enter 从键盘退出。可能最好的方法是添加一个执行 resignFirstResponder 方法的按钮。
  • @Casebash。似乎将返回键设置为“完成”并不能解决 Xcode 6.4 和 Swift 2.0 中的问题。我使用 IB 设置密钥。
【解决方案3】:

我知道这已经得到解答,但我不太喜欢使用字符串文字作为换行符,所以这就是我所做的。

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

【讨论】:

  • 我可能会这样修改它: NSRange resultRange = [text rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:NSBackwardsSearch];因为无论如何这都是一种 hack,所以似乎检查字符串的结尾是否有返回可能是更安全的路线。
  • @maxpower 非常好的评论。此外,最好检查替换文本,例如NSString *replacedText = [textView.text stringByReplacingCharactersInRange:range withString:text].
  • 想象一个用户粘贴一些从其他地方复制的文本,其中包含一个换行符。当应用程序只是关闭键盘而不是附加文本时,他们可能会感到困惑。
【解决方案4】:

我知道这个问题已经回答了很多次了,但这里是我对这个问题的两分钱。

我发现samvermetteribeto 的答案非常有用,maxpowerribeto 的答案中的评论也是如此。但是这些方法存在问题。 mattsamvermette 的回答中提到的问题是,如果用户想要粘贴带有换行符的内容,则键盘会隐藏而不粘贴任何内容。

所以我的方法是上述三种解决方案的混合,仅在字符串长度为 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 answer 没有考虑用户想要粘贴文本的情况。
【解决方案5】:

一种更优雅的方式是当用户点击键盘框架之外的某个位置时关闭键盘。

首先,在 UIBuilder 的身份检查器中将 ViewController 的视图设置为“UIControl”类。按住 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];
}

当用户在键盘外点击而不点击输入空间时,键盘将关闭。

【讨论】:

  • 我喜欢 GestureRecognizer 的想法,但最大的问题是视图上的所有按钮或控件都不再可点击。
【解决方案6】:

在您的视图控制器中添加此方法。

斯威夫特

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

【讨论】:

  • 别忘了确认协议UITextViewDelegate :)
  • 我认为重写 touchesBegan 而不调用 super.touchesBegan(touches:withEvent:) 不是一个好主意。
  • 为了表达这段代码的对称性,你应该写else { return true }
  • @meaning-matters 一点也不
  • @AlexanderVolkov 你不同意这是一个对称的情况,你不明白我的意思,你不相信语义正确代码的价值,或者......?跨度>
【解决方案7】:
-(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"]),则无法编辑

【讨论】:

  • -1 这只是 samvermette 答案的较差版本。如果文本等于 @"\n",则您错过了返回 NO
【解决方案8】:

与 uitextview 一起使用时还有另一种解决方案, 您可以在“textViewShouldBeginEditing”中将工具栏添加为 InputAccessoryView,并通过此工具栏的完成按钮关闭键盘,代码如下:

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

【讨论】:

    【解决方案9】:

    我发现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”的换行符。
    【解决方案10】:

    与使用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
    }
    

    【讨论】:

      【解决方案11】:

      迅速

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

      【讨论】:

      • 屏幕截图来自哪里?
      【解决方案12】:

      使用导航控制器托管一个栏来关闭键盘:

      在 .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;
      }
      

      【讨论】:

        【解决方案13】:

        就像对 samvermette 的 matt 评论一样,我也不喜欢检测“\n”的想法。 UITextView 中有“return”键是有原因的,当然是转到下一行。

        我认为最好的解决方案是模仿 iPhone 消息应用程序 - 在键盘上添加工具栏(和按钮)。

        我从以下博客文章中获得了代码:

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

        步骤:

        -将工具栏添加到您的 XIB 文件中 - 将高度设置为 460

        -添加工具栏按钮项(如果尚未添加)。如果需要右对齐,还要在XIB中添加灵活的bar button item,并移动toolbar button item

        -创建将按钮项链接到 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而不是输入多行的情况。
        • 虽然跑题了,但还是很有用的。我还希望使用多行输入 UITextView 并在需要时关闭键盘。
        【解决方案14】:

        刚刚用不同的方式解决了这个问题。

        • 创建一个将放置在背景中的按钮
        • 在属性检查器中,将按钮类型更改为自定义,并使按钮透明。
        • 展开按钮以覆盖整个视图,并确保按钮位于所有其他对象的后面。简单的方法是将按钮拖到视图中的列表视图的顶部
        • 控制拖动按钮到viewController.h文件并创建一个动作(Sent Event: Touch Up Inside),比如:

          (IBAction)ExitKeyboard:(id)sender;
          
        • ViewController.m 中应该是这样的:

          (IBAction)ExitKeyboard:(id)sender {
              [self.view endEditing:TRUE];
          }
          
        • 运行应用,当你点击离开TextView时,键盘消失

        【讨论】:

        • 您还必须添加:-(void)textViewDidEndEditing:(UITextView *)textView { [self.TextView resignFirstResponder]; }
        【解决方案15】:

        在 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”并且没有专门检查返回键,但我认为这没问题。

        更新

        请参阅下面 ribto 的答案,它使用 [NSCharacterSet newlineCharacterSet] 代替 \n

        【讨论】:

        • 错误它确实使用了\n,并且基于\n 检测到返回键,因此它确实检查了返回键。唯一的区别是您使用的是通知而不是 textViewDelegates。
        • 现在我认为检查 [NSCharacterSet newlineCharacterSet] 而不是 \n 可能是更好的选择。
        【解决方案16】:

        Swift 代码

        在您的类/视图中实现 UITextViewDelegate,如下所示:

        class MyClass: UITextViewDelegate  { ...
        

        将 textView 委托设置为 self

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

        编辑 我更新了代码,因为将文本字段中的用户输入更改为解决方法而不是在 hack 代码完成后重置状态绝不是一个好主意。

        【讨论】:

          【解决方案17】:

          试试这个:

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

          【讨论】:

            【解决方案18】:

            //你可以用这个...

            第 1 步。第一步是确保您声明支持UITextViewDelegate 协议。这是在您的头文件中完成的,例如这里的头文件名为

            EditorController.h:

            @interface EditorController : UIViewController  {
              UITextView *messageTextView;
            }
            
            @property (nonatomic, retain) UITextView *messageTextView;
            
            @end
            

            第 2 步。接下来,您需要将控制器注册为 UITextView 的委托。继续上面的例子,这里是我如何初始化 UITextViewEditorController 作为委托......

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

            【讨论】:

              【解决方案19】:

              您还可以在视图屏幕中触摸时隐藏键盘:

              - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
                   UITouch * touch = [touches anyObject];
                   if(touch.phase == UITouchPhaseBegan) {
                      [txtDetail resignFirstResponder];
                    }
               }
              

              【讨论】:

              • 恕我直言,这是非常好的方法,比使用覆盖整个视图的按钮要好得多。
              【解决方案20】:

              快速回答:

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

              【讨论】:

                【解决方案21】:

                我使用此代码更改响应者。

                 - (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];一次??
                【解决方案22】:

                问题询问如何使用返回键,但我认为这可以帮助那些打算在使用 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()
                }
                

                viewDidLoad 中调用 addToolBarForTextView() 或其他一些生命周期方法。

                这对我来说似乎是完美的解决方案。

                干杯,

                穆拉特

                【讨论】:

                • 对于 2019 现在复制和粘贴,没有语法错误和当前命名
                • 这里是迄今为止最好的答案。我刚刚修复了简单的语法错误,当然可以根据需要进行编辑。谢谢!
                【解决方案23】:

                好的。每个人都给出了技巧的答案,但我认为实现这一目标的正确方法是通过

                将以下操作连接到Interface Builder 中的“Did End On Exit”事件。 (右键单击TextField 并从 'Did end on exit' 按住 cntrl 并拖动到以下方法。

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

                【讨论】:

                • -1 问题是关于 UITextView 而不是 UITextField 我的朋友
                • 这些答案大部分都在这里投票,因为它适合不同开发人员的各种场景。
                • 如果您使用的是 UITextField,这就是这样做的方法。顺便说一句,您应该对 Objective-C BOOL 使用 YES/NO,而不是 TRUE/FALSE。
                • @jshier: TRUE/FALSE 也可以
                【解决方案24】:
                - (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;
                }
                

                【讨论】:

                  【解决方案25】:
                  + (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;
                      }
                  }
                  

                  【讨论】:

                    【解决方案26】:

                    您应该在 UITextView 顶部添加 UIToolbar 以简化操作,而不是使用 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()
                    【解决方案27】:

                    我知道这不是这个问题的确切答案,但我在互联网上寻找答案后找到了这个帖子。我想其他人也有这种感觉。

                    这是我发现可靠且易于使用的 UITapGestureRecognizer 的变体 - 只需将 TextView 的委托设置为 ViewController。

                    当 TextView 变为活动以进行编辑时,我添加了 UITapGestureRecognizer 而不是 ViewDidLoad:

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

                    我希望这会有所帮助。看起来很明显,但我从未在网络上的任何地方看到过这个解决方案——我做错了什么吗?

                    【讨论】:

                      【解决方案28】:

                      不要忘记为 textView 设置委托 - 否则 resignfirstresponder 将不起作用。

                      【讨论】:

                        【解决方案29】:

                        试试这个。

                        NSInteger lengthOfText = [[textView.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length];
                        

                        【讨论】:

                          【解决方案30】:

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

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 2014-12-23
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2011-06-07
                            • 2014-11-12
                            • 2010-11-19
                            相关资源
                            最近更新 更多