UIImageView üzerinde UIGestureRecognizer


179

Sahibim UIImageView döndürme vb boyutlandırmak ve ben isterler, hangi

A UIGestureRecognizereklenebilir UIImageViewmi?

Çalışma UIImageViewzamanında oluşturulacak bir döndürme ve çimdik tanıyıcı eklemek istiyorum .

Bu tanıyıcılar nasıl eklenir?

Yanıtlar:


426

Emin olun userInteractionEnabledolduğu YESüzerine UIImageView. Ardından bir hareket tanıyıcı ekleyebilirsiniz.

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...
}

5
Hayır, bu sadece hareket tanıyıcıların nasıl ekleneceğini gösterir. Gerçek yakınlaştırmayı yapmanız / hareket işleyicilerinde kendinizi döndürmeniz gerekir. Yakınlaştırma / döndürme işlemiyle ilgili Touches_GestureRecognizers örnek uygulamasına bakın .

77
+1, hareketlerimin neden işe yaramayacağını anlamaya çalışan yaşlar için burada oturdu. "UIImageView'da userInteractionEnabled öğesinin EVET olup olmadığını kontrol edin." Teşekkürler!
Yaratık

1
Bu, işimi kesinlikle, genel görünüme ayarlanmış bir tanıyıcı üzerinde sınırlar belirlemeye çalışmaktan daha kolay hale getirdi. Teşekkürler!
Josh Kovach

6
imageView.userInteractionEnabled = EVET; bu anahtar! Teşekkür ederim.
HamasN

3
userInteractionEnabledXcode 8 Objective-C / Swift'te hala YES / true olarak ayarlanmalıdır
leanne

76

Evet, UIImageView öğesine bir UIGestureRecognizer eklenebilir. Diğer cevapta belirtildiği gibi, userInteractionEnabledözelliğini görüntü ayarında kullanıcı etkileşimini etkinleştirmeyi hatırlamak çok önemlidir YES. UIImageView, kullanıcı etkileşimi özelliği YESvarsayılan olarak ayarlanan UIView'den devralır , ancak UIImageView'ın kullanıcı etkileşimi özelliği NOvarsayılan olarak ayarlanır .

Gönderen UIImageView docs:

Yeni görüntü görüntüleme nesneleri, kullanıcı olaylarını varsayılan olarak dikkate almayacak şekilde yapılandırılmıştır. Özel bir UIImageView alt sınıfındaki olayları işlemek istiyorsanız, nesneyi başlattıktan sonra userInteractionEnabled özelliğinin değerini açıkça YES olarak değiştirmeniz gerekir.

Her neyse, cevabın büyük bir kısmında. UIImageViewA UIPinchGestureRecognizer, a UIRotationGestureRecognizerve a ile a'nın nasıl oluşturulacağına dair bir örnekUIPanGestureRecognizer .

İlk olarak, viewDidLoadseçtiğiniz veya başka bir yöntemle, bir görüntü görünümü oluşturun, ona bir görüntü, bir çerçeve verin ve kullanıcı etkileşimini etkinleştirin. Ardından üç hareketi aşağıdaki gibi oluşturun. Temsilci özelliklerini kullandığınızdan emin olun (büyük olasılıkla kendi kendine ayarlanmıştır). Aynı anda birden fazla hareket kullanmak için bu gerekli olacaktır.

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

İşte görünümünüzdeki hareketler algılandığında çağrılacak üç yöntem. Onların içinde, hareketin mevcut durumunu kontrol edeceğiz ve başlamış veya değiştirilmişse UIGestureRecognizerState, hareketin ölçek / döndürme / çeviri özelliğini okuyacağız, bu verileri bir yakın çekim dönüşümüne uygulayacağız, yakın çekim dönüşümünü görüntüye uygulayacağız görüntüleyin ve ardından hareket ölçeğini / döndürme / çevirmeyi sıfırlayın.

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

