UIGestureRecognizer di UIImageView

179

Saya punya UIImageView, yang saya inginkan untuk dapat mengubah ukuran dan memutar dll.

Bisakah UIGestureRecognizerditambahkan ke UIImageView?

Saya ingin menambahkan rotate dan pinch recognition ke UIImageViewyang akan dibuat saat runtime.

Bagaimana cara menambahkan pengenal ini?

sistem
sumber

Jawaban:

426

Periksa yang userInteractionEnabledada YESdi UIImageView. Kemudian Anda bisa menambahkan pengenal isyarat.

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...
}
Abubakr Dar
sumber
5
Tidak, ini hanya menunjukkan cara menambahkan pengenal isyarat. Anda harus melakukan zoom aktual / memutar diri di penangan isyarat. Lihat contoh aplikasi Touches_GestureRecognizers tentang cara melakukan zoom / rotate.
77
+1 duduk di sini selama berabad-abad mencoba mencari tahu mengapa gerakan saya tidak berfungsi .. "Periksa bahwa userInteractionEnabled adalah YA di UIImageView." Terima kasih!
Critter
1
Ini jelas membuat pekerjaan saya lebih mudah daripada mencoba menetapkan batasan pada set pengenal untuk tampilan keseluruhan. Terima kasih!
Josh Kovach
6
imageView.userInteractionEnabled = YA; ini kuncinya! Terima kasih.
HamasN
3
userInteractionEnabledmasih harus disetel ke YA / benar dalam Xcode 8 Objective-C / Swift
leanne
76

Ya, UIGestureRecognizer dapat ditambahkan ke UIImageView. Seperti yang dinyatakan dalam jawaban lain, sangat penting untuk diingat untuk mengaktifkan interaksi pengguna pada tampilan gambar dengan mengatur userInteractionEnabledpropertinya YES. UIImageView mewarisi dari UIView, yang properti interaksi penggunanya diatur YESsecara default, namun, properti interaksi pengguna UIImageView diatur NOsecara default.

Dari dokumen UIImageView:

Objek tampilan gambar baru dikonfigurasikan untuk mengabaikan acara pengguna secara default. Jika Anda ingin menangani peristiwa dalam subkelas kustom UIImageView, Anda harus secara eksplisit mengubah nilai properti userInteractionEnabled menjadi YA setelah menginisialisasi objek.

Bagaimanapun, pada sebagian besar jawabannya. Berikut adalah contoh cara membuat a UIImageViewdengan UIPinchGestureRecognizer, a UIRotationGestureRecognizer, dan a UIPanGestureRecognizer.

Pertama, di viewDidLoad, atau metode lain pilihan Anda, buat tampilan gambar, berikan gambar, bingkai, dan aktifkan interaksi penggunanya. Kemudian buat tiga gerakan sebagai berikut. Pastikan untuk menggunakan properti delegasi mereka (kemungkinan besar diatur sendiri). Ini akan diperlukan untuk menggunakan beberapa gerakan sekaligus.

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

Berikut adalah tiga metode yang akan dipanggil ketika gerakan pada tampilan Anda terdeteksi. Di dalam mereka, kita akan memeriksa keadaan saat ini dari gerakan, dan jika itu di salah satu mulai atau diubah UIGestureRecognizerStatekita akan membaca skala gesture / rotasi / terjemahan properti, menerapkan data ke transformasi affine, menerapkan transformasi affine ke gambar lihat, lalu atur ulang skala gerakan / rotasi / terjemahan.

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

Terakhir dan yang sangat penting, Anda harus menggunakan metode UIGestureRecognizerDelegategestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer untuk memungkinkan gerakan bekerja pada saat yang sama. Jika ketiga gerakan ini adalah satu-satunya gerakan yang ditugaskan kelas ini sebagai delegasi mereka, maka Anda dapat kembali YESseperti yang ditunjukkan di bawah ini. Namun, jika Anda memiliki gerakan tambahan yang ditugaskan kelas ini sebagai delegasi mereka, Anda mungkin perlu menambahkan logika ke metode ini untuk menentukan gerakan yang mana sebelum mengizinkan mereka semua bekerja sama.

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

