¿Alguien puede ayudar a solucionar un noob? Publiqué este problema en varios foros y no recibí ninguna respuesta, mientras que muchas búsquedas de otras respuestas han aparecido en stackOverflow, así que espero que este sea el lugar.UIScrollView toca frente a la subvista toca
Tengo un BeachView.h (subclase de UIScrollView, imagen de una playa de arena) cubierto con un número aleatorio de Stone.h (subclase de UIImageView, un PNG aleatorio de una piedra, userInteractionEnabled = YES para aceptar toques)
Si el usuario toca y se mueve en la playa, debería desplazarse. Si el usuario toca una piedra, debe llamar al método "piedra tocada". Si el usuario toca la playa donde no hay piedra, debe llamar al método "Tocó Playa".
Ahora, me doy cuenta de que esto suena muy simple. Todo el mundo y todo me dice que si hay algo en un UIScrollView que acepta toques debe pasarle el control. Así que cuando toco y arrastro, debería desplazarse; pero si toco, y está en una piedra, debería ignorar los grifos de la playa y aceptar grifos de piedra, ¿sí?
Sin embargo, parece que ambas vistas están aceptando el toque y llamando tanto a touchStone como a TouchBeach. Además, el toque de la playa se produce primero, por lo que ni siquiera puedo poner un indicador de tipo "if touchedStone then not run touchedBeach".
Aquí hay algunos códigos. En BeachView.m
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.decelerating) { didScroll = YES; }
else { didScroll = NO; }
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:touch.view];
NSLog(@"touched beach = %@", [touch view]);
lastTouch = touchLocation;
[super touchesBegan:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
didScroll = YES;
[super touchesMoved:touches withEvent:event];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if (didScroll == NO && isPaused == NO) {
[self touchedBeach:YES location:lastTouch];
}
[super touchesEnded:touches withEvent:event];
}
En Stone.m
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[parent stoneWasTouched]; // parent = ivar pointing from stone to beachview
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:touch.view];
NSLog(@"touched stone = %@", [touch view]);
[parent touchedStone:YES location:touchLocation];
}
Después de un grifo de piedra, Mi NSLog se parece a esto:
Touched beach = <BeachView: 0x1276a0>
ran touchedBeach
Touched Stone = <Stone: 0x1480c0>
ran touchedStone
Por lo que es realmente ejecuta ambos. Lo que es aún más extraño es que si tomo los toques BeGo y Toques Salidos de Stone.m pero dejo userInteractionEnabled = YES, el beachView registra ambos toques, pero devuelve la Piedra como la vista que tocó (la segunda vez).
Touched beach = <BeachView: 0x1276a0>
ran touchedBeach
Touched beach = <Stone: 0x1480c0>
ran touchedBeach
Así que POR FAVOR, he estado tratando de ordenar esto por días. ¿Cómo lo hago para que una piedra golpeada solo llame a Piedra y una playa golpeada solo llame a Playa? ¿Dónde estoy equivocado?
me mudé [muy] para el inicio de los métodos y que hizo una diferencia. Todavía registra dos toques, pero al menos ahora dice 1-startedBeach 2-startedStone 3-endedBeach 4-endedStone, por lo que hay tiempo para hacer estallar una bandera allí. Estaba mirando HitTest pero cuando comenzó a hablar de CAlayers vs UIviews me pareció un libro que simplemente no estaba listo para abrir. Le daré otra oportunidad. Gracias Hatfinch, -k. –