it-swarm.com.de

Wie füge ich einem UIView ein Touch-Ereignis hinzu?

Wie füge ich einem UIView ein Berührungsereignis hinzu?
Ich versuche:

UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, nextY)] autorelease];
[headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown];
// ERROR MESSAGE: UIView may not respond to '-addTarget:action:forControlEvents:'

Ich möchte keine Unterklasse erstellen und überschreiben

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
268
Manni

In iOS 3.2 und höher können Sie Gestenerkenner verwenden. So würden Sie beispielsweise ein Tap-Ereignis behandeln:

//The setup code (in viewDidLoad in your view controller)
UITapGestureRecognizer *singleFingerTap = 
  [[UITapGestureRecognizer alloc] initWithTarget:self 
                                          action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleFingerTap];

//The event handling method
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
  CGPoint location = [recognizer locationInView:[recognizer.view superview]];

  //Do stuff here...
}

Es gibt auch eine Reihe von eingebauten Gesten. In den Dokumenten finden Sie Informationen zur iOS-Ereignisbehandlung und zu UIGestureRecognizer. Ich habe auch eine Reihe von Beispielcode auf Github das könnte helfen.

565
Nathan Eror

Gestenerkenner

Es gibt eine Reihe von häufig verwendeten Berührungsereignissen (oder Gesten), über die Sie benachrichtigt werden können, wenn Sie Ihrer Ansicht ein Gestenerkennungsprogramm hinzufügen. Die folgenden Gestentypen werden standardmäßig unterstützt:

  • UITapGestureRecognizer Tippen Sie auf (berühren Sie den Bildschirm ein oder mehrmals kurz)
  • UILongPressGestureRecognizer Lange Berührung (Bildschirm lange berühren)
  • UIPanGestureRecognizer Pan (bewegen Sie Ihren Finger über den Bildschirm)
  • UISwipeGestureRecognizer Streichen (Finger schnell bewegen)
  • UIPinchGestureRecognizer Pinch (Bewegen von zwei Fingern zusammen oder auseinander - normalerweise zum Zoomen)
  • UIRotationGestureRecognizer Drehen (zwei Finger kreisförmig bewegen)

Darüber hinaus können Sie Ihre eigene benutzerdefinierte Gestenerkennung erstellen.

Hinzufügen einer Geste im Interface Builder

Ziehen Sie einen Gestenerkenner aus der Objektbibliothek auf Ihre Ansicht.

enter image description here

Steuern Sie das Ziehen von der Geste in der Dokumentgliederung auf den View Controller-Code, um ein Outlet und eine Aktion auszuführen.

enter image description here

Dies sollte standardmäßig festgelegt werden, aber stellen Sie auch sicher, dass Benutzeraktion aktiviert für Ihre Ansicht auf true festgelegt ist.

enter image description here

Programmgesteuertes Hinzufügen einer Geste

Um eine Geste programmgesteuert hinzuzufügen, erstellen Sie (1) eine Gestenerkennung, (2) fügen sie einer Ansicht hinzu und (3) erstellen eine Methode, die aufgerufen wird, wenn die Geste erkannt wird.

import UIKit
class ViewController: UIViewController {

    @IBOutlet weak var myView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // 1. create a gesture recognizer (tap gesture)
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))

        // 2. add the gesture recognizer to a view
        myView.addGestureRecognizer(tapGesture)
    }

    // 3. this method is called when a tap is recognized
    @objc func handleTap(sender: UITapGestureRecognizer) {
        print("tap")
    }
}

Notizen

  • Der Parameter sender ist optional. Wenn Sie keinen Verweis auf die Geste benötigen, können Sie ihn weglassen. Wenn Sie dies dennoch tun, entfernen Sie den (sender:) Nach dem Namen der Aktionsmethode.
  • Die Benennung der Methode handleTap war beliebig. Benennen Sie es mit action: #selector(someMethodName(sender:)).

Mehr Beispiele

Sie können die Gestenerkenner untersuchen, die ich diesen Ansichten hinzugefügt habe, um zu sehen, wie sie funktionieren.

enter image description here

Hier ist der Code für dieses Projekt:

import UIKit
class ViewController: UIViewController {

    @IBOutlet weak var tapView: UIView!
    @IBOutlet weak var doubleTapView: UIView!
    @IBOutlet weak var longPressView: UIView!
    @IBOutlet weak var panView: UIView!
    @IBOutlet weak var swipeView: UIView!
    @IBOutlet weak var pinchView: UIView!
    @IBOutlet weak var rotateView: UIView!
    @IBOutlet weak var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Tap
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        tapView.addGestureRecognizer(tapGesture)

