web-dev-qa-db-fra.com

Xcode / iOS5: déplacez UIView vers le haut, lorsque le clavier apparaît

J'aimerais remonter ma vue lorsque le clavier est affiché. Le clavier (hauteur: 216) devrait pousser ma vue avec sa hauteur. Est-ce possible avec un code simple?

49
filou

Pour déplacer la vue up, changez simplement son center. Tout d'abord, conservez l'original dans une propriété CGPoint.

- (void)viewDidLoad 
{
    ...
    self.originalCenter = self.view.center;
    ...
}

Ensuite, modifiez au besoin lorsque le clavier apparaît:

self.view.center = CGPointMake(self.originalCenter.x, /* new calculated y */);

Enfin, restaurez-le lorsque le clavier est masqué:

self.view.center = self.originalCenter;

Ajoutez du sucre d'animation comme vous le souhaitez

Vous avez plusieurs façons de savoir quand le clavier apparaît.

Observation IKeyboardDidShowNotification notification.

/* register notification in any of your initWithNibName:bundle:, viewDidLoad, awakeFromNib, etc. */
{
    ...
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];     
    ...
}

- (void)keyboardDidShow:(NSNotification *)note 
{
    /* move your views here */
}

Faites le contraire avec UIKeyboardDidHideNotification.

-OU-

Implémenter ITextFieldDelegate

Détectez lorsque vous modifiez le début/la fin pour déplacer les vues.

- (void)textFieldDidBeginEditing:(UITextField *)textField 
{
    /* keyboard is visible, move views */
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    /* resign first responder, hide keyboard, move views */
}

En fonction des champs de texte réels dont vous pouvez avoir besoin pour suivre dans quel champ l'utilisateur modifie, ajoutez une minuterie pour éviter de trop déplacer les vues.

97
djromero

fait comme ça. après que le clavier soit visible, utilisez ce code

- (void)textFieldDidBeginEditing:(UITextField *)textField 
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.25];
    self.view.frame = CGRectMake(0,-10,320,480);
    [UIView commitAnimations];

}
31
Tendulkar

C'est le moyen le plus simple et le plus efficace d'y parvenir:

Ajoutez les constantes suivantes:

static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;    

Ajoutez ceci à votre contrôleur de vue:

CGFloat animatedDistance;

Et ajoutez ces méthodes à votre code:

- (void)textFieldDidBeginEditing:(UITextField *)textField{
CGRect textFieldRect =
[self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect =
[self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.Origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator =
midline - viewRect.Origin.y
- MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator =
(MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
* viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
    heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
    heightFraction = 1.0;
}
UIInterfaceOrientation orientation =
[[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait ||
    orientation == UIInterfaceOrientationPortraitUpsideDown)
{
    animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
}
else
{
    animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
}
CGRect viewFrame = self.view.frame;
viewFrame.Origin.y -= animatedDistance;

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

[self.view setFrame:viewFrame];

[UIView commitAnimations];
}

- (void)textFieldDidEndEditing:(UITextField *)textfield{

CGRect viewFrame = self.view.frame;
viewFrame.Origin.y += animatedDistance;

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

[self.view setFrame:viewFrame];

[UIView commitAnimations];
}
13
Kishore Suthar

J'ai fait cela d'une manière similaire à djromero, sauf que j'ai ajusté l'origine du cadre de la vue plutôt que son centre.

La vue que je déplace est un UIScrollView, et je veux qu'il se déplace par rapport à un élément UITextField, de sorte que le champ de texte s'affiche toujours. La position de ce champ de texte peut varier en fonction du décalage de la vue de défilement.

Donc, mon code ressemble à ceci:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    dispatch_async(dispatch_get_main_queue(), ^{
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.2];
        [UIView setAnimationCurve:UIViewAnimationCurveLinear];
        self.scrollView.frame = CGRectMake(0,0,self.scrollView.frame.size.width,self.scrollView.frame.size.height);
        [UIView commitAnimations];
    });
    return YES;
}

- (NSInteger)getKeyBoardHeight:(NSNotification *)notification
{
    NSDictionary* keyboardInfo = [notification userInfo];
    NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
    CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
    NSInteger keyboardHeight = keyboardFrameBeginRect.size.height;
    return keyboardHeight;
}

-(void) keyboardDidShow:(NSNotification*) notification
{
    NSInteger keyboardHeight;
    keyboardHeight = [self getKeyBoardHeight:notification];
    NSInteger scrollViewFrameHeight = self.scrollView.frame.size.height;
    NSInteger textFieldRelativePosition = self.tableView.frame.Origin.y - self.scrollView.contentOffset.y;
    NSInteger textFieldFrameOffset = scrollViewFrameHeight - textFieldRelativePosition;
    NSInteger movement = MAX(0,keyboardHeight-textFieldFrameOffset); // Offset from where the keyboard will appear.
    dispatch_async(dispatch_get_main_queue(), ^{
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.2];
        [UIView setAnimationCurve:UIViewAnimationCurveLinear];
        self.scrollView.frame = CGRectMake(0,-movement,
                                           self.scrollView.frame.size.width,
                                           self.scrollView.frame.size.height);
        [UIView commitAnimations];
    });
}

