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
UIGestureRecognizer on UIImageView
提问by system
I have a UIImageView
, which I want to be able to resize and rotate etc.
我有一个UIImageView
,我希望能够调整大小和旋转等。
Can a UIGestureRecognizer
be added to the UIImageView
?
可以UIGestureRecognizer
添加到UIImageView
?
I would want to add a rotate and pinch recognizer to a UIImageView
which would be created at runtime.
我想向将UIImageView
在运行时创建的a 添加一个旋转和捏合识别器。
How does one add these recognizers?
如何添加这些识别器?
回答by
Check that userInteractionEnabled
is YES
on the UIImageView
. Then you can add a gesture recognizer.
检查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...
}
回答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 userInteractionEnabled
property to YES
. UIImageView inherits from UIView, whose user interaction property is set to YES
by default, however, UIImageView's user interaction property is set to NO
by default.
是的,可以将 UIGestureRecognizer 添加到 UIImageView。正如另一个答案中所述,记住通过将其userInteractionEnabled
属性设置为 来启用图像视图上的用户交互非常重要YES
。UIImageView 继承自 UIView,其用户交互属性YES
默认设置为,但 UIImageView 的用户交互属性NO
默认设置为。
From the UIImageView docs:
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 UIImageView
with 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 UIGestureRecognizerState
we 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: shouldRecognizeSimultaneouslyWithGestureRecognizer
to 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 YES
as 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 UIGestureRecognizerDelegate
by 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 = nil
if 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 个手势来完成此操作
- UIPinchGestureRecognizer: Zoom in and zoom out view.
- UIRotationGestureRecognizer: Rotate the view.
- UIPanGestureRecognizer: Dragging the view.
- UIPinchGestureRecognizer:放大和缩小视图。
- UIRotationGestureRecognizer:旋转视图。
- 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 + drag
to 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];