        // Double Tap
        let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap))
        doubleTapGesture.numberOfTapsRequired = 2
        doubleTapView.addGestureRecognizer(doubleTapGesture)

        // Long Press
        let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(gesture:)))
        longPressView.addGestureRecognizer(longPressGesture)

        // Pan
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(gesture:)))
        panView.addGestureRecognizer(panGesture)

        // Swipe (right and left)
        let swipeRightGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(gesture:)))
        let swipeLeftGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(gesture:)))
        swipeRightGesture.direction = UISwipeGestureRecognizerDirection.right
        swipeLeftGesture.direction = UISwipeGestureRecognizerDirection.left
        swipeView.addGestureRecognizer(swipeRightGesture)
        swipeView.addGestureRecognizer(swipeLeftGesture)

        // Pinch
        let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(gesture:)))
        pinchView.addGestureRecognizer(pinchGesture)

        // Rotate
        let rotateGesture = UIRotationGestureRecognizer(target: self, action: #selector(handleRotate(gesture:)))
        rotateView.addGestureRecognizer(rotateGesture)

    }

    // Tap action
    @objc func handleTap() {
        label.text = "Tap recognized"

        // example task: change background color
        if tapView.backgroundColor == UIColor.blue {
            tapView.backgroundColor = UIColor.red
        } else {
            tapView.backgroundColor = UIColor.blue
        }

    }

    // Double tap action
    @objc func handleDoubleTap() {
        label.text = "Double tap recognized"

        // example task: change background color
        if doubleTapView.backgroundColor == UIColor.yellow {
            doubleTapView.backgroundColor = UIColor.green
        } else {
            doubleTapView.backgroundColor = UIColor.yellow
        }
    }

    // Long press action
    @objc func handleLongPress(gesture: UILongPressGestureRecognizer) {
        label.text = "Long press recognized"

        // example task: show an alert
        if gesture.state == UIGestureRecognizerState.began {
            let alert = UIAlertController(title: "Long Press", message: "Can I help you?", preferredStyle: UIAlertControllerStyle.alert)
            alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }

    // Pan action
    @objc func handlePan(gesture: UIPanGestureRecognizer) {
        label.text = "Pan recognized"

        // example task: drag view
        let location = gesture.location(in: view) // root view
        panView.center = location
    }

    // Swipe action
    @objc func handleSwipe(gesture: UISwipeGestureRecognizer) {
        label.text = "Swipe recognized"

        // example task: animate view off screen
        let originalLocation = swipeView.center
        if gesture.direction == UISwipeGestureRecognizerDirection.right {
            UIView.animate(withDuration: 0.5, animations: {
                self.swipeView.center.x += self.view.bounds.width
            }, completion: { (value: Bool) in
                self.swipeView.center = originalLocation
            })
        } else if gesture.direction == UISwipeGestureRecognizerDirection.left {
            UIView.animate(withDuration: 0.5, animations: {
                self.swipeView.center.x -= self.view.bounds.width
            }, completion: { (value: Bool) in
                self.swipeView.center = originalLocation
            })
        }
    }

    // Pinch action
    @objc func handlePinch(gesture: UIPinchGestureRecognizer) {
        label.text = "Pinch recognized"

        if gesture.state == UIGestureRecognizerState.changed {
            let transform = CGAffineTransform(scaleX: gesture.scale, y: gesture.scale)
            pinchView.transform = transform
        }
    }

    // Rotate action
    @objc func handleRotate(gesture: UIRotationGestureRecognizer) {
        label.text = "Rotate recognized"

        if gesture.state == UIGestureRecognizerState.changed {
            let transform = CGAffineTransform(rotationAngle: gesture.rotation)
            rotateView.transform = transform
        }
    }
}

Notizen

  • Sie können einer Ansicht mehrere Gestenerkenner hinzufügen. Der Einfachheit halber habe ich das jedoch nicht getan (mit Ausnahme der Wischgeste). Wenn Sie für Ihr Projekt benötigen, sollten Sie die Gestenerkennungsdokumentation lesen. Es ist ziemlich verständlich und hilfreich.
  • Bekannte Probleme mit meinen obigen Beispielen: (1) Die Schwenkansicht setzt ihren Rahmen beim nächsten Gestenereignis zurück. (2) Die Wischansicht kommt beim ersten Wischen aus der falschen Richtung. (Diese Fehler in meinen Beispielen sollten Ihr Verständnis der Funktionsweise von Gestenerkennungsprogrammen jedoch nicht beeinträchtigen.)
115
Suragch

Ich denke du kannst es einfach benutzen

UIControl *headerView = ...
[headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown];

ich meine, HeaderView erstreckt sich von UIControl.

50
LiCheng

Basierend auf der akzeptierten Antwort können Sie ein Makro definieren:

#define handle_tap(view, delegate, selector) do {\
    view.userInteractionEnabled = YES;\
    [view addGestureRecognizer: [[UITapGestureRecognizer alloc] initWithTarget:delegate action:selector]];\
} while(0)

Dieses Makro verwendet ARC, sodass kein release -Aufruf erfolgt.

Beispiel für die Verwendung von Makros:

handle_tap(userpic, self, @selector(onTapUserpic:));
18
rudyryk

Swift 3 & Swift 4

import UIKit

extension UIView {
  func addTapGesture(tapNumber: Int, target: Any, action: Selector) {
    let tap = UITapGestureRecognizer(target: target, action: action)
    tap.numberOfTapsRequired = tapNumber
    addGestureRecognizer(tap)
    isUserInteractionEnabled = true
  }
}

Verwenden Sie

