2010-11-04 5 views
4

J'ai un problème sérieux, et je ne peux pas le résoudre par moi-même. J'ai passé des heures à chercher les documentations, les guides de programmation ainsi que les forums de développeurs et les débordements de pile.UITableViewController avec vue sélecteur

Le problème est que je veux afficher une vue sélecteur dans UITableViewController. J'ai un écran qui a plusieurs champs de texte me permettant de faire une recherche par titre/auteur/mots-clés ... et je voudrais aussi spécifier les dates minimum et maximum, en utilisant le UIDatePicker (ou UIPickerView - pour spécifier "5 derniers jours" par exemple). Je souhaite utiliser UITableViewController car cela me permet d'économiser beaucoup de temps lors du redimensionnement de la table lorsque le clavier apparaît lorsque l'utilisateur appuie sur le champ de texte. En fait, je n'ai jamais été capable de reproduire cette animation en utilisant UIViewController et en écoutant le délégué de textfields. C'était presque parfait mais il y avait quelques désavantages visibles comparés au comportement de la table si affiché avec UITableViewController.

Alors tout va bien quand il n'y a que des champs de texte. Mais qu'en est-il des fichiers de date? Je veux faire exactement comme le Contacts.app par Apple quand je veux ajouter un nouveau contact et spécifier l'anniversaire. Dans cette application, le sélecteur de date est affiché, la table est redimensionnée, la commutation entre le champ email/téléphone et l'anniversaire fonctionne très bien. Je pourrais croire que le sélecteur de date est dans ce cas le clavier mais pas pour taper le téléphone/email mais la date parce qu'il glisse dedans/dehors juste comme un clavier et est remplacé immédiatement quand le clavier/sélecteur est ouvert.

Comment l'a-t-il accompli? Où puis-je trouver la solution la plus simple pour le reproduire. Je crois que ça ne peut pas être aussi difficile parce que c'est une situation très courante.

Cordialement Chris

+0

J'ai essayé cela moi-même, et la seule chose que je n'ai pas réussi à faire jusqu'à présent est de redimensionner la vue de la table. – BoltClock

Répondre

7

Tout cela est inutile. Nous devrions traiter avec inputView et inputAccessoryView, où inputView doit avoir le sélecteur et inputAccessoryView la barre d'outils.

+6

Si quelqu'un n'est pas sûr de ce que cette réponse veut dire ... Ensuite, vous devez ajouter un objet UITextField à la cellule du tableau (dans tableView: cellForRowAtIndexPath:) et utiliser la balise view pour pouvoir le récupérer plus tard. Définissez votre contrôleur de vue de table en tant que délégué, puis définissez les propriétés inputView et inputAccessoryView sur les instances UIDatePicker et UIToolbar (à partir de votre plume si vous le souhaitez). Maintenant, le sélecteur se montrera, lorsque vous appuyez sur la cellule. Substituez les méthodes UITextViewDelegate pour formater la sortie à l'aide d'une instance NSDateFormatter. –

0

Si vous voulez glisser dans/la vue du sélecteur, vous pouvez utiliser Core Animation. Simplest Snippet:

// Slide picker view in 
[UIView beginAnimations: @"SlideIn" context: nil]; 
myPickerView.frame = upFrame; 
[UIView commitAnimations]; 

// ... 

// Slide picker view out 
[UIView beginAnimations: @"SlideOut" context: nil]; 
myPickerView.frame = downFrame; 
[UIView commitAnimations]; 

upFrame et downFrame sont CGRect que vous faites avec la bonne position pour votre vue sélecteur sur l'écran et respectivement hors de l'écran.

Espérons que cela aide.

+1

mais myPickerView est ajouté comme une sous-vue de ce que l'élément d'interface utilisateur? Un UITablieView? Si j'ajoute le sélecteur sous forme de sous-vue à la vue de table, elle défilera aussi quand je défilerai la table. Et j'utilise un UITableViewController donc le self.view = tableview –

+0

Ah ... vous devriez l'attacher au parent de votre table si possible. 'self.parentViewController'. – jv42

1

Vous allez devoir créer un objet UIWindow, puis ajouter une vue. La propriété windowLevel le rend plus élevé que le statusBar, que vous pouvez ou ne pas vouloir.

//statusWindow is a UIWindow ivar declared in the header 
//pickerShowing is declared as a BOOL in header 
//release and removeFromSuperview is done in the animation delegate methods 

//ANIMATE IN 

-(void)slideIn { 
    CGRect pickerFrame = CGRectMake(0.0f, 0.0f, 320.0f, 200.0f); //guessing on height 
    UIView *viewForPicker = [[UIView alloc] init]; 
    UIPickerView *aPicker = [[UIPickerView alloc] init]; //don't forget to set delegate and dataSource 
    viewForPicker.frame = pickerFrame; 
    statusWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0.0, 480.0, 320.0f, 200.0f)];//guessing on height, y value is off the screen (bottom) 
    statusWindow.windowLevel = UIWindowLevelStatusBar; 
    statusWindow.hidden = NO; 
    statusWindow.backgroundColor = [UIColor clearColor]; 
    [statusWindow makeKeyAndVisible]; 
    [viewForPicker addSubview:aPicker]; 
    [statusWindow addSubview:viewForPicker]; 
    [viewForPicker release]; 
    [aPicker release]; 
    [UIView beginAnimations:@"slideUp" context:nil]; 
    [UIView setAnimationDuration:0.3]; 
    [UIView setAnimationDelegate:self]; 
    [UIView setAnimationDidStopSelector:@selector(animationFinished:)]; 
    statusWindow.frame = CGRectMake(0.0f, 200.0f, 320.0f, 200.0f); //guessing on y and height values, change them to suit needs 
    [UIView commitAnimations]; 
    pickerShowing = YES; 
} 


