Adjust View For Keyboard When Switching UITextField?

佐手、 提交于 2020-01-06 08:08:16

问题


I have the ability for my view to slide up when the keyboard appears in my app so the text field can be seen and it worked just fine. However, because its based on keyboard notifications it only works when the keyboard appears.

Meaning, I select a textfield, the keyboard appears and the view slides up accordingly, but if I then tap directly onto another textfield the view doesn't adjust because the keyboard is already present.

Here is the code I am using, any help adapting this to work in a situation like above would be greatly appreciated.

-(void)registerForKeyboardNotifications
{
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
    [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

    // add a tap gesture to drop first responder
    UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapToHideKeyboard:)];
    [self.view addGestureRecognizer:tapGR];
}

-(void)keyboardDidShow:(NSNotification *)notification
{
    CGRect keyboardFrameW = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    UIWindow *window = [[UIApplication sharedApplication] keyWindow];
    CGRect keyboardFrame = [window convertRect:keyboardFrameW toView:self.view];

    //Have a minimum space between the keyboard and textfield
    CGFloat textFieldBuffer = 40;
    CGFloat textFieldKeyboardDifference = 0;

    if (activeTextField.frame.origin.y + activeTextField.frame.size.height > keyboardFrame.origin.y) textFieldKeyboardDifference = (activeTextField.frame.origin.y + activeTextField.frame.size.height + textFieldBuffer) - keyboardFrame.origin.y;
    else if (activeTextField.frame.origin.y + activeTextField.frame.size.height < keyboardFrame.origin.y) textFieldKeyboardDifference = 0;

    [self translateView:self.view toRect:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y - textFieldKeyboardDifference, self.view.frame.size.width, self.view.frame.size.height) withDuration:0.3];
}

-(void)keyboardWillHide:(NSNotification *)notification
{
    //Revert to y origin 0
    [self translateView:self.view toRect:CGRectMake(self.view.frame.origin.x, 0, self.view.frame.size.width, self.view.frame.size.height) withDuration:0.3];
}

EDIT:

I have tried calling the keyboard notification manually when textFieldDidBeginEditing is called like this:

[self keyboardDidShow:[NSNotification notificationWithName:UIKeyboardDidShowNotification object:nil]]; without luck. The method gets called, but no adjustment is made for a reason I can't work out.


回答1:


What you probably want to do here is provide a delegate to all your UITextFields and implement - (void)textFieldDidBeginEditing:(UITextField *)textField on the delegate to trigger your scrolling action. This will be called any time someone starts editing on a text field, and the text field is passed in as a parameter to the method.

EDIT: Using your code as a starting point, this is what I came up with. It gets called on every change of text fields:

@interface SOViewController () <UITextFieldDelegate>
@property (nonatomic, readwrite, assign) UITextField* activeTextField;
@property (nonatomic, readwrite, assign) CGRect keyboardFrame;
@end

@implementation SOViewController

@synthesize activeTextField;
@synthesize keyboardFrame;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self registerForKeyboardNotifications];
    self.keyboardFrame = CGRectNull;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    self.activeTextField = textField;
    [self updatePosition];
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    self.activeTextField = nil;
}

-(void)registerForKeyboardNotifications
{
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
    [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

    //    // add a tap gesture to drop first responder
    //    UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapToHideKeyboard:)];
    //    [self.view addGestureRecognizer:tapGR];
}

- (void)translateView: (UIView*)view toRect: (CGRect)rect withDuration: (NSTimeInterval)duration
{
    NSLog(@"Translating view to rect: %@ overDuration: %g", NSStringFromCGRect(rect), duration);
}

- (void)updatePosition
{
    if (self.activeTextField && !CGRectIsNull(self.keyboardFrame))
    {
        UIWindow *window = [[UIApplication sharedApplication] keyWindow];
        CGRect localKeyboardFrame = [window convertRect: self.keyboardFrame toView:self.view];

        //Have a minimum space between the keyboard and textfield
        CGFloat textFieldBuffer = 40;

        CGRect textFieldFrame = self.activeTextField.frame;

        CGRect viewFrame = self.view.frame;
        viewFrame.origin.y = 0;

        if (CGRectGetMaxY(textFieldFrame) + textFieldBuffer > CGRectGetMinY(localKeyboardFrame))
        {
            viewFrame.origin.y = -1.0 * (CGRectGetMaxY(textFieldFrame) + textFieldBuffer - CGRectGetMinY(localKeyboardFrame));
        }

        [self translateView: self.view toRect: viewFrame withDuration: 0.3];

    }
    else
    {
        CGRect viewFrame = self.view.frame;
        viewFrame.origin.y = 0;
        [self translateView: self.view toRect: viewFrame withDuration: 0.3];
    }
}

-(void)keyboardDidShow:(NSNotification *)notification
{
    self.keyboardFrame = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    [self updatePosition];
}

-(void)keyboardWillHide:(NSNotification *)notification
{
    self.keyboardFrame = CGRectNull;
    [self updatePosition];
}

@end



回答2:


I like to use UITableViewController subclass in situations like you have. Just build your view using UITableView headers footers and cells. When you'll need to make a text edit inside UITextView or Field UITableViewController will layout everything automatically.

It will work even you'll set scrollEnabled property to NO;



来源:https://stackoverflow.com/questions/15052964/adjust-view-for-keyboard-when-switching-uitextfield

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!