ios UIImageView 上的 UIGestureRecognizer

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3907397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:52:36  来源:igfitidea点击:

UIGestureRecognizer on UIImageView

iosobjective-cuiimageviewuigesturerecognizer

提问by system

I have a UIImageView, which I want to be able to resize and rotate etc.

我有一个UIImageView,我希望能够调整大小和旋转等。

Can a UIGestureRecognizerbe added to the UIImageView?

可以UIGestureRecognizer添加到UIImageView?

I would want to add a rotate and pinch recognizer to a UIImageViewwhich would be created at runtime.

我想向将UIImageView在运行时创建的a 添加一个旋转和捏合识别器。

How does one add these recognizers?

如何添加这些识别器?

回答by

Check that userInteractionEnabledis YESon the UIImageView. Then you can add a gesture recognizer.

检查userInteractionEnabled是否YESUIImageView. 然后你可以添加一个手势识别器。

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

回答by Mick MacCallum

Yes, a UIGestureRecognizer can be added to a UIImageView. As stated in the other answer, it is very important to remember to enable user interaction on the image view by setting its userInteractionEnabledproperty to YES. UIImageView inherits from UIView, whose user interaction property is set to YESby default, however, UIImageView's user interaction property is set to NOby default.

是的,可以将 UIGestureRecognizer 添加到 UIImageView。正如另一个答案中所述,记住通过将其userInteractionEnabled属性设置为 来启用图像视图上的用户交互非常重要YES。UIImageView 继承自 UIView,其用户交互属性YES默认设置为,但 UIImageView 的用户交互属性NO默认设置为。

From the UIImageView docs:

UIImageView 文档:

New image view objects are configured to disregard user events by default. If you want to handle events in a custom subclass of UIImageView, you must explicitly change the value of the userInteractionEnabled property to YES after initializing the object.

默认情况下,新的图像视图对象被配置为忽略用户事件。如果要在 UIImageView 的自定义子类中处理事件,则必须在初始化对象后将 userInteractionEnabled 属性的值显式更改为 YES。

Anyway, on the the bulk of the answer. Here's an example of how to create a UIImageViewwith a UIPinchGestureRecognizer, a UIRotationGestureRecognizer, and a UIPanGestureRecognizer.

无论如何,关于大部分答案。下面是如何UIImageView使用 a UIPinchGestureRecognizer、 aUIRotationGestureRecognizer和 a创建 a 的示例UIPanGestureRecognizer

First, in viewDidLoad, or another method of your choice, create an image view, give it an image, a frame, and enable its user interaction. Then create the three gestures as follows. Be sure to utilize their delegate property (most likely set to self). This will be required to use multiple gestures at the same time.

首先,在viewDidLoad或您选择的其他方法中,创建一个图像视图,给它一个图像、一个框架,并启用它的用户交互。然后创建三个手势如下。一定要利用他们的委托属性(最有可能设置为 self)。这将需要同时使用多个手势。

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

Here are the three methods that will be called when the gestures on your view are detected. Inside them, we will check the current state of the gesture, and if it is in either the began or changed UIGestureRecognizerStatewe will read the gesture's scale/rotation/translation property, apply that data to an affine transform, apply the affine transform to the image view, and then reset the gestures scale/rotation/translation.

以下是检测到视图上的手势时将调用的三个方法。在其中,我们将检查手势的当前状态,如果它处于开始或更改状态,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];
    }
}

Finally and very importantly, you'll need to utilize the UIGestureRecognizerDelegatemethod gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizerto allow the gestures to work at the same time. If these three gestures are the only three gestures that have this class assigned as their delegate, then you can simply return YESas shown below. However, if you have additional gestures that have this class assigned as their delegate, you may need to add logic to this method to determine which gesture is which before allowing them to all work together.

最后也是非常重要的是,您需要利用UIGestureRecognizerDelegate方法gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer来允许手势同时工作。如果这三个手势是仅有的三个将此类指定为其代理的手势,那么您可以简单地返回YES,如下所示。但是,如果您有其他手势将此类指定为其委托,则可能需要向此方法添加逻辑以确定哪个手势是哪个手势,然后再允许它们一起工作。

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

Don't forget to make sure that your class conforms to the UIGestureRecognizerDelegateprotocol. To do so, make sure that your interface looks something like this:

不要忘记确保您的类符合UIGestureRecognizerDelegate协议。为此,请确保您的界面如下所示:

@interface MyClass : MySuperClass <UIGestureRecognizerDelegate>

If you prefer to play with the code in a working sample project yourself, the sample project I've created containing this code can be found here.

如果您更喜欢自己在工作示例项目中使用代码,可以在此处找到我创建的包含此代码的示例项目

回答by ayalcinkaya

Swift 4.2

斯威夫特 4.2

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

and when tapped:

当点击时:

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

回答by Dan Beaulieu

Swift 2.0 Solution

Swift 2.0 解决方案

You create a tap, pinch or swipe gesture recognizer in the same manor. Below I'll walk you through 4 steps to getting your recognizer up and running.

您在同一个庄园中创建了一个点击、捏合或滑动手势识别器。下面我将引导您完成 4 个步骤来启动和运行您的识别器。

4 Steps

4 个步骤

1.)Inherit from UIGestureRecognizerDelegateby adding it to your class signature.

1.)UIGestureRecognizerDelegate通过将其添加到您的类签名来继承。

class ViewController: UIViewController, UIGestureRecognizerDelegate {...}

2.)Control drag from your image to your viewController to create an IBOutlet:

2.)控制从您的图像拖动到您的 viewController 以创建一个 IBOutlet:

@IBOutlet weak var tapView: UIImageView!

3.)In your viewDidLoad add the following code:

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.)Create the function that will be called when your gesture recognizer is tapped. (You can exclude the = nilif you choose).

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


Your final code should look something like this:

您的最终代码应如下所示:

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

回答by Leang Socheat

I just done this with swift4 by adding 3 gestures together in single view

我刚刚在 swift4 中通过在单个视图中添加 3 个手势来完成此操作

  1. UIPinchGestureRecognizer: Zoom in and zoom out view.
  2. UIRotationGestureRecognizer: Rotate the view.
  3. UIPanGestureRecognizer: Dragging the view.
  1. UIPinchGestureRecognizer:放大和缩小视图。
  2. UIRotationGestureRecognizer:旋转视图。
  3. UIPanGestureRecognizer:拖动视图。

Here my sample code

这是我的示例代码

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
     }

}

Any question, just type to comment. thank you

有任何问题,只需输入评论即可。谢谢你

回答by mourodrigo

SWIFT 3 Example

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
}

No gesture recongnizer delegates or other implementations where necessary.

在必要时没有手势识别器委托或其他实现。

回答by zevij

You can also drag a tap gesture recogniser to the image view in Storyboard. Then create an action by ctrl + dragto the code.

您还可以将点击手势识别器拖到 中的图像视图中Storyboard。然后通过ctrl + drag代码创建一个动作。

回答by dimo hamdy

For Blocks lover you can use ALActionBlocksto add action of gestures in block

对于积木爱好者,您可以使用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];