UIGestureRecognizer บน UIImageView


179

ฉันมีUIImageViewซึ่งฉันต้องการที่จะสามารถปรับขนาดและหมุน ฯลฯ

ที่สามารถUIGestureRecognizerถูกเพิ่มไปยังUIImageView?

ฉันต้องการเพิ่มตัวจดจำการหมุนและการหยิกUIImageViewที่จะถูกสร้างขึ้นในขณะใช้งานจริง

ใครจะเพิ่มตัวจดจำเหล่านี้ได้อย่างไร

คำตอบ:


426

ตรวจสอบว่าuserInteractionEnabledเป็นบนYES UIImageViewจากนั้นคุณสามารถเพิ่มตัวจำแนกท่าทาง

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
ไม่นี่เป็นเพียงแสดงวิธีเพิ่มตัวรู้จำท่าทาง คุณต้องทำการซูม / หมุนตัวเองในเครื่องจัดการท่าทางสัมผัส ดูแอปตัวอย่างTouches_GestureRecognizersเกี่ยวกับวิธีการซูม / หมุน

77
+1 นั่งที่นี่สำหรับอายุที่พยายามคิดว่าทำไมท่าทางของฉันไม่ทำงาน .. "ตรวจสอบว่า userInteractionEnabled คือ YES บน UIImageView" ขอบคุณ!
Critter

1
สิ่งนี้ทำให้การทำงานของฉันง่ายกว่าการพยายาม จำกัด ขีด จำกัด ของตัวจำแนกลายมือให้เป็นมุมมองโดยรวม ขอบคุณ!
Josh Kovach

6
imageView.userInteractionEnabled = YES; นี่คือกุญแจ! ขอบคุณ.
HamasN

3
userInteractionEnabledยังคงต้องตั้งค่าเป็น YES / true ใน Xcode 8 Objective-C / Swift
leanne

76

ใช่ UIGestureRecognizer สามารถเพิ่มใน UIImageView ตามที่ระบุไว้ในคำตอบอื่น ๆ ก็เป็นสิ่งสำคัญมากที่จะจำไว้ว่าให้เปิดใช้งานการโต้ตอบกับผู้ใช้ในมุมมองภาพโดยการตั้งค่าของคุณสมบัติการuserInteractionEnabled YESUIImageView สืบทอดมาจาก UIView ซึ่งคุณสมบัติการโต้ตอบผู้ใช้ถูกตั้งค่าเป็นค่าYESเริ่มต้นอย่างไรก็ตามคุณสมบัติการโต้ตอบกับผู้ใช้ของ UIImageView ถูกกำหนดเป็นค่าNOเริ่มต้น

จากเอกสาร UIImageView:

วัตถุมุมมองรูปภาพใหม่ถูกกำหนดค่าให้ละเว้นกิจกรรมผู้ใช้โดยค่าเริ่มต้น ถ้าคุณต้องการจัดการเหตุการณ์ในคลาสย่อยที่กำหนดเองของ UIImageView คุณต้องเปลี่ยนค่าของคุณสมบัติ userInteractionEnabled เป็น YES อย่างชัดเจนหลังจากเริ่มต้นวัตถุ

อย่างไรก็ตามในจำนวนมากของคำตอบ นี่คือตัวอย่างของวิธีการสร้างหนึ่งUIImageViewที่มีความUIPinchGestureRecognizerเป็นและUIRotationGestureRecognizerUIPanGestureRecognizer

ขั้นแรกในviewDidLoadหรืออีกวิธีหนึ่งที่คุณเลือกสร้างมุมมองรูปภาพกำหนดรูปภาพเฟรมและเปิดใช้งานการโต้ตอบกับผู้ใช้ จากนั้นสร้างสามท่าทางดังต่อไปนี้ ตรวจสอบให้แน่ใจว่าได้ใช้ทรัพย์สินของพวกเขา (ส่วนใหญ่ตั้งเป็นตนเอง) สิ่งนี้จะต้องใช้ท่าทางหลายอย่างในเวลาเดียวกัน

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

ต่อไปนี้เป็นวิธีการสามวิธีที่จะเรียกใช้เมื่อตรวจพบท่าทางบนมุมมองของคุณ ภายในพวกเขาเราจะตรวจสอบสถานะปัจจุบันของท่าทางและหากอยู่ในสถานะเริ่มต้นหรือเปลี่ยนแปลงUIGestureRecognizerStateเราจะอ่านคุณสมบัติมาตราส่วน / การหมุน / การแปลของท่าทางใช้ข้อมูลนั้นกับการแปลงเลียนแบบใช้การเลียนแบบการเปลี่ยนภาพ มุมมองจากนั้นรีเซ็ตมาตราส่วนท่าทาง / การหมุน / การแปล

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

ในที่สุดและที่สำคัญคุณจะต้องใช้วิธีUIGestureRecognizerDelegategestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizerเพื่อให้ท่าทางทำงานในเวลาเดียวกัน หากท่าทางทั้งสามนี้เป็นสามท่าทางเท่านั้นที่มีการกำหนดคลาสนี้เป็นตัวแทนของพวกเขาคุณสามารถกลับมาYESดังที่แสดงด้านล่าง อย่างไรก็ตามหากคุณมีท่าทางสัมผัสเพิ่มเติมที่ได้รับมอบหมายให้เป็นคลาสนี้คุณอาจต้องเพิ่มตรรกะในวิธีนี้เพื่อพิจารณาว่าท่าทางใดเป็นแบบไหนก่อนที่จะอนุญาตให้พวกเขาทำงานร่วมกันได้

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

อย่าลืมตรวจสอบให้แน่ใจว่าคลาสของคุณเป็นไปตามโปรโตคอลUIGestureRecognizerDelegate ในการทำเช่นนั้นตรวจสอบให้แน่ใจว่าอินเทอร์เฟซของคุณมีลักษณะดังนี้:

@interface MyClass : MySuperClass <UIGestureRecognizerDelegate>

หากคุณต้องการเล่นกับรหัสในโครงการตัวอย่างที่ใช้งานได้ด้วยตัวเองโครงการตัวอย่างที่ฉันสร้างขึ้นซึ่งมีรหัสนี้สามารถพบได้ที่นี่


1
นี่คือคำตอบที่ดีที่สุดที่ฉันเคยเห็นใน stackoverflow.com ซึ่งมีรายละเอียดครบถ้วนมีความคิดเห็นดีและยังมีซอร์สโค้ดบน git ขอบคุณสำหรับสิ่งนั้น
Alejandro Luengo

1
ชัดเจนทีละขั้นตอนการอธิบายที่ยอดเยี่ยม
อัลวิน

1
ขอบคุณที่ทำในหน้าหรือสองสิ่งที่หลายสิบบทเรียนในช่วงหลายปีที่ผ่านมาโดย Apple และคนอื่น ๆ ไม่ได้ทำ ฉันรู้สึกว่าต้องมีสิ่งอื่น ๆ อีกมากมายใน iOS ที่เป็นไปได้ แต่เนื่องจากการทำให้งงงวยและความเข้าใจผิดที่พวกเขาสูญเสียให้เรา
Zack Morris

คำตอบที่ดีคำตอบที่ดีที่สุด ขอบคุณมากสำหรับความอดทนของคุณ
Jorg B Jorge

13

สวิฟท์ 4.2

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

และเมื่อแตะ:

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

11

โซลูชัน Swift 2.0

คุณสร้างตัวจำแนกลายมือแบบแตะจีบนิ้วหรือการปัดนิ้วในคฤหาสน์เดียวกัน ด้านล่างฉันจะแนะนำคุณผ่าน 4 ขั้นตอนเพื่อทำให้ตัวจำแนกลายมือของคุณทำงาน

4 ขั้นตอน

1. ) รับค่าจากUIGestureRecognizerDelegateการเพิ่มลงในคลาสของคุณ

class ViewController: UIViewController, UIGestureRecognizerDelegate {...}

2. )ควบคุมการลากจากภาพของคุณไปยัง viewController ของคุณเพื่อสร้าง IBOutlet:

@IBOutlet weak var tapView: UIImageView!

3. )ใน viewDidLoad ของคุณให้เพิ่มรหัสต่อไปนี้:

// 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. )สร้างฟังก์ชั่นที่จะถูกเรียกเมื่อตัวจำแนกท่าทางของคุณถูกแตะ (คุณสามารถยกเว้น= 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)
}

รหัสสุดท้ายของคุณควรมีลักษณะดังนี้:

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

1
ฉันเขียนบล็อกเกี่ยวกับสิ่งนี้ที่นี่: codebeaulieu.com/3/UIGestureRecognier-programatically
Dan Beaulieu

6

ฉันเพิ่งทำสิ่งนี้กับ swift4 ด้วยการเพิ่ม 3 ท่าทางด้วยกันในมุมมองเดียว

  1. UIPinchGestureRecognizer : ซูมเข้าและซูมออกดู
  2. UIRotationGestureRecognizer : หมุนมุมมอง
  3. UIPanGestureRecognizer : การลากมุมมอง

นี่คือตัวอย่างรหัสของฉัน

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
     }

}

คำถามใด ๆ เพียงแค่พิมพ์เพื่อแสดงความคิดเห็น ขอบคุณ


3

SWIFT 3 ตัวอย่าง

override func viewDidLoad() {

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

    self.backgroundImageView.isUserInteractionEnabled = true
}

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

ไม่ได้มอบหมายผู้แนะนำหรือการใช้งานอื่น ๆ ตามที่จำเป็น


2

คุณยังสามารถลากตัวจดจำท่าทางการแตะไปยังมุมมองรูปภาพStoryboardได้ จากนั้นสร้างการกระทำตามctrl + dragรหัส


1

สำหรับคนรักบล็อกคุณสามารถใช้ALActionBlocksเพื่อเพิ่มการกระทำของท่าทางในบล็อก

__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];
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.