简体   繁体   English

在关闭UIAlertView后如何防止UIKeyboard动画回退

[英]How to prevent the UIKeyboard from animating away and back after dismissing a UIAlertView

I'm wondering if any iOS devs here have ran into this issue and might be able to propose a solution. 我想知道这里是否有任何iOS开发人员遇到过这个问题,并且可能能够提出解决方案。 It involves the behavior of the UIKeyboard as it relates to a UITextView and UIAlertView. 它涉及UIKeyboard的行为,因为它与UITextView和UIAlertView有关。

In an app, tapping a UITextView invokes the UIKeyboard. 在应用程序中,点击UITextView会调用UIKeyboard。 Tapping a button in the UITextView's accessory view invokes a UIAlertView with the UIAlertViewStyleLoginAndPasswordInput style. 在UITextView的附件视图中点击一个按钮将调用具有UIAlertViewStyleLoginAndPasswordInput样式的UIAlertView。 So far all is good. 到目前为止,一切都很好。

Here's the badness: dismissing the UIAlertView causes the UIKeyboard to animate away, and then back as the UITextView becomes the first responder again. 这是坏处:关闭UIAlertView会使UIKeyboard进行动画处理,然后在UITextView再次成为第一响应者时返回。 The desired behavior is to skip the animation. 所需的行为是跳过动画。 Calling [textView becomeFirstResponder] in the UIAlertViewDelegate methods doesn't seem to do the trick. 在UIAlertViewDelegate方法中调用[textView成为FirstResponder]似乎没有用。

Here is a sample project that illustrates the behavior, and a relevant code snippet and log is posted below. 是一个示例项目 ,说明了这种行为,下面相关的代码段和日志。

Thoughts on this? 有这个想法吗?

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIBarButtonItem *alertButton = [[UIBarButtonItem alloc] initWithTitle:@"Alert" style:UIBarButtonItemStyleBordered target:self action:@selector(handleAlertButtonTapped:)];
    UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleBordered target:self action:@selector(handleDoneButtonTapped:)];
    UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.frame.size.width, 44.0)];
    toolbar.barStyle = UIBarStyleBlack;
    toolbar.items = @[alertButton, spacer, doneButton];

    UIView *accessoryView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.frame.size.width, 44.0)];
    [accessoryView addSubview:toolbar];
    textView.inputAccessoryView = toolbar;

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleKeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleKeyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleKeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleKeyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];

}


- (void)handleAlertButtonTapped:(id)sender {
    NSLog(@"%@", NSStringFromSelector(_cmd));
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Styled AlertView"
                                                        message:nil
                                                       delegate:self
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil, nil];
    [alertView setAlertViewStyle:UIAlertViewStyleLoginAndPasswordInput];
    [alertView show];
}


- (void)handleDoneButtonTapped:(id)sender {
    [textView resignFirstResponder];
}


#pragma mark -
#pragma mark TextView Delegate Methods

- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
    NSLog(@"%@", NSStringFromSelector(_cmd));
    return YES;
}


- (void)textViewDidEndEditing:(UITextView *)textView {
    NSLog(@"%@", NSStringFromSelector(_cmd));
}


#pragma mark -
#pragma mark AlertView Delegate methods

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    NSLog(@"%@", NSStringFromSelector(_cmd));
    [textView becomeFirstResponder]; // Not a solution.
}

- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
    NSLog(@"%@", NSStringFromSelector(_cmd));
    [textView becomeFirstResponder]; // Not a solution.
}

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
    NSLog(@"%@", NSStringFromSelector(_cmd));
    [textView becomeFirstResponder]; // Not a solution.
}


#pragma mark -
#pragma mark Keyboard Notification Methods

- (void)handleKeyboardWillShow:(NSNotification *)notification {
    NSLog(@"%@", NSStringFromSelector(_cmd));
    [textView becomeFirstResponder]; // Not a solution.
}


