在IB的库中,介绍告诉我们当按下 return 键时,UITextView
的键盘将消失。但实际上 return 键只能作为'\ n'。
我可以添加一个按钮并使用[txtView resignFirstResponder]
来隐藏键盘。
但是有没有办法在键盘中添加 return 键的操作,这样我就不需要添加UIButton
了?
答案 0 :(得分:479)
想想我会在这里发布片段代码:
确保声明支持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 :(得分:340)
UITextView
没有任何在用户点击返回键时将被调用的方法。如果您希望用户只能添加一行文本,请使用UITextField
。点击返回并隐藏键盘UITextView
不符合界面指南。
即便如此,如果您想这样做,请实施textView:shouldChangeTextInRange:replacementText:
UITextViewDelegate
方法,并检查替换文字是否为\n
,隐藏键盘。
可能还有其他方法,但我不知道。
答案 2 :(得分:72)
我知道已经回答了这个问题,但我真的不喜欢使用新行的字符串文字,所以这就是我所做的。
- (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
}
答案 3 :(得分:41)
我知道这已经被回答了很多次,但这是我的两分钱。
我发现samvermette和ribeto的答案非常有用,maxpower在ribeto答案中的评论也是如此。但这些方法存在问题。 matt在samvermette的答案中提到的问题是,如果用户想要在其中粘贴换行符,键盘会隐藏而不会粘贴任何内容。
所以我的方法是上面提到的三个解决方案的混合,只检查当字符串的长度为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;
}
答案 4 :(得分:35)
更优雅的方法是在用户点击键盘框架外的某个位置时关闭键盘。
首先,将ViewController的视图设置为UIBuilder中的标识检查器中的“UIControl”类。按住Ctrl键将视图拖动到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。
来源:Big Nerd Ranch
编辑:我还想补充一点,如果您使用的是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];
}
当用户点击键盘外部并且没有点击输入空格时,键盘将会解除。
答案 5 :(得分:31)
在视图控制器中添加此方法。
<强>夫特强>:
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()
}
}
}
答案 6 :(得分: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"])
,则无法修改
答案 7 :(得分:14)
使用uitextview时还有另一种解决方案, 您可以在&#34; textViewShouldBeginEditing&#34;中添加工具栏作为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];
}
答案 8 :(得分:11)
我发现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
}
答案 9 :(得分:6)
使用导航控制器托管一个栏以关闭键盘:
<。>文件中的:
UIBarButtonItem* dismissKeyboardButton;
<。>文件中的:
- (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;
}
答案 10 :(得分:6)
迅速
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
textView.resignFirstResponder()
}
return true
}
答案 11 :(得分:5)
类似于使用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
}
答案 12 :(得分:5)
以不同的方式解决了这个问题。
控制将按钮拖到viewController.h
文件并创建一个操作(已发送事件:内部触摸),如:
(IBAction)ExitKeyboard:(id)sender;
在ViewController.m
中应如下所示:
(IBAction)ExitKeyboard:(id)sender {
[self.view endEditing:TRUE];
}
答案 13 :(得分:5)
就像对samvermette的暗淡评论一样,我不喜欢检测“\ n”的想法。在UITextView中出现“return”键是有原因的,那就是当然要转到下一行。
我认为最好的解决方案是模仿iPhone消息应用程序 - 即在键盘上添加工具栏(和按钮)。
我从以下博客文章中获得了代码:
http://www.iosdevnotes.com/2011/02/iphone-keyboard-toolbar/
步骤:
- 将工具栏添加到XIB文件 - 将高度设置为460
- 添加工具栏按钮项(如果尚未添加)。如果需要右对齐,还可以向XIB添加灵活的条形按钮项,并移动工具栏按钮项
- 创建将按钮项链接到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];
}
答案 14 :(得分: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”并没有专门检查返回键,但我认为这没关系。
<强>更新强>
请参阅下面的ribto答案,该答案使用[NSCharacterSet newlineCharacterSet]
代替\n
答案 15 :(得分:4)
试试这个:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
if ([text isEqualToString:@"\n"]) {
[self.view endEditing:YES];
}
return YES;
}
答案 16 :(得分:4)
Swift Code
在您的类/ View中实现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()
}
}
}
}
修改强> 我更新了代码,因为将文本字段中的用户输入更改为workarround并且在黑客代码完成后不重置状态永远不是一个好主意。
答案 17 :(得分: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;
}
答案 18 :(得分:3)
确定。每个人都用技巧给出了答案,但我认为实现这一目标的正确方法是
将以下操作连接到Interface Builder
中的“退出时退出”事件。
(右键单击TextField
并从“退出时结束”按住cntrl拖动到以下方法。
-(IBAction)hideTheKeyboard:(id)sender
{
[self.view endEditing:TRUE];
}
答案 19 :(得分: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;
}
答案 20 :(得分:3)
快速回答:
override func viewDidLoad() {
super.viewDidLoad()
let tapGestureReconizer = UITapGestureRecognizer(target: self, action: "tap:")
view.addGestureRecognizer(tapGestureReconizer)
}
func tap(sender: UITapGestureRecognizer) {
view.endEditing(true)
}
答案 21 :(得分:3)
您还可以在视图屏幕中触摸时隐藏键盘:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch * touch = [touches anyObject];
if(touch.phase == UITouchPhaseBegan) {
[txtDetail resignFirstResponder];
}
}
答案 22 :(得分: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;
}
}
答案 23 :(得分:1)
该问题询问如何使用返回键执行此操作,但我认为这可以帮助那些在使用UITextView时意图使键盘消失的人:
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl',
controllerAs: 'main'
})
.when('/characters', {
templateUrl: 'views/characters.html',
controller: 'AboutCtrl',
controllerAs: 'characters'
})
.when('/framedata', {
templateUrl: 'views/framedata.html',
controller: 'FrameDataCtrl',
controllerAs: 'frame'
})
.otherwise({
redirectTo: '/'
});
});
在 viewDidLoad 或其他一些生命周期方法中调用 addToolBarForTextView()。
对我来说,这似乎是完美的解决方案。
干杯,
穆拉特
答案 24 :(得分: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;
}
答案 25 :(得分:0)
试试这个。
NSInteger lengthOfText = [[textView.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length];
答案 26 :(得分: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()
}
}
答案 27 :(得分:0)
我知道这不是这个问题的确切答案,但我在寻找答案之后找到了这个帖子。我认为其他人也有这种感觉。
这是我发现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");
}
我希望这会有所帮助。它看起来很明显,但我从来没有在网络上的任何地方看到过这种解决方案 - 我做错了吗?
答案 28 :(得分:0)
不要忘记为textView设置委托 - 否则resignfirstresponder将无效。
答案 29 :(得分: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()
}
答案 30 :(得分:-1)
隐藏棋盘的功能。
- (void)HideQueyboard
{
[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
}
答案 31 :(得分:-1)
我的黑客:
1-创建一个覆盖整个视图的按钮; 2-将其发送到您的视图背景, 3-更改它在属性检查器中从“Round Rect”键入“Custom”, 4-创建一个动作 5-实现动作方法:
- (IBAction)bgTouched:(id)sender
{
//to dismiss keyboard on bg btn pressed
[_userInput resignFirstResponder];
}
其中_userInput是您的TextField出口
答案 32 :(得分:-1)
对于Swift 3,此代码允许我在UITextView外部按下以关闭键盘。
@IBOutlet weak var comment: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
comment.delegate = self
let tapGestureRecogniser = UITapGestureRecognizer(target: self, action: #selector(tap))
view.addGestureRecognizer(tapGestureRecogniser)
}
func tap(sender: UITapGestureRecognizer) {
if comment.isFirstResponder {
comment.resignFirstResponder()
}
}
答案 33 :(得分:-1)
-(BOOL)textFieldShouldReturn:(UITextField *)textField; // called from textfield (keyboard)
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text; // good tester function - thanks