Quiero tener una vista en la que hay vehículos que circulan en torno a que el usuario también puede arrastrar y soltar. ¿Cuál crees que es el mejor a gran escala de la estrategia para hacer esto? Es la mejor forma de obtener eventos de toque a partir de las opiniones que representan los vehículos, o de la más grande a la vista? Hay un paradigma simple que usted ha utilizado para arrastrar y soltar de que estás satisfecho con los resultados? ¿Cuáles son las desventajas de las diferentes estrategias?

InformationsquelleAutor Luke | 2011-01-16

8 Comentarios

  1. 126

    Supongamos que usted tiene una UIView escena con una imagen de fondo y muchos vehicles, usted puede definir cada nuevo vehículo como un UIButton (UIImageView es probable que el trabajo también):

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button addTarget:self action:@selector(imageTouch:withEvent:) forControlEvents:UIControlEventTouchDown];
    [button addTarget:self action:@selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragInside];
    [button setImage:[UIImage imageNamed:@"vehicle.png"] forState:UIControlStateNormal];
    [self.view addSubview:button];

    A continuación, puede mover el vehículo a donde quieras, por responder a la UIControlEventTouchDragInside evento, por ejemplo:

    - (IBAction) imageMoved:(id) sender withEvent:(UIEvent *) event
    {
        CGPoint point = [[[event allTouches] anyObject] locationInView:self.view];
        UIControl *control = sender;
        control.center = point;
    }

    Es mucho más fácil para el individuo vehículo para manejar su propia arrastra, comparando a gestionar la escena como un todo.

    • Se ve genial y muy sencillo! Voy a probar esto.
    • Sería esta estrategia causar arrastrando a romperse si el usuario arrastra el botón más rápido que la animación se actualiza? Si su dedo consiguió fuera de la caja, dejaría de recibir el imageMoved:withEvent: llamadas, ¿correcto?
    • Sí, Tim, lo hace.
    • ¿Cómo puede usted saber si la imagen deja de arrastrar? ¿Cómo sabes dedo mudó?
    • ohho – es posible compensar el arrastre de «mango» para una imagen o un botón de modo que pueda ser arrastrado por la parte superior derecha o la esquina superior izquierda?
    • cuando estoy tratando de conseguir excepción–[drag_move_textViewController imageTouch:withEvent:]: no reconocidos selector enviado a la instancia 0x4b4b1c0
    • debe ser «corregido» por la orientación de UIControlEventTouchDragOutside evento?
    • realmente…tendrías que estar arrastrando bastante rápido 🙂 yo simplemente no recomendamos el uso de este para cualquier tipo de juego, pero para la aplicación típica, esto funciona.
    • Un poco tarde, pero usted puede intentar esto con UIPanGestureRecognizer demasiado. Que no rompa por cualquier arrastre de velocidad.

  2. 34

    Además ohho la respuesta, he probado con una implementación similar, pero sin el problema de la «rápida» arrastrar y centrado en el arrastre.

    El botón de inicialización es…

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button addTarget:self action:@selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragInside];
    [button addTarget:self action:@selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragOutside];
    [button setImage:[UIImage imageNamed:@"vehicle.png"] forState:UIControlStateNormal];
    [self.view addSubview:button];

    y método de aplicación:

    - (IBAction) imageMoved:(id) sender withEvent:(UIEvent *) event
    {
        UIControl *control = sender;
    
        UITouch *t = [[event allTouches] anyObject];
        CGPoint pPrev = [t previousLocationInView:control];
        CGPoint p = [t locationInView:control];
    
        CGPoint center = control.center;
        center.x += p.x - pPrev.x;
        center.y += p.y - pPrev.y;
        control.center = center;
    }

    Yo no digo, que esta es la solución perfecta para la respuesta. Sin embargo, me pareció que la solución más fácil para el arrastre.

    • En el ejemplo de código, se define UIControl *control=remitente después de que se utiliza – en caso de que no se definió anteriormente?
    • En realidad no importa en este caso. No hay antes del uso de esta variable desde la línea Que hemos mencionado 🙂
    • ¿Qué acerca de CGPoint pPrev = [t previousLocationInView:control]; CGPoint p = [t locationInView:control]; Estos dos anteriores líneas parecen referirse a «control»?
    • Oh gosh! ¿Cómo puede que me perdí? :-O … he editado la respuesta.
    • Bueno! gracias por el fragmento.
    • puedo añadir el botón formulario de interface builder y yo uso el diseño automático para algunas de inicio de sesión hago ocultar el botón y se mostrará de nuevo cuando lo hago es volver al lugar original de cómo evitar que esto beviour

  3. 2

    Tuve un caso donde me gustaría arrastrar/soltar uiviews entre otras múltiples uiviews. En ese caso me pareció la mejor solución para trazar el pan eventos en una super vista que contiene todas las zonas de colocación y todos los arrastre gable objetos. La razón principal para NO añadir el evento a los oyentes a la real arrastrado opiniones fue que perdí el curso de pan eventos tan pronto como he cambiado superview para la arrastró a la vista.

    Lugar que he implementado un lugar genérico arrastrar y soltar solución que podría ser utilizado en un único o múltiples zonas de colocación.

    He creado un sencillo ejemplo que puede ser visto aquí: Arrastre una caída uiviews entre otras múltiples uiviews

    Si usted decide ir por el otro camino, trate de usar uicontrol en lugar de uibutton. Declaran que la addTarget métodos y son mucho más fáciles de extender, de ahí dar personalizada estado y comportamiento.

  4. 1

    Yo en realidad iba a la pista de arrastre en el vehículo de vista mismo, en lugar de la gran vista – a menos que haya una razón en particular, no para.

    En uno de los casos donde puedo permitir que el usuario coloque los elementos arrastrándolos en la pantalla.
    En ese caso he experimentado con ambos tienen la vista superior y la niño vistas arrastrables. He encontrado es un código más limpio si agrega un par de «arrastrarse» vistas a la UIView y mango de cómo podrían ser arrastrados. He utilizado una simple devolución de llamada a los padres UIView para comprobar si la nueva ubicación era conveniente o no – así me podría indicar con animaciones.

    Tener la vista superior pista arrastrando supongo que es tan bueno, pero que la hace un poco más desordenado de si le gustaría añadir que no se pueden arrastrar las vistas que interactuar con el usuario, tales como un botón.

  5. 1
    -(void)funcAddGesture
    { 
    //DRAG BUTTON
    UIPanGestureRecognizer *panGestureRecognizer;
    panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(dragButton:)];
    panGestureRecognizer.cancelsTouchesInView = YES;
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(50, 100, 60, 60);
    [button addTarget:self action:@selector(buttontapEvent) forControlEvents:UIControlEventPrimaryActionTriggered];
    [button setImage:[UIImage imageNamed:@"button_normal.png"] forState:UIControlStateNormal];
    [button addGestureRecognizer:panGestureRecognizer];
    [self.view addSubview:button];
    }
    - (void)dragButton:(UIPanGestureRecognizer *)recognizer {
    UIButton *button = (UIButton *)recognizer.view;
    CGPoint translation = [recognizer translationInView:button];
    float xPosition = button.center.x;
    float yPosition = button.center.y;
    float buttonCenter = button.frame.size.height/2;
    if (xPosition < buttonCenter)
    xPosition = buttonCenter;
    else if (xPosition > self.view.frame.size.width - buttonCenter)
    xPosition = self.view.frame.size.width - buttonCenter;
    if (yPosition < buttonCenter)
    yPosition = buttonCenter;
    else if (yPosition > self.view.frame.size.height - buttonCenter)
    yPosition = self.view.frame.size.height - buttonCenter;
    button.center = CGPointMake(xPosition + translation.x, yPosition + translation.y);
    [recognizer setTranslation:CGPointZero inView:button];
    }
    - (void)buttontapEvent {
    NSLog(@"buttontapEvent");
    }
  6. 1

    ohho la respuesta funcionado bien para mí. En caso de que necesite el swift 2.x versión:

    override func viewDidLoad() {
    let myButton = UIButton(type: .Custom)
    myButton.setImage(UIImage(named: "vehicle"), forState: .Normal)
    //drag support
    myButton.addTarget(self, action:#selector(imageMoved(_:event:)), forControlEvents:.TouchDragInside)
    myButton.addTarget(self, action:#selector(imageMoved(_:event:)), forControlEvents:.TouchDragOutside)
    }
    private func imageMoved(sender: AnyObject, event: UIEvent) {
    guard let control = sender as? UIControl else { return }
    guard let touches = event.allTouches() else { return }
    guard let touch = touches.first else { return }
    let prev = touch.previousLocationInView(control)
    let p = touch.locationInView(control)
    var center = control.center
    center.x += p.x - prev.x
    center.y += p.y - prev.y
    control.center = center
    }
  7. 0

    Para Swift 4 Fácil y sencilla. 😛

    Paso 1:
    Conecte El Botón De Storyboard A La Vista Del Controlador. Y Establecer La base Autodiseño Restricciones

     @IBOutlet weak var cameraButton: UIButton!

    Paso 2:
    Añadir Pan Gesto para tu botón En viewDidLoad()

    self.cameraButton.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.panGestureHandler(panGesture:))))

    Paso 3:

    Agregar panGestureHandler

    @objc func panGestureHandler(panGesture recognizer: UIPanGestureRecognizer) {
    let location = recognizer.location(in: view)
    cameraButton.center = location
    }

    Y Ahora El Botón De Acción

    @IBAction func ButtonAction(_ sender: Any) {
    print("This is button Action")
    }

    Básicos de Arrastrar y Soltar en iOS

    Agregar Ver el Resultado ☝️

Dejar respuesta

Please enter your comment!
Please enter your name here