wake-up-neo.com

UIGestureRecognizer unter UIImageView

Ich habe eine UIImageView, die ich in der Lage sein möchte, die Größe zu ändern und zu drehen usw.

Kann eine UIGestureRecognizer zur UIImageView hinzugefügt werden?

Ich möchte ein Rotations- und Quetscherkennungsprogramm zu einer UIImageView hinzufügen, die zur Laufzeit erstellt wird.

Wie fügt man diese Erkenner hinzu?

171
jarryd

Stellen Sie sicher, dass userInteractionEnabledYES für die UIImageView ist. Dann können Sie eine Gestenerkennung hinzufügen.

imageView.userInteractionEnabled = YES;
UIPinchGestureRecognizer *pgr = [[UIPinchGestureRecognizer alloc] 
    initWithTarget:self action:@selector(handlePinch:)];
pgr.delegate = self;
[imageView addGestureRecognizer:pgr];
[pgr release];
:
:
- (void)handlePinch:(UIPinchGestureRecognizer *)pinchGestureRecognizer
{
  //handle pinch...
}
410
user467105

Ja, ein UIGestureRecognizer kann zu einem UIImageView hinzugefügt werden. Wie in der anderen Antwort erwähnt, ist es sehr wichtig, dass Sie die Benutzerinteraktion in der Bildansicht aktivieren, indem Sie die userInteractionEnabled-Eigenschaft auf YES setzen. UIImageView erbt von UIView, dessen Benutzerinteraktionseigenschaft standardmäßig auf YES festgelegt ist. Die Benutzerinteraktionseigenschaft von UIImageView ist jedoch standardmäßig auf NO festgelegt.

Aus den UIImageView-Dokumenten:

Neue Bildansichtsobjekte sind so konfiguriert, dass Benutzerereignisse von .__ ignoriert werden. Standard. Wenn Sie Ereignisse in einer benutzerdefinierten Unterklasse von .__ behandeln möchten. UIImageView, Sie müssen den Wert von .__ explizit ändern. userInteractionEnabled-Eigenschaft auf YES nach dem Initialisieren des Objekts.

Jedenfalls auf die Masse der Antwort. Hier ein Beispiel, wie Sie ein UIImageView mit einem UIPinchGestureRecognizer, einem UIRotationGestureRecognizer und einem UIPanGestureRecognizer erstellen.

Erstellen Sie zunächst in viewDidLoad oder einer anderen Methode Ihrer Wahl eine Bildansicht, geben Sie ihr ein Bild, einen Rahmen und aktivieren Sie die Benutzerinteraktion. Dann erstellen Sie die drei Gesten wie folgt. Stellen Sie sicher, dass Sie ihre Delegateigenschaft verwenden (höchstwahrscheinlich auf "selbst" gesetzt). Dies ist erforderlich, um mehrere Gesten gleichzeitig zu verwenden.

- (void)viewDidLoad
{
    [super viewDidLoad];

    // set up the image view
    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"someImage"]];
    [imageView setBounds:CGRectMake(0.0, 0.0, 120.0, 120.0)];
    [imageView setCenter:self.view.center];
    [imageView setUserInteractionEnabled:YES]; // <--- This is very important

    // create and configure the pinch gesture
    UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGestureDetected:)];
    [pinchGestureRecognizer setDelegate:self];
    [imageView addGestureRecognizer:pinchGestureRecognizer];

    // create and configure the rotation gesture
    UIRotationGestureRecognizer *rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationGestureDetected:)];
    [rotationGestureRecognizer setDelegate:self];
    [imageView addGestureRecognizer:rotationGestureRecognizer];

    // creat and configure the pan gesture
    UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureDetected:)];
    [panGestureRecognizer setDelegate:self];
    [imageView addGestureRecognizer:panGestureRecognizer];


    [self.view addSubview:imageView]; // add the image view as a subview of the view controllers view
}

Hier sind die drei Methoden, die aufgerufen werden, wenn die Gesten in Ihrer Ansicht erkannt werden. In ihnen werden wir den aktuellen Status der Geste überprüfen, und wenn es sich entweder in der Anfangs- oder der Änderungsvariable UIGestureRecognizerState befindet, lesen wir die Skalen-/Rotations-/Translationseigenschaft der Geste, wenden diese Daten auf eine affine Transformation an und wenden die affine Transformation auf die Bildansicht, und setzen Sie die Gesten wieder zurück. 