- (void)handleKeyboardDidShow:(NSNotification *)notification {
    NSLog(@"%@", NSStringFromSelector(_cmd));
    [textView becomeFirstResponder]; // Not a solution.
}


- (void)handleKeyboardWillHide:(NSNotification *)notification {
    NSLog(@"%@", NSStringFromSelector(_cmd));
    [textView becomeFirstResponder]; // Not a solution.
}


- (void)handleKeyboardDidHide:(NSNotification *)notification {
    NSLog(@"%@", NSStringFromSelector(_cmd));
    [textView becomeFirstResponder]; // Not a solution.
}

And the result of the logs is something like this: 日志的结果是这样的:

ResponderTest[1228:11303] handleKeyboardWillShow:
ResponderTest[1228:11303] handleKeyboardDidShow:
ResponderTest[1228:11303] handleAlertButtonTapped:
ResponderTest[1228:11303] handleKeyboardWillShow:
ResponderTest[1228:11303] handleKeyboardDidShow:
ResponderTest[1228:11303] alertView:clickedButtonAtIndex:
ResponderTest[1228:11303] alertView:willDismissWithButtonIndex:
ResponderTest[1228:11303] handleKeyboardWillHide:
ResponderTest[1228:11303] handleKeyboardDidHide:
ResponderTest[1228:11303] handleKeyboardWillShow:
ResponderTest[1228:11303] handleKeyboardDidShow:
ResponderTest[1228:11303] handleKeyboardWillHide:
ResponderTest[1228:11303] handleKeyboardDidHide:
ResponderTest[1228:11303] handleKeyboardWillShow:
ResponderTest[1228:11303] alertView:didDismissWithButtonIndex:
ResponderTest[1228:11303] handleKeyboardDidShow:

Unless I misunderstood your application structure, it seems like you're over complicating things with all those resignFirstResponder and becomeFirstResponder for UIAlertView dismiss. 除非我误解了您的应用程序结构,否则您似乎已经使所有resignFirstResponder变得复杂了,而UIAlertView被关闭成为了FirstResponder。

Essentially you got a UIAlertView with Username and Password fields yeah? 从本质上讲,您有一个带有用户名和密码字段的UIAlertView是吗?

Add a UIToolBar with a "Done" button that has a callback method like so: 添加带有“完成”按钮的UIToolBar,该按钮具有如下回调方法:

// ------------------------------------------
// Setup keyboard done button as input
// accessory view for your two fields
// ------------------------------------------
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[toolBar setBarStyle:UIBarStyleBlackTranslucent];

UIButton *btnDone = [[UIButton alloc] initWithFrame:CGRectMake(230, 4, 66, 35)];
[btnDone setImage:[UIImage imageNamed:@"btnDoneOff.png"] forState:UIControlStateNormal];
[btnDone setImage:[UIImage imageNamed:@"btnDoneOn.png"] forState:UIControlStateHighlighted];

// ------------------------------------------
// Done button calls hideKeyboard method
// when tapped, this is the only place you
// need to call resign first responder
// ------------------------------------------
[btnDone addTarget:self action:@selector(hideKeyboard) forControlEvents:UIControlEventTouchUpInside];

[toolBar addSubview:btnDone];

[btnDone release];

fldUsername.inputAccessoryView = toolBar;
fldPassword.inputAccessoryView = toolBar;


...

// ------------------------------------------
// Resigns first responder for the two fields
// ------------------------------------------
-(void)hideKeyboard
{
    [fldUsername resignFirstResponder];
    [fldPassword resignFirstResponder];
}

Doing it like this, you can tap either the username field or the password field, the keyboard should not dismiss. 这样做,您可以点击用户名字段或密码字段,不要关闭键盘。 When you're done entering username and password, pressing the "Done" button in your keyboard input accessory view will hide the keyboard without causing the keyboard to slide in and out. 输入用户名和密码后,在键盘输入附件视图中按“完成”按钮将隐藏键盘,而不会导致键盘滑入和滑出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM