recognizer - Detección de iOS toque abajo y retoque de un UIView
uipangesturerecognizer swift 4 (5)
Estoy atascado con el problema de determinar cómo detectar un UIView que está siendo tocado y UIView que se está tocando. Cuando se toca, quiero que UIView cambie su color de fondo. Cuando se toca, me gustaría que UIView realice ciertas tareas. Me gustaría saber cómo puedo solucionar este problema.
-(void)viewDidLoad
{
UITapGestureRecognizer *dismissGestureRecognition = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDismissDoubleTap:)];
dismissGestureRecognition.numberOfTapsRequired = 1;
[sectionDismissDoubleView addGestureRecognizer:dismissGestureRecognition];
UITapGestureRecognizer *dismissGestureDownRecognition = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissGestureDownRecognition:)];
dismissGestureRecognition.numberOfTouchesRequired = 1;
[sectionDismissDoubleView addGestureRecognizer:dismissGestureDownRecognition];
}
- (void)handleDismissDoubleTap:(UIGestureRecognizer*)tap {
SettingsDismissDoubleViewController *settingsDouble = [[SettingsDismissDoubleViewController alloc] initWithNibName:@"SettingsDismissDoubleViewController" bundle:nil];
[self.navigationController pushViewController:settingsDouble animated:YES];
}
- (void)dismissGestureDownRecognition:(UIGestureRecognizer*)tap {
NSLog(@"Down");
}
En cada subclase de UIControl (UIButton, etc.) puede usar esto para suscribirse a un conjunto específico de UIControlEvent:
addTarget:action:forControlEvents
Debe agregar el destino con el selector apropiado para UIControlEventTouchDown y otro destino / selector para el evento UIControlEventTouchUpInside.
En primer lugar, por su selector handleDismissDoubleTap:
asumo que está buscando un doble toque para descartar. Para lograr esto, debes hacer: dismissGestureRecognition.numberOfTapsRequired = 2;
En segundo lugar, si con un toque se UILongPressGestureRecognizer
un tipo de gesto de toque prolongado (o toque y mantenga presionado), debe usar un UILongPressGestureRecognizer
lugar del UITapGestureRecognizer
.
Gracias a la respuesta de Holly, construí una clase de conveniencia ButtonView
.
Edit: Como dice esta answer , UILongPressGestureRecognizer
reacciona bastante más rápido, así que actualicé mi clase.
Uso:
let btn = ButtonView()
btn.onNormal = { btn.backgroundColor = .clearColor() }
btn.onPressed = { btn.backgroundColor = .blueColor() }
btn.onReleased = yourAction // Function to be called
Clase:
/** View that can be pressed like a button */
import UIKit
class ButtonView : UIView {
/* Called when the view goes to normal state (set desired appearance) */
var onNormal = {}
/* Called when the view goes to pressed state (set desired appearance) */
var onPressed = {}
/* Called when the view is released (perform desired action) */
var onReleased = {}
override init(frame: CGRect)
{
super.init(frame: frame)
let recognizer = UILongPressGestureRecognizer(target: self, action: Selector("touched:"))
recognizer.delegate = self
recognizer.minimumPressDuration = 0.0
addGestureRecognizer(recognizer)
userInteractionEnabled = true
onNormal()
}
func touched(sender: UILongPressGestureRecognizer)
{
if sender.state == .Began {
onPressed(self)
} else if sender.state == .Ended {
onNormal(self)
onReleased()
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Un gestor de reconocimiento es probablemente una exageración por lo que quieres. Probablemente solo quieras usar una combinación de -touchesBegan:withEvent:
y -touchesEnded:withEvent:
Esto es defectuoso, pero debería darle una idea de lo que quiere hacer.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.touchDown = YES;
self.backgroundColor = [UIColor redColor];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// Triggered when touch is released
if (self.isTouchDown) {
self.backgroundColor = [UIColor whiteColor];
self.touchDown = NO;
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
// Triggered if touch leaves view
if (self.isTouchDown) {
self.backgroundColor = [UIColor whiteColor];
self.touchDown = NO;
}
}
Este código debe ir en una subclase personalizada de UIView
que cree. Luego use este tipo de vista personalizada en lugar de UIView
y obtendrá un manejo táctil.
Este método no requiere subclasificar nada. Simplemente agregue un UILongPressGestureRecognizer
a la vista y establezca la minimumPressDuration
en cero. Luego verifica el estado cuando se llaman los eventos de gestos para ver si el evento táctil está comenzando o finalizando.
Aquí está el código completo del proyecto para la imagen de ejemplo anterior.
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var myView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Add "long" press gesture recognizer
let tap = UILongPressGestureRecognizer(target: self, action: #selector(tapHandler))
tap.minimumPressDuration = 0
myView.addGestureRecognizer(tap)
}
// called by gesture recognizer
func tapHandler(gesture: UITapGestureRecognizer) {
// handle touch down and touch up events separately
if gesture.state == .Began {
myView.backgroundColor = UIColor.darkGrayColor()
} else if gesture.state == .Ended {
myView.backgroundColor = UIColor.lightGrayColor()
}
}
}
Gracias a esta respuesta por la idea.