tutorial example efecto create apple ios objective-c uitableview drag-and-drop touches

ios - example - uitableview tutorial



Tutorial sobre Cómo arrastrar y soltar elementos de UITableView a UITableView (1)

He estado golpeando mi cabeza en este por un tiempo y lo descubrí. Quiero devolver algo a la comunidad ya que recibí mucha ayuda de este sitio web :).

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
      • UITableViewCell personalizado
        • UIView personalizado que se copia (objeto Persona en mi caso)
    • UIView con UITableView
      • UITableViewCell personalizado
        • UIView personalizado que se copia (objeto Persona en mi caso)

El objeto personal 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; } } } }

Establecí el indicador userInteractionEnabled del objeto Person en NO en la inicialización para que ningún clic en la tabla quede atrapado por el objeto Person. 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 sale de la mesa, 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, ¡publíquela!

EDITAR # 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 touchesEnded se activa en la clase personalizada UITableViewCell.
mj


Hola, he logrado crear arrastrar y soltar de 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. Aquí hay algunas publicaciones sobre los dolores que enfrenté:

  1. UITableView: Arrastre una fila en otra
  2. UITableView: desplazamiento programático de la vista de contenido
  3. UITableView: los gestos personalizados lo hacen desplazarse no más

Espero que esto pueda ayudar ^^