- (void)pinchGestureDetected:(UIPinchGestureRecognizer *)recognizer
{
    UIGestureRecognizerState state = [recognizer state];

    if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
    {
        CGFloat scale = [recognizer scale];
        [recognizer.view setTransform:CGAffineTransformScale(recognizer.view.transform, scale, scale)];
        [recognizer setScale:1.0];
    }
}

- (void)rotationGestureDetected:(UIRotationGestureRecognizer *)recognizer
{
    UIGestureRecognizerState state = [recognizer state];

    if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
    {
        CGFloat rotation = [recognizer rotation];
        [recognizer.view setTransform:CGAffineTransformRotate(recognizer.view.transform, rotation)];
        [recognizer setRotation:0];
    }
}

- (void)panGestureDetected:(UIPanGestureRecognizer *)recognizer
{
    UIGestureRecognizerState state = [recognizer state];

    if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
    {
        CGPoint translation = [recognizer translationInView:recognizer.view];
        [recognizer.view setTransform:CGAffineTransformTranslate(recognizer.view.transform, translation.x, translation.y)];
        [recognizer setTranslation:CGPointZero inView:recognizer.view];
    }
}

Schließlich und ganz wichtig ist, dass Sie die UIGestureRecognizerDelegate - Methode gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer verwenden müssen, damit die Gesten gleichzeitig funktionieren können. Wenn diese drei Gesten die einzigen drei Gesten sind, denen diese Klasse als Delegat zugewiesen ist, können Sie YES wie nachstehend gezeigt zurückgeben. Wenn Sie jedoch über zusätzliche Gesten verfügen, denen diese Klasse als Delegat zugewiesen ist, müssen Sie möglicherweise dieser Methode Logik hinzufügen, um zu ermitteln, welche Geste welche ist, bevor sie alle zusammenarbeiten können.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

Vergewissern Sie sich, dass Ihre Klasse dem Protokoll UIGestureRecognizerDelegate entspricht. Stellen Sie dazu sicher, dass Ihre Benutzeroberfläche ungefähr so ​​aussieht:

@interface MyClass : MySuperClass <UIGestureRecognizerDelegate>

Wenn Sie lieber selbst mit dem Code in einem funktionierenden Beispielprojekt spielen möchten, finden Sie das von mir erstellte Beispielprojekt mit diesem Code hier.

73
Mick MacCallum

Swift 2.0-Lösung

Sie erstellen eine Tipp-, Prise- oder Swipe-Gestenerkennung im selben Herrenhaus. Im Folgenden werde ich Sie durch 4 Schritte führen, um Ihren Erkenner zum Laufen zu bringen.

4 Schritte

1.) Vererben von UIGestureRecognizerDelegate durch Hinzufügen zu Ihrer Klassensignatur.

class ViewController: UIViewController, UIGestureRecognizerDelegate {...}

2.) Steuern Sie die Ziehbewegung von Ihrem Bild auf Ihren viewController, um ein IBOutlet zu erstellen:

@IBOutlet weak var tapView: UIImageView!

3.) Fügen Sie in Ihrer viewDidLoad den folgenden Code hinzu:

// create an instance of UITapGestureRecognizer and tell it to run 
// an action we'll call "handleTap:"
let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
// we use our delegate
tap.delegate = self
// allow for user interaction
tapView.userInteractionEnabled = true
// add tap as a gestureRecognizer to tapView
tapView.addGestureRecognizer(tap)

4.) Erstellen Sie die Funktion, die aufgerufen wird, wenn Ihre Gestenerkennung aktiviert wird. (Sie können den = nil ausschließen, wenn Sie möchten.).

func handleTap(sender: UITapGestureRecognizer? = nil) {
    // just creating an alert to prove our tap worked!
    let tapAlert = UIAlertController(title: "hmmm...", message: "this actually worked?", preferredStyle: UIAlertControllerStyle.Alert)
    tapAlert.addAction(UIAlertAction(title: "OK", style: .Destructive, handler: nil))
    self.presentViewController(tapAlert, animated: true, completion: nil)
}

Ihr endgültiger Code sollte ungefähr so ​​aussehen:

class ViewController: UIViewController, UIGestureRecognizerDelegate {

    @IBOutlet weak var tapView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
        tap.delegate = self
        tapView.userInteractionEnabled = true
        tapView.addGestureRecognizer(tap)
    }

    func handleTap(sender: UITapGestureRecognizer? = nil) {
        let tapAlert = UIAlertController(title: "hmmm...", message: "this actually worked?", preferredStyle: UIAlertControllerStyle.Alert)
        tapAlert.addAction(UIAlertAction(title: "OK", style: .Destructive, handler: nil))
        self.presentViewController(tapAlert, animated: true, completion: nil)
    }
}
11
Dan Beaulieu

Schnell 4.2

myImageView.isUserInteractionEnabled = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped))
tapGestureRecognizer.numberOfTapsRequired = 1
myImageView.addGestureRecognizer(tapGestureRecognizer)

und wenn abgegriffen:

@objc func imageTapped(_ sender: UITapGestureRecognizer) {
   // do something when image tapped
   print("image tapped")
}
10
ayalcinkaya

Swift 3 Beispiel

override func viewDidLoad() {

         self.backgroundImageView.addGestureRecognizer(
             UITapGestureRecognizer.init(target: self, action:
                 #selector(didTapImageview(_:))
             )
         )
         self.backgroundImageView.isUserInteractionEnabled = true
     }

     func didTapImageview(_ sender: Any) {
          // do something
     }
}

Gegebenenfalls keine Delegierten für Gestenempfänger oder andere Implementierungen.

3
mourodrigo

Ich habe das gerade mit Swift4 gemacht, indem ich drei Gesten in einer einzigen Ansicht zusammengefügt habe 

  1. UIPinchGestureRecognizer : Ansicht vergrößern und verkleinern. 
  2. UIRotationGestureRecognizer : Ansicht drehen.
  3. UIPanGestureRecognizer : Ziehen der Ansicht.

Hier mein Beispielcode

class ViewController: UIViewController: UIGestureRecognizerDelegate{
      //your image view that outlet from storyboard or xibs file.
     @IBOutlet weak var imgView: UIImageView!
     // declare gesture recognizer
     var panRecognizer: UIPanGestureRecognizer?
     var pinchRecognizer: UIPinchGestureRecognizer?
     var rotateRecognizer: UIRotationGestureRecognizer?

     override func viewDidLoad() {
          super.viewDidLoad()
          // Create gesture with target self(viewcontroller) and handler function.  
          self.panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.handlePan(recognizer:)))
          self.pinchRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(self.handlePinch(recognizer:)))
          self.rotateRecognizer = UIRotationGestureRecognizer(target: self, action: #selector(self.handleRotate(recognizer:)))
          //delegate gesture with UIGestureRecognizerDelegate
          pinchRecognizer?.delegate = self
          rotateRecognizer?.delegate = self
          panRecognizer?.delegate = self
          // than add gesture to imgView
          self.imgView.addGestureRecognizer(panRecognizer!)
          self.imgView.addGestureRecognizer(pinchRecognizer!)
          self.imgView.addGestureRecognizer(rotateRecognizer!)
     }

     // handle UIPanGestureRecognizer 
     @objc func handlePan(recognizer: UIPanGestureRecognizer) {    
          let gview = recognizer.view
          if recognizer.state == .began || recognizer.state == .changed {
               let translation = recognizer.translation(in: gview?.superview)
               gview?.center = CGPoint(x: (gview?.center.x)! + translation.x, y: (gview?.center.y)! + translation.y)
               recognizer.setTranslation(CGPoint.zero, in: gview?.superview)
          }
     }

     // handle UIPinchGestureRecognizer 
     @objc func handlePinch(recognizer: UIPinchGestureRecognizer) {
          if recognizer.state == .began || recognizer.state == .changed {
               recognizer.view?.transform = (recognizer.view?.transform.scaledBy(x: recognizer.scale, y: recognizer.scale))!
               recognizer.scale = 1.0
         }
     }   

     // handle UIRotationGestureRecognizer 
     @objc func handleRotate(recognizer: UIRotationGestureRecognizer) {
          if recognizer.state == .began || recognizer.state == .changed {
               recognizer.view?.transform = (recognizer.view?.transform.rotated(by: recognizer.rotation))!
               recognizer.rotation = 0.0
           }
     }

     // mark sure you override this function to make gestures work together 
     func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
         return true
     }

}

Jede Frage, geben Sie einfach einen Kommentar ein. Danke dir

3
Leang Socheat

Sie können auch einen Tap-Gestenerkenner in die Bildansicht im Storyboard ziehen. Dann erstellen Sie eine Aktion per Strg + Ziehen in den Code ...

2
goggelj

Für Blockliebhaber können Sie ALActionBlocks verwenden, um Gestenbewegungen im Block hinzuzufügen

__weak ALViewController *wSelf = self;
imageView.userInteractionEnabled = YES;
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithBlock:^(UITapGestureRecognizer *weakGR) {
    NSLog(@"pan %@", NSStringFromCGPoint([weakGR locationInView:wSelf.view]));
}];
[self.imageView addGestureRecognizer:gr];
0
dimo hamdy