//ANIMATE out: 



-(void)slideOut { 
    [UIView beginAnimations:@"slideDown" context:nil]; 
    [UIView setAnimationDuration:0.3]; 
    [UIView setAnimationDelegate:self]; 
    [UIView setAnimationDidStopSelector:@selector(animationFinished:)]; 
    statusWindow.frame = CGRectMake(0.0f, 480.0f, 320.0f, 200.0f); 
    [UIView commitAnimations]; 
    pickerShowing = NO; 
} 

-(void)animationFinished:(NSString *)name { 
    if ([name isEqualToString:@"slideDown"]) { 
     [statusWindow release]; 
    } 
} 
+0

Oui, c'est cool, mais dans ce cas je vais devoir m'occuper de cette fenêtre comme d'un petit bébé. La fenêtre avec le sélecteur reste visible même si j'appuie sur le bouton de retour de mon contrôleur de navigation.Si le clavier du champ de texte est visible, il est masqué lorsque le contrôleur de vue disparaît. N'y a-t-il pas d'autre moyen de jouer avec les claviers et les sélecteurs? Je serais étonné si un jour je voyais le sélecteur et le sélecteur de date comme des types de clavier ... –

+0

Vous devrez définir un BOOL pour quand le sélecteur et UIWindow sont visibles, c'est-à-dire quand le slideIn est fait . Réglez le BOOL sur NO lorsque la glissière est terminée. Vérifiez le BOOL dans viewWillDisappear de votre viewController, et si c'est OUI, appelez la méthode slideOut. Cela devra être déclaré dans l'en-tête comme BOOL pickerShowing; – Justin

+0

J'ai ajouté le BOOL dans le code ci-dessus – Justin

0
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *targetCell = [tableView cellForRowAtIndexPath:indexPath]; 
    self.pickerView.date = [self.dateFormatter dateFromString:targetCell.detailTextLabel.text]; 

    // check if our date picker is already on screen 
    if (self.pickerView.superview == nil) 
    { 
     [self.view.window addSubview: self.pickerView]; 

     // size up the picker view to our screen and compute the start/end frame origin for our slide up animation 
     // 
     // compute the start frame 
     CGRect screenRect = [[UIScreen mainScreen] applicationFrame]; 
     CGSize pickerSize = [self.pickerView sizeThatFits:CGSizeZero]; 
     CGRect startRect = CGRectMake(0.0, 
             screenRect.origin.y + screenRect.size.height, 
             pickerSize.width, pickerSize.height); 
     self.pickerView.frame = startRect; 

     // compute the end frame 
     CGRect pickerRect = CGRectMake(0.0, 
             screenRect.origin.y + screenRect.size.height - pickerSize.height, 
             pickerSize.width, 
             pickerSize.height); 
     // start the slide up animation 
     [UIView beginAnimations:nil context:NULL]; 
      [UIView setAnimationDuration:0.3]; 

      // we need to perform some post operations after the animation is complete 
      [UIView setAnimationDelegate:self]; 

      self.pickerView.frame = pickerRect; 

      // shrink the table vertical size to make room for the date picker 
      CGRect newFrame = self.tableView.frame; 
      newFrame.size.height -= self.pickerView.frame.size.height; 
      self.tableView.frame = newFrame; 
     [UIView commitAnimations]; 

     // add the "Done" button to the nav bar 
     self.navigationItem.rightBarButtonItem = self.doneButton; 
    } 
} 

- (void)slideDownDidStop 
{ 
    // the date picker has finished sliding downwards, so remove it 
    [self.pickerView removeFromSuperview]; 
} 

- (IBAction)dateAction:(id)sender 
{ 
    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; 
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; 
    cell.detailTextLabel.text = [self.dateFormatter stringFromDate:self.pickerView.date]; 
} 

- (IBAction)doneAction:(id)sender 
{ 
    CGRect screenRect = [[UIScreen mainScreen] applicationFrame]; 
    CGRect endFrame = self.pickerView.frame; 
    endFrame.origin.y = screenRect.origin.y + screenRect.size.height; 

    // start the slide down animation 
    [UIView beginAnimations:nil context:NULL]; 
     [UIView setAnimationDuration:0.3]; 

     // we need to perform some post operations after the animation is complete 
     [UIView setAnimationDelegate:self]; 
     [UIView setAnimationDidStopSelector:@selector(slideDownDidStop)]; 

     self.pickerView.frame = endFrame; 
    [UIView commitAnimations]; 

    // grow the table back again in vertical size to make room for the date picker 
    CGRect newFrame = self.tableView.frame; 
    newFrame.size.height += self.pickerView.frame.size.height; 
    self.tableView.frame = newFrame; 

    // remove the "Done" button in the nav bar 
    self.navigationItem.rightBarButtonItem = nil; 

    // deselect the current table row 
    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; 
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 
} 

Vous pouvez télécharger une application de l'échantillon de travail complet d'Apple démontrant que cela. http://developer.apple.com/library/ios/#samplecode/DateCell/Introduction/Intro.html

Questions connexes