如何用退货键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