iOS关闭虚拟键盘方法汇总
在iOS应用开发中,有三类视图对象会打开虚拟键盘,进行输入操作,但如何关闭虚拟键盘,却没有提供自动化的方法。这个需要我们自己去实现。这三类视图对象分别是UITextField,UITextView和UISearchBar。这里介绍一下UITextField中关闭虚拟键盘的几种方法。
第一种方法,使用它的委托UITextFieldDelegate中的方法textFieldShouldReturn:来关闭虚拟键盘。
在UITextField视图对象如birdNameInput所在的类中实现这个方法。
(BOOL)textFieldShouldReturn:(UITextField*)textField{ if((textField==self.birdNameInput)||(textField==self.locationInput)){ [textFieldresignFirstResponder]; } returnYES; } -(BOOL)textFieldShouldReturn:(UITextField*)textField{ if((textField==self.birdNameInput)||(textField==self.locationInput)){ [textFieldresignFirstResponder]; } returnYES; }
这样,在输入框birdNameInput中打开虚拟键盘后,轻击键盘的return键就会自动关闭掉虚拟键盘。
第二种方法,将birdNameInput的属性中ReturnKey修改为done,再定义一个方法和Done键的DidEndOnExit连接。
通过轻击done键触发这个事件来关闭虚拟键盘。
定义的方法如下:
(IBAction)textFieldDoneEditing:(id)sender { [senderresignFirstResponder]; } -(IBAction)textFieldDoneEditing:(id)sender { [senderresignFirstResponder]; }
这两个方法都是轻击虚拟键盘上一个键来关闭它。这属于精确操作,而手指不像鼠标,做这种操作不容易。因此就UI层面而言,这两个方法都不是最好的方法。在iphone或ipad屏幕上,虚拟键盘占用的面积大小是有限的。通过轻击虚拟键盘之外的区域而关闭虚拟键盘。
第三种方法,通过轻击键盘之外的空白区域关闭虚拟键盘。
在birdNameInput所属的视图控制器类的viewDidLoad方法中定义一个UITapGestureRecognizer的对象,然后将它赋值为它的视图。
UITapGestureRecognizer*tap=[[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(dismissKeyboard)]; [self.viewaddGestureRecognizer:tap]; [taprelease]; UITapGestureRecognizer*tap=[[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(dismissKeyboard)]; [self.viewaddGestureRecognizer:tap]; [taprelease];
再定义一下选择器调用的方法dismissKeyboard。
(void)dismissKeyboard{ [birdNameInputresignFirstResponder]; } -(void)dismissKeyboard{ [birdNameInputresignFirstResponder]; }
如果屏幕上有多个textField的话,一个一个地列出来就有些麻烦。那么将方法修改一下,如下:
(void)dismissKeyboard{ NSArray*subviews=[self.viewsubviews]; for(idobjInputinsubviews){ if([objInputisKindOfClass:[UITextFieldclass]]){ UITextField*theTextField=objInput; if([objInputisFirstResponder]){ [theTextFieldresignFirstResponder]; } } } } -(void)dismissKeyboard{ NSArray*subviews=[self.viewsubviews]; for(idobjInputinsubviews){ if([objInputisKindOfClass:[UITextFieldclass]]){ UITextField*theTextField=objInput; if([objInputisFirstResponder]){ [theTextFieldresignFirstResponder]; } } } }
如果这个屏幕上的视图对象很复杂的话,另当别论。这个方法是编码新建一个手势对象。也可以直接使用interfacebuilder图形化开发工具,在storyboard中拉入一个手势对象到视图控制器类中,再将此手势对象建立一个IBACTION,名称可以是dismissKeyboard。
第四种方法,通过轻击键盘之外的空白区域关闭虚拟键盘。
将屏幕上的view也就是textField的父视图拖一个touchdown事件出来,和一个能关闭虚拟键盘的方法连接。如果视图没有touchdown事件,可将view的父类从UIView修改为UIButton。首先定义并实现一个方法backgroundTap:。
(IBAction)backgroundTap:(id)sender { NSArray*subviews=[self.viewsubviews]; for(idobjInputinsubviews){ if([objInputisKindOfClass:[UITextFieldclass]]){ UITextField*theTextField=objInput; if([objInputisFirstResponder]){ [theTextFieldresignFirstResponder]; } } } } -(IBAction)backgroundTap:(id)sender { NSArray*subviews=[self.viewsubviews]; for(idobjInputinsubviews){ if([objInputisKindOfClass:[UITextFieldclass]]){ UITextField*theTextField=objInput; if([objInputisFirstResponder]){ [theTextFieldresignFirstResponder]; } } } }
然后选择背景视图的TouchDown事件,连接backgroundTap:即可。这样只要轻击一下虚拟键盘之外的区域,就能关闭虚拟键盘。这些方法都是使用resignFirstResponder方法来关闭虚拟键盘,还有其他的方法。
第五种方法,使用endEditing:方法在所在的视图控制器类中,覆盖这个方法。
(void)touchesBegan:(NSSet*)toucheswithEvent:(UIEvent*)event{ [[selfview]endEditing:YES]; } -(void)touchesBegan:(NSSet*)toucheswithEvent:(UIEvent*)event{ [[selfview]endEditing:YES]; }
Thismethodlooksatthecurrentviewanditssubviewhierarchyforthetextfieldthatiscurrentlythefirstresponder.Ifitfindsone,itasksthattextfieldtoresignasfirstresponder.IftheforceparameterissettoYES,thetextfieldisneverevenasked;itisforcedtoresign.
但是,如果这个屏幕很复杂,虚拟键盘之外的区域中有很多按钮。轻击这些区域时可能会轻击到这些按钮,这样虚拟键盘就不能关闭。
要是找到一个没有按钮的空白区域都不容易且还有隐藏的视图对象时,通过轻击虚拟键盘之外的区域关闭虚拟键盘的方法实现起来就难了。
第六种方法,覆盖hitTest:withEvent:方法关闭虚拟键盘
在stackoverflow.com上,有人这样总结。说使用hitTest:withEvent:方法是最好的,也是最容易的解决方法。
Ithinktheeasiest(andbest)waytodothisistosubclassyourglobalviewandusehitTest:withEventmethodtolistentoanytouch.Touchesonkeyboardaren'tregistered,sohitTest:withEventisonlycalledwhenyoutouch/scroll/swipe/pinch...somewhereelse,thencall[selfendEditing:YES].ThisisbetterthanusingtouchesBeganbecausetouchesBeganarenotcalledifyouclickonabuttonontopoftheview.ItisbetterthanUITapGestureRecognizerwhichcan'trecognizeascrollinggestureforexample.Itisalsobetterthanusingadimscreenbecauseinacomplexeanddynamicuserinterface,youcan'tputdimscreeneverywhere.Moreover,itdoesn'tblockotheractions,youdon'tneedtotaptwicetoselectabuttonoutside(likeinthecaseofaUIPopover).Also,it'sbetterthancalling[textFieldresignFirstResponder],becauseyoumayhavemanytextfieldsonscreen,sothisworksforallofthem.
因此,我再建立一个继承UIView的视图类。在这个视图类中,覆盖hitTest:withEvent:方法,增加[selfendEditing:YES]方法。
(UIView*)hitTest:(CGPoint)pointwithEvent:(UIEvent*)event{ UIView*result=[superhitTest:pointwithEvent:event]; [selfendEditing:YES] returnresult; } -(UIView*)hitTest:(CGPoint)pointwithEvent:(UIEvent*)event{ UIView*result=[superhitTest:pointwithEvent:event]; [selfendEditing:YES] returnresult; }
我将视图控制器的主视图所属类修改为这个新建视图类。这样在屏幕上轻击任何位置都会关闭虚拟键盘。这个方法是最简单,也是最好的关闭虚拟键盘的方法。使用好hitTest:withEvent:这个方法,还可以实现很多很复杂的功能。
TheimplementationofhitTest:withEvent:inUIResponderdoesthefollowing:
•ItcallspointInside:withEvent:ofself
•IfthereturnisNO,hitTest:withEvent:returnsnil.theendofthestory.
•IfthereturnisYES,itsendshitTest:withEvent:messagestoitssubviews.itstartsfromthetop-levelsubview,andcontinuestootherviewsuntilasubviewreturnsanon-nilobject,orallsubviewsreceivethemessage.
•Ifasubviewreturnsanon-nilobjectinthefirsttime,thefirsthitTest:withEvent:returnsthatobject.theendofthestory.
•Ifnosubviewreturnsanon-nilobject,thefirsthitTest:withEvent:returnsself
Thisprocessrepeatsrecursively,sonormallytheleafviewoftheviewhierarchyisreturnedeventually.However,youmightoverridehitTest:withEventtodosomethingdifferently.Inmanycases,overridingpointInside:withEvent:issimplerandstillprovidesenoughoptionstotweakeventhandlinginyourapplication.
以上给大家介绍了六种iOS关闭虚拟键盘的方法,大家可以根据个人需要选择一种适合自己比较好的方法。同时也非常感谢大家对毛票票网站的支持!