Best Way To Move View Up When Keyboard Shows

Discussion in 'iOS Programming' started by loon3y, Oct 2, 2012.

  1. loon3y macrumors 65816

    loon3y

    Joined:
    Oct 21, 2011
    #1
    how can i move the UITextFields and Labels, when the keyboard appears?


    so far ive only managed to move the background lol.



    i've used this code that i found on stackoverflow, it seemed nice because he made his own class.



    Code:
    
    KBKeyboardHandler.h:
    
    @protocol KBKeyboardHandlerDelegate;
    
    @interface KBKeyboardHandler : NSObject
    
    - (id)init;
    
    // Put 'weak' instead of 'assign' if you use ARC
    @property(nonatomic, assign) id<KBKeyboardHandlerDelegate> delegate; 
    @property(nonatomic) CGRect frame;
    
    @end


    Code:
    KBKeyboardHandler.m:
    
    #import "KBKeyboardHandler.h"
    #import "KBKeyboardHandlerDelegate.h"
    
    @implementation KBKeyboardHandler
    
    - (id)init
    {
        self = [super init];
        if (self)
        {
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(keyboardWillShow:)
                                                         name:UIKeyboardWillShowNotification
                                                       object:nil];
    
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(keyboardWillHide:)
                                                         name:UIKeyboardWillHideNotification
                                                       object:nil];
        }
    
        return self;
    }
    
    - (void)dealloc
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
        [super dealloc];
    }
    
    @synthesize delegate;
    @synthesize frame;
    
    - (void)keyboardWillShow:(NSNotification *)notification
    {
        CGRect oldFrame = self.frame;    
        [self retrieveFrameFromNotification:notification];
    
        if (oldFrame.size.height != self.frame.size.height)
        {
            CGSize delta = CGSizeMake(self.frame.size.width - oldFrame.size.width,
                                      self.frame.size.height - oldFrame.size.height);
            if (self.delegate)
                [self notifySizeChanged:delta notification:notification];
        }
    }
    
    - (void)keyboardWillHide:(NSNotification *)notification
    {
        if (self.frame.size.height > 0.0)
        {
            [self retrieveFrameFromNotification:notification];
            CGSize delta = CGSizeMake(-self.frame.size.width, -self.frame.size.height);
    
            if (self.delegate)
                [self notifySizeChanged:delta notification:notification];
        }
    
        self.frame = CGRectZero;
    }
    
    - (void)retrieveFrameFromNotification:(NSNotification *)notification
    {
        CGRect keyboardRect;
        [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardRect];
        self.frame = [[UIApplication sharedApplication].keyWindow.rootViewController.view convertRect:keyboardRect fromView:nil];
    }
    
    - (void)notifySizeChanged:(CGSize)delta notification:(NSNotification *)notification
    {
        NSDictionary *info = [notification userInfo];
    
        UIViewAnimationCurve curve;
        [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&curve];
    
        NSTimeInterval duration;
        [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&duration];
    
        void (^action)(void) = ^{
            [self.delegate keyboardSizeChanged:delta];
        };
    
        [UIView animateWithDuration:duration
                              delay:0.0
                            options:curve
                         animations:action
                         completion:nil];    
    }
    
    @end


    Code:
    KBKeyboardHandlerDelegate.h:
    
    @protocol KBKeyboardHandlerDelegate
    
    - (void)keyboardSizeChanged:(CGSize)delta;
    
    @end



    Code:
    MyViewController.m:
    
    @implementation MyViewController
    {
        KBKeyboardHandler *keyboard;
    }
    
    - (void)dealloc
    {
        keyboard.delegate = nil;
        [keyboard release];
        [super dealloc];
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        keyboard = [[KBKeyboardHandler alloc] init];
        keyboard.delegate = self;
    }
    
    - (void)viewDidUnload
    {
        [super viewDidUnload];
        keyboard.delegate = nil;
        [keyboard release];
        keyboard = nil;
    }
    
    - (void)keyboardSizeChanged:(CGSize)delta
    {
        // Resize / reposition your views here. All actions performed here 
        // will appear animated.
        // delta is the difference between the previous size of the keyboard 
        // and the new one.
        // For instance when the keyboard is shown, 
        // delta may has width=768, height=264,
        // when the keyboard is hidden: width=-768, height=-264.
        // Use keyboard.frame.size to get the real keyboard size.
    
        // Sample:
        CGRect frame = self.view.frame;
        frame.size.height -= delta.height;
        self.view.frame = frame;
    }


    it seems like to me its just resizing my keyboard rather than moving anything up?


    but it was weird, the OP question was to move the textfields and labels up,

    but this was one of the better answers :confused:
     
  2. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #2


    That code appears to be moving the view controller's entire content view up, which is what I recommend. That way, EVERYTHING slides up to make room for the keyboard. If you implement that code in your view controller, everything should move up, not just the background.

    What do you mean that only the background moves up?
     
  3. loon3y thread starter macrumors 65816

    loon3y

    Joined:
    Oct 21, 2011
    #3


    only the background moves up, like the image/wallpaper i put on there.

    on my 3GS it doesnt even move or give the animation, but it does in the simulator and newer devices


    my textfields, labels, image, and button, do not move up at all.


    all i see is the background moving up and down, is a scrollview needed?
     
  4. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #4
    No. The code you posted should be moving the view controller's entire content view.
    You must have done something wrong. Show us where you put that code, and give us an explanation of the view hierarchy that you're using.
     
  5. loon3y thread starter macrumors 65816

    loon3y

    Joined:
    Oct 21, 2011
    #5


    this view is my login viewcontroller, its modally called from viewDidAppear from the first viewcontroller in my tab bar app, the viewcontroller is shown first and than the login view pulls up (not sure if it matters).


    i put all the coding in the loginviewcontroller.m file, i basically did it almost exactly how this guy did it,


    i used his sample formula/logic, to check it out but it didnt work,
     
  6. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #6
    I've set up code that slides a view controller's entire content view up for the keyboard and it works flawlessly, on iOS 3.2 all the way up to iOS 6.

    You didn't answer my questions so there's no way I can help you.
     
  7. lasash macrumors member

    Joined:
    Sep 15, 2012
    #7
    I would put the text fields in a separate view, then create the view (i.e. contactFormView) and add it CGRectMake in the M file:

    Code:
    contactFormView.frame=CGRectMake(0, 460, 320, 261);
    
    Then, when the keyboard pops in (you probably have an method for that), I would move the entire view:

    Code:
    - (void)showContactFormView:(id)sender
    {
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:0.3];
        contactFormView.frame=CGRectMake(0, 120, [[UIScreen mainScreen] bounds].size.width, 260);
        [UIView commitAnimations];
    }
    
    And when the keyboard is dismissed, I would move it back to it's original state.
    That way, you can move the view with an animation to a different position for each text field in your view.
     
  8. GroovyMan1976 macrumors newbie

    GroovyMan1976

    Joined:
    May 22, 2012
    Location:
    Reading, UK
    #8
    You could put your text fields in a table view.. I think then the table view will handle this for you.
     

Share This Page