yourView.addTapGesture(tapNumber: 1, target: self, action: #selector(yourMethod))
18

Sie können dies erreichen, indem Sie dem Code den Gestenerkenner hinzufügen.

Schritt 1: ViewController.m:

// Declare the Gesture.
UITapGestureRecognizer *gesRecognizer = [[UITapGestureRecognizer alloc] 
                                          initWithTarget:self 
                                          action:@selector(handleTap:)];
gesRecognizer.delegate = self;

// Add Gesture to your view.
[yourView addGestureRecognizer:gesRecognizer]; 

Schritt 2: ViewController.m:

// Declare the Gesture Recogniser handler method.
- (void)handleTap:(UITapGestureRecognizer *)gestureRecognizer{
   NSLog(@"Tapped");
}

HINWEIS: hier war yourView in meinem Fall @property (strong, nonatomic) IBOutlet UIView *localView;

BEARBEITEN: * localView ist das weiße Kästchen in Main.storyboard von unten

enter image description here

enter image description here

9
Annu

In Swift 4.2 und Xcode 10

Verwenden Sie ITapGestureRecognizer, um ein Berührungsereignis hinzuzufügen

//Add tap gesture to your view
let tap = UITapGestureRecognizer(target: self, action: #selector(handleGesture))
yourView.addGestureRecognizer(tap)

// GestureRecognizer
@objc func handleGesture(gesture: UITapGestureRecognizer) -> Void {
//Write your code here
}

Wenn Sie SharedClass verwenden möchten

//This is my shared class
import UIKit

class SharedClass: NSObject {

    static let sharedInstance = SharedClass()

    //Tap gesture function
    func addTapGesture(view: UIView, target: Any, action: Selector) {
        let tap = UITapGestureRecognizer(target: target, action: action)
        view.addGestureRecognizer(tap)
    }
} 

Ich habe 3 Ansichten in meinem ViewController namens view1, view2 und view3.

override func viewDidLoad() {
    super.viewDidLoad()
    //Add gestures to your views
    SharedClass.sharedInstance.addTapGesture(view: view1, target: self, action: #selector(handleGesture))
    SharedClass.sharedInstance.addTapGesture(view: view2, target: self, action: #selector(handleGesture))
    SharedClass.sharedInstance.addTapGesture(view: view3, target: self, action: #selector(handleGesture2))

}

// GestureRecognizer
@objc func handleGesture(gesture: UITapGestureRecognizer) -> Void {
    print("printed 1&2...")
}
// GestureRecognizer
@objc func handleGesture2(gesture: UITapGestureRecognizer) -> Void {
    print("printed3...")
}
6
iOS

Swift 3:

let tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGestureRecognizer(_:)))
view.addGestureRecognizer(tapGestureRecognizer)

func handleTapGestureRecognizer(_ gestureRecognizer: UITapGestureRecognizer) {

}
5
Giang

Hier ist eine Swift Version:

// MARK: Gesture Extensions
extension UIView {

    func addTapGesture(#tapNumber: Int, target: AnyObject, action: Selector) {
        let tap = UITapGestureRecognizer (target: target, action: action)
        tap.numberOfTapsRequired = tapNumber
        addGestureRecognizer(tap)
        userInteractionEnabled = true
    }

    func addTapGesture(#tapNumber: Int, action: ((UITapGestureRecognizer)->())?) {
        let tap = BlockTap (tapCount: tapNumber, fingerCount: 1, action: action)
        addGestureRecognizer(tap)
        userInteractionEnabled = true
    }
}
5
Esqarrouth

Hier ist ios tapgesture; Zuerst müssen Sie eine Aktion für GestureRecognizer erstellen, nachdem Sie den folgenden Code unter die unten gezeigte Aktion geschrieben haben

- (IBAction)tapgesture:(id)sender

{


[_password resignFirstResponder];


[_username resignFirstResponder];

NSLog(@" TapGestureRecognizer  tapped");

}
0
sathish

Eine andere Möglichkeit besteht darin, der Ansicht eine transparente Schaltfläche hinzuzufügen

UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
b.frame = CGRectMake(0, 0, headerView.width, headerView.height);
[headerView addSubview:b];
[b addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchDown];

Und dann mit Klick umgehen:

- (void)buttonClicked:(id)sender
{}
0
thanhbinh84

Erstellen Sie eine Gestenerkennung (Unterklasse), die Berührungsereignisse wie touchesBegan implementiert. Anschließend können Sie es der Ansicht hinzufügen.

Auf diese Weise verwenden Sie Komposition statt Unterklassen (was die Anforderung war).

0
Geri

Warum versucht ihr nicht SSEventListener ?

Sie müssen keine Gestenerkennung erstellen und Ihre Logik von einer anderen Methode trennen. SSEventListener unterstützt das Festlegen von Listener-Blöcken in einer Ansicht, um nach einer Geste mit einem Fingertipp, einer Geste mit doppeltem Fingertipp und einer Geste mit N-Fingertipp zu suchen. So stellen Sie einen einzelnen Tippen-Gesten-Listener ein:

[view ss_addTapViewEventListener:^(UITapGestureRecognizer *recognizer) { ... } numberOfTapsRequired:1];

0
Shengsheng