Son olarak ve en önemlisi, hareketlerin aynı anda çalışmasına izin vermek için UIGestureRecognizerDelegate yöntemini kullanmanız gerekir gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer. Bu üç hareket, bu sınıfa delege olarak atanmış yalnızca üç hareketse, YESaşağıda gösterildiği gibi geri dönebilirsiniz . Ancak, bu sınıfın temsilcisi olarak atanmış ek hareketleriniz varsa, bunların birlikte çalışmasına izin vermeden önce hangi hareketin hangisi olduğunu belirlemek için bu yönteme mantık eklemeniz gerekebilir.

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

Sınıfınızın UIGestureRecognizerDelegate protokolüne uygun olduğundan emin olun . Bunu yapmak için arayüzünüzün şuna benzer olduğundan emin olun:

@interface MyClass : MySuperClass <UIGestureRecognizerDelegate>

Kod ile çalışan bir örnek projede kendiniz oynamayı tercih ediyorsanız, bu kodu içeren oluşturduğum örnek projeyi burada bulabilirsiniz.


1
Bu bugüne kadar stackoverflow.com'da gördüğüm en iyi cevap, tam ayrıntılı, iyi yorumlanmış ve hatta git kaynak kodunu içeriyor. Bunun için teşekkürler
Alejandro Luengo

1
Açık, adım adım, harika açıklama
Alvin

1
Teşekkür ederim, bir veya iki sayfada Apple ve diğerlerinin yıllar boyunca birkaç düzine öğreticinin yapamadığı şeyleri yaptı. İOS'ta mümkün olan başka birçok şey olması gerektiğini hissediyorum, ancak şaşkınlık ve yanlış anlama nedeniyle bize kayboldular.
Zack Morris

Harika cevap, en iyisi. Sabrınız için çok teşekkürler.
Jorg B Jorge

13

Hızlı 4.2

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

ve dokunulduğunda:

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

11

Swift 2.0 Çözümü

Aynı malikanede bir dokunma, sıkıştırma veya kaydırma hareketi tanıyıcı oluşturursunuz. Aşağıda, tanıyıcıyı çalıştırmak ve çalıştırmak için 4 adımda size yol göstereceğim.

4 Adım

1.)UIGestureRecognizerDelegate Sınıf imzanıza ekleyerek devralın .

class ViewController: UIViewController, UIGestureRecognizerDelegate {...}

2.) IBOutlet oluşturmak için görüntünüzden viewController'a sürüklemeyi kontrol edin:

@IBOutlet weak var tapView: UIImageView!

3.) viewDidLoad öğenize aşağıdaki kodu ekleyin:

// 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.) Hareket algılayıcınıza dokunulduğunda çağrılacak işlevi oluşturun. (İsterseniz hariç tutabilirsiniz = nil).

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

Son kodunuz şöyle görünmelidir:

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


6

Bunu swift4 ile tek bir görünümde 3 hareket ekleyerek yaptım

  1. UIPinchGestureRecognizer : Görünümü yakınlaştırın ve uzaklaştırın.
  2. UIRotationGestureRecognizer : Görünümü döndürün.
  3. UIPanGestureRecognizer : Görünümü sürükleyin.

İşte örnek kodum

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
     }

}

Herhangi bir soru, sadece yorum yazın. teşekkür ederim


3

SWIFT 3 Örneği

override func viewDidLoad() {

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

    self.backgroundImageView.isUserInteractionEnabled = true
}

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

Gerektiğinde jest tanıma delegeleri veya diğer uygulamalar yok.


2

Ayrıca, hafifçe dokunma hareketi tanıyıcısını içindeki görüntü görünümüne sürükleyebilirsiniz Storyboard. Ardından ctrl + drag, koda göre bir eylem oluşturun .


1

Blok sevgilisi için, bloktaki hareketlerin hareketini eklemek için ALActionBlocks'u kullanabilirsiniz

__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];
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.