2010-08-14 24 views
46

Je me suis cogné la tête sur celui-ci pendant un moment et je l'ai compris. Je veux redonner à la communauté depuis que j'ai reçu beaucoup d'aide de ce site :). J'essaie de copier un élément d'un UITableView à un autre UITableView et les informations que j'ai vu sur le Web concernant comment faire ceci ont été sommaires au mieux. Je me suis débrouillé seul et je vais donc décrire ma petite architecture.Tutoriel sur Comment faire glisser et déposer l'élément de UITableView à UITableView

  • Maître UIView
    • UIView avec UITableView
      • sur mesure UITableViewCell
        • personnalisé UIView qui obtient copié (objet Personne dans mon cas)
    • UIView avec UITableView
      • sur mesure UITableViewCell
        • personnalisé UIView qui obtient copié (objet Personne dans mon cas)

L'objet personne que j'ai en UITableView est l'objet que je veux faire glisser et déposer d'une table dans une autre. J'ai eu le plus de mal à trouver comment sortir l'objet de la table et le faire glisser en un seul mouvement fluide. Pour le plus long temps, il me faudrait deux touches pour effectuer l'opération. À partir de l'objet Personne, il s'agit d'un objet simple qui contient une image.

J'ai dû implémenter ma propre méthode touchesMoved pour changer la position centrale de la personne quand un glissement a lieu.

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ 
    if(m_moveable == YES){ 
     UITouch *touch = [touches anyObject]; 
     CGPoint location = [touch locationInView:self.superview]; 

     if(0 < location.x-50 && location.x+50 < 768){ 
      if(0 < location.y-50 && location.y+150 < 1004){ 
       self.center = location; 
      } 
     } 
    } 
} 

Je mis le drapeau de l'objet Personne userInteractionEnabled à NO sur l'initialisation pour que les clics dans le tableau ne serait pas se laisser prendre par l'objet Personne. L'objet Person dans ce cas se déplacerait dans la table qui va à l'encontre du but.

L'objet suivant est mon UITableViewCell personnalisé. Cet objet est responsable d'attraper le premier contact de l'utilisateur. Qu'est-ce qu'il est censé faire est d'attraper cette touche et "pop" de la personne. La personne est l'une des sous-vues appartenant à la personnalisation UITableViewCell.

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    UIView *parent = self.superview.superview.superview;  

    Person *s = nil; 
    for(UIView *child in self.subviews){ 
     if([child isKindOfClass:[Person class]]){ 
      s = child; 
      s removeFromSuperview]; 
      break; 
     }   
    } 

    if(s != nil){ 
     self.userInteractionEnabled = NO; 
     s.userInteractionEnabled = YES; 
     UITableView *subParent = self.superview; //EDIT #1 
     subParent.scrollEnabled = NO;    //EDIT #1 

     [parent addSubview:s]; 
     //[self touchesEnded:touches withEvent:event]; //EDIT #1 
    } 
} 

Il est important de noter que l'indicateur userInteractionEnabled est retourné dans la méthode ci-dessus. Avant le toucher, l'objet Personne est «hors limites» au toucher d'une personne. Une fois que la cellule personnalisée a attrapé un mouvement, la personne est libérée en l'ajoutant à la vue du parent, puis activée (userInteractionEnabled = YES). L'objet Personne est alors "né" et peut gérer les touches individuelles.

Cela a un petit pépin en ce que l'objet Personne clignote dans le coin supérieur gauche, mais tombe ensuite immédiatement au doigt de l'utilisateur.

La dernière partie de cette conception est que le maître UIView doit gérer une «transition tactile». Lorsque l'utilisateur touche la table et que l'objet Personne est retiré, l'application doit réaliser que le focus doit être supprimé de la table et dirigé vers l'objet Personne. La façon dont cela a été fait est que la méthode hitTest dans le maître UIView était surchargée avec ce qui suit.

- (UIView*) hitTest:(CGPoint)point withEvent:(UIEvent *)event { 
    UIView *rv = nil; 
    for(UIView *child in self.subviews){ 
     if([child isKindOfClass:[Person class]]){ 
      rv = child; 
      child.center = point; 
      break; 
     } 
    } 
    if(rv == nil){ 
     rv = [super hitTest:point withEvent:event]; 
    } 
    return rv; 
} 

La façon dont ce code fonctionne, est que lorsque la personne est émergea de la table, il ne dispose pas d'une touche concentrée à elle. La touche est "possédée" par UITableView d'où la personne a été expulsée. La méthode hitTest est la clé pour recentrer ce contact. Régulièrement, le système vérifie que UIView est l'objet d'un contact. La méthode hitTest est appelée par le système pour identifier cette UIView. Lorsque la personne est attachée à la vue principale, cette fonction hitTest parcourt toutes les sous-vues et détecte la présence de la personne et la renvoie comme objet touché «dominant». Tout mouvement de votre doigt sera immédiatement signalé à la personne et non à UITableView.

Ceci est le courage de la mise en œuvre. Pour avoir un UITableView "attraper" l'objet en mouvement est simple maintenant et je vais le laisser pour vous d'essayer! Si vous avez des questions, s'il vous plaît les poster!

EDIT # 1 La suppression de l'objet Person s'avère plus difficile que je ne le pensais :). J'ai dû ajouter une ligne pour empêcher le UITableView de défiler quand le parent est déplacé parce que UITableView aspire dans tous les événements de mouvement.
La fonction touchesEnded se déclenche dans la classe UITableViewCell personnalisée.
mj

+0

@mj_: excellent travail, et félicitations pour partage! Il semble que beaucoup de temps et d'efforts ont été dépensés. +1 vote pour vous! –

+0

Ne pas donner mon upvote car ce n'est pas une question, mais marqué comme un favori, car il est toujours génial de toute façon. Bien joué! – BoltClock

+3

StackOverflow n'est pas votre blog. S'il vous plaît garder ce site un site de questions et réponses en ne collant aux questions et réponses seulement. –

Répondre

7

Salut, j'ai réussi à créer une traînée & chute d'une ligne dans un UITableView sur une autre ligne de la même table. J'ai créé un uiImageView représentant l'objet en mouvement (qui n'a pas été retiré de la table) et l'ai attaché à l'UIView le plus en avant pour le rendre glissant sur tout l'écran. Voici quelques-uns post sur les douleurs que je dû faire face:

  1. UITableView: Drag a row onto another one
  2. UITableView: scrolling programmatically the content view
  3. UITableView: custom gestures make it scrolling no more

Hope this peut aider ^^

+0

Bonjour, pouvez-vous s'il vous plaît partager votre code? – TilalHusain

+2

Salut! Je sais que c'est vieux, mais cela pourrait aider? https://github.com/Ice3SteveFortune/i3-dragndrop – sf13579

+1

Pour les personnes qui cherchent encore cela en 2016 et après, j'ai un projet de test rapide que j'ai fouetté. J'espère que cela t'aides. https://github.com/BridgeTheGap/Trelloesque – BridgeTheGap