2010-08-14 17 views
46

He estado golpeando mi cabeza en este durante un tiempo y lo descubrí. Quiero devolver algo a la comunidad ya que recibí mucha ayuda de este sitio web :).Tutorial sobre Cómo arrastrar y soltar elemento de UITableView a UITableView

Estoy tratando de copiar un elemento de una UITableView a otra UITableView y la información que he visto en la web sobre cómo hacer esto ha sido incompleta en el mejor de los casos. Lo descubrí por mi cuenta y entonces describiré mi pequeña arquitectura.

  • Maestro UIView
    • UIView con UITableView
      • personalizada UITableViewCell
        • personalizada UIView que se copia (objeto Persona en mi caso)
    • UIView con UITableView
      • personalizada UITableViewCell
        • personalizada UIView que se copia (objeto Persona en mi caso)

El objeto persona que tengo en UITableView es el objeto que quiero arrastrar y soltar de una tabla a otra. Tuve el problema más difícil de descifrar cómo sacar el elemento de la mesa y arrastrarlo con un solo movimiento suave. Durante mucho tiempo, me llevaría dos toques para realizar la operación.

Comenzando con el objeto Persona, este es un objeto simple que contiene una imagen. Tuve que implementar mi propio método touchesMoved para cambiar la posición central de la Persona cuando se está llevando a cabo un arrastre.

-(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; 
      } 
     } 
    } 
} 

puse la bandera userInteractionEnabled de la persona objeto de NO en la inicialización de modo que los clics en la tabla no quedar atrapados por la persona objeto. El objeto Persona en ese caso se movería dentro de la tabla que anula el propósito.

El siguiente objeto es mi UITableViewCell personalizado. Este objeto es responsable de atrapar el primer toque del usuario. Lo que se supone que debe hacer es capturar este toque y "sacar" a la persona. La persona es una de las subvistas que pertenecen a la UITableViewCell personalizada.

- (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 
    } 
} 

Es importante tener en cuenta que la bandera UserInteractionEnabled se invirtió en el método anterior. Antes del toque, el objeto Persona está "fuera de los límites" del toque de una persona. Después de que la celda personalizada capta un movimiento, la Persona se libera agregándola a la vista principal y luego activada (userInteractionEnabled = YES). El objeto Persona entonces "nace" y puede manejar toques de movimiento por sí mismo.

Esto tiene un problema menor ya que el objeto Persona parpadea en la esquina superior izquierda, pero luego cae inmediatamente al dedo del usuario.

La parte final de este diseño es que el maestro UIView necesita manejar una "transición táctil". Cuando el usuario toca la mesa y aparece el objeto Persona, la aplicación debe darse cuenta de que el foco debe eliminarse de la mesa y dirigirse hacia el objeto Persona. La forma en que esto se hizo es que el método hitTest en el UIView maestro estaba sobrecargado con lo siguiente.

- (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 forma en que funciona este código, es que cuando la persona se salió de la mesa, que no tiene un toque centrado en ella. El tacto es "propiedad" de UITableView del que salió la persona. El método hitTest es la clave para reenfocar ese toque. Regularmente, el sistema verifica qué UIView es el foco de un toque. El sistema llama al método hitTest para identificar ese UIView. Cuando la Persona está unida a la vista maestra, esta función HitTest recorre todas las subvistas y detecta la presencia de la Persona y la devuelve como el objeto tocado "dominante". Cualquier movimiento de su dedo se informará inmediatamente a la persona y no a UITableView.

Esto es agallas de la implementación. ¡Tener una UITableView "atrapar" el objeto en movimiento es simple ahora y lo dejo para que lo intente! ¡Si tiene alguna pregunta, por favor publíquela!

EDIT # 1 Dejar caer el objeto Persona está resultando más difícil de lo que pensaba :). Tuve que agregar una línea para evitar que UITableView se desplace cuando se mueve el elemento primario porque el UITableView está absorbiendo todos los eventos de movimiento.
La función toquesEnded se activa en la clase UITableViewCell personalizada.
mj

+0

@mj_: gran trabajo, y felicitaciones por compartiendo! Parece que se gastó mucho tiempo y esfuerzo. ¡+1 voto por ti! –

+0

No dar mi voto explícito ya que esto no es una pregunta, pero marcado como favorito porque de todos modos sigue siendo impresionante. ¡Bien hecho! – BoltClock

+3

StackOverflow no es tu blog. Por favor, mantenga este sitio como un sitio de preguntas y respuestas solo con preguntas y respuestas. –

Respuesta

7

Hola He logrado crear arrastrar & colocar una fila en una UITableView en otra fila de la misma tabla. Creé uiImageView que representa el elemento en movimiento (que no se eliminó de la tabla) y lo adjunté a la parte delantera de UIView para que se pueda arrastrar en toda la pantalla. Éstos son algunos post sobre los dolores que tuve que enfrentar:

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

la esperanza que esto puede ayudar ^^

+0

Hola, ¿puedes compartir tu código? – TilalHusain

+2

¡Hola! Sé que esto es viejo, pero esto podría ayudar? https://github.com/Ice3SteveFortune/i3-dragndrop – sf13579

+1

Para las personas que todavía están buscando esto en 2016 y después, tengo un proyecto de prueba rápido que impulsé. Espero que esto ayude. https://github.com/BridgeTheGap/Trelloesque – BridgeTheGap