如何用退货键closuresUITextView的键盘?

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

我可以添加一个button,并使用[txtView resignFirstResponder]来隐藏键盘。

但有没有办法添加键盘上的返回键的操作,以便我不需要添加UIButton

当用户点击返回键时, UITextView没有任何方法。 如果您希望用户只能添加一行文本,请使用UITextField 。 触摸返回和隐藏键盘的UITextView不遵循接口指南。

即使如此,如果你想这样做,实现UITextViewDelegate textView:shouldChangeTextInRange:replacementText:方法,并检查replace文本是否\n ,隐藏键盘。

可能还有其他的方法,但我没有意识到。

想想我会在这里发布代码片段:

确保你声明了对UITextViewDelegate协议的支持。

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

我知道这已经被回答了,但我真的不喜欢使用string的新行,所以这就是我所做的。

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

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

我发现samvermette和ribeto的答案真的很有用,还有ribeto答案中的maxpower的评论。 但是这些方法存在问题。 在samvermette的回答中提到的问题是,如果用户想要在内部粘贴一个断行的东西,键盘会隐藏而不粘贴任何东西。

所以我的方法是上面提到的三个解决scheme的混合,并且只检查input的string是否是一个新行,当string的长度是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; } 

更优雅的方式是当用户在键盘框架外部的某个地方点击时closures键盘。

首先,将你的ViewController的视图设置为UIBuilder身份检查器中的“UIControl”类。 控制 – 将视图拖动到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,上面的技术可能无法通过界面生成器轻松工作。 在这种情况下,您可以使用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]; } 

当用户轻敲键盘外部并且不敲击input空间时,键盘将被解除。

在你的视图控制器中添加这个方法。

Swift

 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() } } } 
 -(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"])你不能编辑

在使用uitextview的时候还有另外一个解决scheme,你可以在“textViewShouldBeginEditing”中添加工具栏作为InputAccessoryView,从这个工具栏的完成button你可以closures键盘,代码如下:

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

在工具栏中button完成的操作如下:

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

使用导航控制器托pipe一个栏来closures键盘:

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

就像samvermette的暗淡评论,我也不喜欢检测“\ n”的想法。 UITextView中的“返回”键是有原因的,也就是下一行。

我认为最好的解决scheme是模仿iPhone的消息应用程序 – 这是在键盘上添加工具栏(和button)。

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

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

脚步:

– 将工具栏添加到XIB文件 – 将高度设置为460

– 添加工具栏button项目(如果尚未添加)。 如果您需要将它右alignment,也可以将灵活的条形button项目添加到XIB,并移动工具栏button项目

创build行动,链接您的button项目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]; } 

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

  • 创build一个将放置在后台的button
  • 从属性检查器,将buttontypes更改为自定义,并使button透明。
  • 展开button以覆盖整个视图,并确保button位于所有其他对象之后。 简单的方法是将button拖到视图中列表视图的顶部
  • 控制拖动button到viewController.h文件,并创build一个动作(发送事件:触摸里面),如:

     (IBAction)ExitKeyboard:(id)sender; 
  • ViewController.m应该看起来像:

     (IBAction)ExitKeyboard:(id)sender { [self.view endEditing:TRUE]; } 
  • 运行应用程序,当您从TextView中单击时,键盘消失

在viewDidLoad中添加一个观察者

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

然后使用select器检查“\ n”

 -(void) textViewKeyPressed: (NSNotification*) notification { if ([[[notification object] text] hasSuffix:@"\n"]) { [[notification object] resignFirstResponder]; } } 

它确实使用“\ n”而不是专门检查返回键,但我认为这是可以的。

UPDATE

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

尝试这个 :

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

//你可以使用这个…

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

EditorController.h:

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

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

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

迅速

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

并配置

SWIFT代码

在你的类/视图中实现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() } } } } 

编辑我更新了代码,因为它不是一个好主意,将文本字段中的用户input更改为workarround,而不是在完成hack代码后重置状态。

我发现约塞巴马的答案是在这个线程中最完整和干净的答案。

下面是它的Swift 3语法:

 func textView(_ textView: UITextView, shouldChangeTextIn _: NSRange, replacementText text: String) -> Bool { let resultRange = text.rangeOfCharacter(from: CharacterSet.newlines, options: .backwards) if text.characters.count == 1 && resultRange != nil { textView.resignFirstResponder() // Do any additional stuff here return false } return true } 

触摸视图屏幕时也可以隐藏键盘:

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

迅速回答:

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

我用这个代码来改变响应者。

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

好。 每个人都用诡计给出答案,但我认为正确的做法是通过

将以下操作连接到Interface Builder的“ 退出时结束 ”事件。 (右键单击TextField并按住Ctrl键并从“ 退出时结束 ”拖动到以下方法。

 -(IBAction)hideTheKeyboard:(id)sender { [self.view endEditing:TRUE]; } 
 -(BOOL)textFieldShouldReturn:(UITextField *)textField; // called from textfield (keyboard) -(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text; // good tester function - thanks 
 - (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; } 
 + (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; } } 

问题是如何使用返回键来实现,但是我认为这可以帮助有意使用UITextView的键盘消失的人:

 @IBOutlet weak var textView: UITextView! private func addToolBarForTextView() { let textViewToolbar: UIToolbar = UIToolbar() textViewToolbar = UIBarStyle.Default textViewToolbar = [ UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Done, target: self, action: #selector(self.cancelInput)), UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil), UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: #selector(self.doneInput)) ] textViewToolbar() self.textView.inputAccessoryView = textViewToolbar //do it for every relevant textView if there are more than one } func doneInput() { self.textView.resignFirstResponder() } func cancelInput() { self.textView.text = "" self.textView.resignFirstResponder() } 

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

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

干杯,

穆拉特

我知道这不是这个问题的确切答案,但是我find了这个线程后,find了一个答案。 我假设其他人分享这种感觉。

这是我发现可靠和易于使用的UITapGestureRecognizer的差异 – 只需将TextView的代理设置为ViewController即可。

而不是ViewDidLoad我TextView成为活动编辑时添加UITapGestureRecognizer:

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

我希望这有帮助。 这似乎很明显,但我从来没有在networking上的任何地方看到这个解决scheme – 我做错了什么?

不要忘记为textView设置委托 – 否则resignfirstresponder将无法正常工作。

尝试这个 。

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

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

我为此破解:

1-创build一个覆盖整个视图的button; 2-将它发送到您的视图的背景,3-在Attribute Inspector中将其从“Round Rect”types更改为“Custom”4-创build一个动作5-实施动作方法:

 - (IBAction)bgTouched:(id)sender { //to dismiss keyboard on bg btn pressed [_userInput resignFirstResponder]; } 

其中_userInput是您的TextFieldsockets