web-dev-qa-db-fra.com

iOS Detect touchez et retouchez une UIView

Je suis coincé avec un problème de déterminer comment détecter un UIView touché et UIView tapé. Lorsqu'il est touché, je veux que l'UIView change sa couleur d'arrière-plan. Quand il est touché, j'aimerais que l'UIView effectue certaines tâches. Je voudrais savoir comment je peux résoudre ce problème.

-(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");
}
34
user288231

Un Gesture Recognizer est probablement exagéré pour ce que vous voulez. Vous voulez probablement simplement utiliser une combinaison de -touchesBegan:withEvent: et -touchesEnded:withEvent:.

C'est imparfait, mais cela devrait vous donner une idée de ce que vous voulez faire.

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

Ce code doit aller dans une sous-classe personnalisée de UIView que vous créez. Ensuite, utilisez ce type d'affichage personnalisé au lieu de UIView et vous obtiendrez une manipulation tactile.

41
Holly

enter image description here

Cette méthode ne nécessite rien de sous-classement. Vous ajoutez simplement un UILongPressGestureRecognizer à la vue et définissez le minimumPressDuration à zéro. Ensuite, vous vérifiez l'état lorsque les événements gestuels sont appelés pour voir si l'événement tactile commence ou se termine.

Voici le code de projet entier pour l'exemple d'image ci-dessus.

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

Merci à cette réponse pour l'idée.

47
Suragch

Dans chaque sous-classe UIControl (UIButton, etc.), vous pouvez l'utiliser pour vous abonner à un ensemble spécifique d'UIControlEvent:

addTarget:action:forControlEvents

Vous devez ajouter une cible avec le sélecteur approprié pour UIControlEventTouchDown et un autre cible/sélecteur pour UIControlEventTouchUpInside.

référence UIControl

6
opedge

Merci à réponse de Holly J'ai construit une classe de commodité ButtonView.

Edit: Comme cela answer dit, UILongPressGestureRecognizer réagit assez rapidement, j'ai donc mis à jour ma classe.

Usage:

let btn = ButtonView()
btn.onNormal = { btn.backgroundColor = .clearColor() }
btn.onPressed = { btn.backgroundColor = .blueColor() }
btn.onReleased = yourAction // Function to be called

Classe:

/** 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")
    }
}
2
Ferran Maylinch

Tout d'abord, par votre sélecteur handleDismissDoubleTap:, Je suppose que vous recherchez une double pression pour rejeter. Pour ce faire, vous devez: dismissGestureRecognition.numberOfTapsRequired = 2;

Deuxièmement, si par toucher vers le bas vous entendez un type de geste prolongé (ou un "appui prolongé"), vous devez utiliser un UILongPressGestureRecognizer au lieu du UITapGestureRecognizer.

1
Bell App Lab