Le contrôleur de vue est un UITextFieldDelegate et s'abonne également à UIKeyboardDidShowNotification afin que nous puissions accéder à la taille du clavier.

Lorsque le clavier s'affiche, nous calculons le décalage relatif de l'UITextField (ajusté pour le décalage de défilement) et le clavier et eux modifient l'origine de l'UIScrollView afin qu'il se déplace juste assez pour que l'UITextField reste à afficher.

Si UITextField s'affiche toujours même si le clavier apparaît, alors l'origine ne change pas.

13
Michael
5
len
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    CGFloat y = textField.frame.Origin.y;
    if (y >= 350) //not 380
   {
        CGRect frame = self.view.frame;
        frame.Origin.y = 320 - textField.frame.Origin.y;
        [UIView animateWithDuration:0.3 animations:^{self.view.frame = frame;}];
    }
}

-(void)textFieldDidEndEditing:(UITextField *)textField
{
CGRect returnframe =self.view.frame;
returnframe.Origin.y = 0;
[UIView animateWithDuration:0.3 animations:^{self.view.frame = frame;}];
}

éditez simplement ces deux méthodes.
réponse simple à tous les codes d. Dans l'instruction if, changez la valeur en fonction de l'iphone, c'est-à-dire si iphone 4S changez-la en 265 et en didbeginediting changez 320 en 240 et si iphone 5 changez-la en 350 et en méthode didbeginediting gardez-la 320, car c'est la logique si tu comprends

2
sreekanthk

Vraisemblablement, vous avez du code appelant [myTextField becomeFirstResponder];. Vous devez déplacer votre vue juste après cet appel.

1
James Webster

Il s'agit de la solution Tendulkar, mais en gardant à l'esprit la taille du cadre d'origine et en retirant le clavier. Cette solution fonctionne pour tous les appareils.

-(BOOL) textFieldShouldReturn:(UITextField *)textField{

[textField resignFirstResponder];

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
self.view.frame = CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height);
[UIView commitAnimations];
return YES;
 }


- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.25];
    self.view.frame = CGRectMake(0,-50,self.view.frame.size.width,self.view.frame.size.height);
    [UIView commitAnimations];

}

N'oubliez pas de définir le délégué UITextField!

Exemple de projet basé sur Apple Référence Documentation du clavier

Fichier H: (N'oubliez pas le UITextFieldDelegate)

@property (weak, nonatomic) IBOutlet UIScrollView *scrollview;

@property (weak, nonatomic) IBOutlet UIView *myView;


    //items on view
@property (weak, nonatomic) IBOutlet UISwitch *partySwitch;
@property (weak, nonatomic) IBOutlet UILabel *partyLabel;
@property (weak, nonatomic) IBOutlet UITextField *partyNameTextfield;

Fichier M:

    //MARK: View Loading
- (void)viewDidLoad
{
    [super viewDidLoad];
        // Do any additional setup after loading the view.
}//eom

-(void)viewDidAppear:(BOOL)animated
{
    [self registerForKeyboardNotifications];
}//eom

    //MARK: textfield delegates
-(bool)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return true;
}//eom

    //MARK: - Keyboard Observers
    // Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWasShown:)
                                                 name:UIKeyboardDidShowNotification object:nil];

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

}


- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info      = [aNotification userInfo];
    CGSize kbSize           = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    CGRect bkgndRect        = myView.superview.frame;
    bkgndRect.size.height += kbSize.height;

    [myView.superview setFrame:bkgndRect];
    [scrollview setContentOffset:CGPointMake(0.0, myView.frame.Origin.y-kbSize.height) animated:YES];
}//eom

    // Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets          = UIEdgeInsetsZero;
    scrollview.contentInset             = contentInsets;
    scrollview.scrollIndicatorInsets    = contentInsets;
}//eom
0
LuAndre