Siddharth Dhingra
Siddharth Dhingra

Reputation: 456

Keyboard hiding UIView iOS

I know this question has been asked a few times. I understand how to move the view up or a textfield up when the keyboard is presented, however I am running into a glitch that I cannot seem to figure out.

The view I am trying to move up is inside a UIViewController that acts as a container for two views. This container is itself a view inside a sliding view controller (kind of like the one Facebook implements).

The text field moves up fine when you first load the view however if you go to a different view and come back, the keyboard causes the view to disappear.

Here is the code I am using to move the view up:

    - (void) animateTextField:(BOOL)up {

    const int movementDistance = 350; // tweak as needed
    const float movementDuration = 0; // tweak as needed

    int movement = (up ? -movementDistance : movementDistance);

    [UIView beginAnimations: @"anim" context: nil];
    [UIView setAnimationBeginsFromCurrentState: YES];
    [UIView setAnimationDuration: movementDuration];

    self.sendingToolbar.frame = CGRectOffset(self.sendingToolbar.frame, 0, movement);
    self.messagesTable.frame = CGRectOffset(self.messagesTable.frame, 0, movement);
    //[splitController moveViewUp:up];
    [UIView commitAnimations];

}

- (void)registerForKeyboardNotifications
{
    NSLog(@"was this method called");

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWasShown:)
                                                 name:UIKeyboardDidShowNotification object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillBeHidden:)
                                                 name:UIKeyboardWillHideNotification object:nil];

}

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    [self animateTextField:YES];
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    [self animateTextField:NO];
}

Any ideas why this glitch might be happening? Thanks

After adding the suggestion for a boolean to check if the text field is already up the view disappears all the time when the keyboard is shown and not just when you leave the view and come back. Here is the revised method:

- (void) animateTextField:(BOOL)up {

    const int movementDistance = 350; // tweak as needed
    const float movementDuration = 0; // tweak as needed

    int movement = movementDistance;

    [UIView beginAnimations: @"anim" context: nil];
    [UIView setAnimationBeginsFromCurrentState: YES];
    [UIView setAnimationDuration: movementDuration];

    if(textFieldIsUp && (up == YES)) {
        NSLog(@"Case 1");
        // Do nothing since text field is already up
    }
    else if(textFieldIsUp && (up == NO)) {
        NSLog(@"Case 2");
        // Move the text field down
        self.sendingToolbar.frame = CGRectOffset(self.sendingToolbar.frame, 0, -movement);
        self.messagesTable.frame = CGRectOffset(self.messagesTable.frame, 0, -movement);

        textFieldIsUp = NO;
    }
    else if((textFieldIsUp == NO) && (up == YES)) {
        NSLog(@"Case 3");
        // Move the text field up
        self.sendingToolbar.frame = CGRectOffset(self.sendingToolbar.frame, 0, movement);
        self.messagesTable.frame = CGRectOffset(self.messagesTable.frame, 0, movement);

        textFieldIsUp = YES;
    }
    else if((textFieldIsUp == NO) && (up == NO)) {
        NSLog(@"Case 4");
        // Do nothing since the text field is already down
    }
    else {
        NSLog(@"Default");
        // Default catch all case. Does nothing
    }

    [UIView commitAnimations];

}

Here are some more details about my setup:

The view controller is a messaging center for the app. The view controller contains two subviews the subview on the left side is a menu for picking the conversation and the right menu is a subview with the messages within that conversation. Since I want the messages to load from the bottom up, the table view is rotated 180 degrees and the cells are also rotated 180 degrees the opposite direction. Also the table view reloads every 5 seconds using an NSTimer so that the messages can be updated with any new messages.

Upvotes: 1

Views: 1324

Answers (1)

Dustin
Dustin

Reputation: 6803

The textfield has already been moved up but didn't move back down when you left the view. When you revisit the view it gets moved up again - and off the screen.

I've had this problem before; solved it by keeping a boolean variable the indicated whether the textfield was in the up or down position. Check the variable to make sure the textfield isn't already up before you move it up again.

How I did it. I'm using an NSNumber property on my view to store whether the view has been pushed up or not so that other views can communicate whether they have pushed the view up or down.

//In viewDidLoad
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardWillHideNotification object:nil];

//Pushes the view up if one of the table forms is selected for editing
- (void) keyboardDidShow:(NSNotification *)aNotification
{
    if ([isRaised boolValue] == NO)
    {
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:0.25];
        self.view.center = CGPointMake(self.view.center.x, self.view.center.y-moveAmount);
        [UIView commitAnimations];
        isRaised = [NSNumber numberWithBool:YES];
    }
}

//Push view back down
- (void) keyboardDidHide:(NSNotification *)aNotification
{
    if ([isRaised boolValue])
    {
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:0.25];
        self.view.center = CGPointMake(self.view.center.x, self.view.center.y+moveAmount);
        [UIView commitAnimations];
        isRaised = [NSNumber numberWithBool:NO];
    }
}

-EDIT-

Looking at your code it appears that you're subtracting from the y-coordinate of a frame to move frame down. The iOS coordinate system for CGRect is not the same as a normal coordinate system - the y-axis is flipped (this is relatively common for graphic systems). You're going to want to do the opposite of what you're doing.

Upvotes: 1

Related Questions