Jangan lupa untuk memastikan bahwa kelas Anda sesuai dengan protokol UIGestureRecognizerDelegate . Untuk melakukannya, pastikan antarmuka Anda terlihat seperti ini:

@interface MyClass : MySuperClass <UIGestureRecognizerDelegate>

Jika Anda lebih suka bermain sendiri dengan kode dalam proyek sampel yang berfungsi, proyek sampel yang saya buat berisi kode ini dapat ditemukan di sini.

Mick MacCallum
sumber
1
Sejauh ini, inilah jawaban terbaik yang pernah saya lihat di stackoverflow.com, lengkap, dikomentari dengan baik dan bahkan menyertakan kode sumber di git. Terima kasih untuk itu
Alejandro Luengo
1
Jelas, langkah demi langkah, penjelasan yang luar biasa
Alvin
1
Terima kasih, yang melakukannya dalam satu atau dua halaman yang gagal dilakukan oleh beberapa lusin tutorial selama bertahun-tahun oleh Apple dan lainnya. Saya merasa bahwa harus ada banyak hal lain di iOS yang dimungkinkan, tetapi karena kebingungan dan kesalahpahaman, semuanya hilang bagi kami.
Zack Morris
Jawaban yang bagus, yang terbaik. Terima kasih banyak atas kesabaran Anda.
Jorg B Jorge
13

Cepat 4.2

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

dan ketika disadap:

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

Solusi Swift 2.0

Anda membuat pengenal isyarat ketukan, jepit, atau geser di manor yang sama. Di bawah ini saya akan memandu Anda melalui 4 langkah untuk mengaktifkan dan menjalankan pengenal Anda.

4 Langkah

1.) Mewarisi dari UIGestureRecognizerDelegatedengan menambahkannya ke tanda tangan kelas Anda.

class ViewController: UIViewController, UIGestureRecognizerDelegate {...}

2.) Kontrol seret dari gambar Anda ke viewController Anda untuk membuat IBOutlet:

@IBOutlet weak var tapView: UIImageView!

3.) Di viewDidLoad Anda, tambahkan kode berikut:

// 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.) Buat fungsi yang akan dipanggil ketika pengenal isyarat Anda diketuk. (Anda dapat mengecualikan = niljika Anda memilih).

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

Kode akhir Anda akan terlihat seperti ini:

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)
    }
}
Dan Beaulieu
sumber
1
saya menulis blog tentang ini di sini: codebeaulieu.com/3/UIGestureRecognier-programatically
Dan Beaulieu
6

Saya baru saja melakukan ini dengan swift4 dengan menambahkan 3 gerakan bersamaan dalam tampilan tunggal

  1. UIPinchGestureRecognizer : Memperbesar dan memperkecil tampilan.
  2. UIRotationGestureRecognizer : Putar tampilan.
  3. UIPanGestureRecognizer : Menyeret tampilan.

Di sini kode sampel saya

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
     }

}

Setiap pertanyaan, cukup ketik untuk berkomentar. Terima kasih

Leang Socheat
sumber
3

SWIFT 3 Contoh

override func viewDidLoad() {

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

    self.backgroundImageView.isUserInteractionEnabled = true
}

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

Tidak ada delegasi penerima gesture atau implementasi lainnya jika diperlukan.

mourodrigo
sumber
2

Anda juga dapat menyeret pengenal gerakan ketukan ke tampilan gambar di Storyboard. Kemudian buat tindakan dengan ctrl + dragmenggunakan kode.

zevij
sumber
1

Untuk pencinta Blok Anda dapat menggunakan ALActionBlocks untuk menambahkan aksi gerakan di blok

__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];
dimo hamdy
sumber