如何将触摸事件添加到UIView?

如何添加触摸事件到UIView?
我尝试:

UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, nextY)] autorelease]; [headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown]; // ERROR MESSAGE: UIView may not respond to '-addTarget:action:forControlEvents:' 

我不想创build一个子类和覆盖

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 

在iOS 3.2及更高版本中,您可以使用手势识别器。 例如,这是你将如何处理一个轻拍事件:

 //The setup code (in viewDidLoad in your view controller) UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; [self.view addGestureRecognizer:singleFingerTap]; //The event handling method - (void)handleSingleTap:(UITapGestureRecognizer *)recognizer { CGPoint location = [recognizer locationInView:[recognizer.view superview]]; //Do stuff here... } 

还有一些内置的手势。 查看iOS事件处理和UIGestureRecognizer的文档。 我也有一堆示例代码在github上 ,可能有帮助。

手势识别器

有许多常用的触摸事件(或手势),当您将“ 手势识别器”添加到您的视图时,您会收到通知。 他们以下的手势types默认支持:

  • UITapGestureRecognizer 点击 (短暂触摸屏幕一次或多次)
  • UILongPressGestureRecognizer 长时间触摸长时间触摸屏幕)
  • UIPanGestureRecognizer 平移 (在屏幕上移动手指)
  • UISwipeGestureRecognizer 轻扫 (快速移动手指)
  • UIPinchGestureRecognizer (将两个手指放在一起或分开 – 通常放大)
  • UIRotationGestureRecognizer 旋转 (沿圆周方向移动两个手指)

除此之外,您还可以制作自己的自定义手势识别器。

在界面生成器中添加一个手势

将对象库中的手势识别器拖到您的视图中。

在这里输入图像说明

控制从“文档大纲”中的手势拖动到View Controller代码,以制作Outlet和Action。

在这里输入图像说明

以编程方式添加手势

要以编程方式添加手势,您(1)创build一个手势识别器,(2)将其添加到一个视图,(3)制作一个手势识别时调用的方法。

 import UIKit class ViewController: UIViewController { @IBOutlet weak var myView: UIView! override func viewDidLoad() { super.viewDidLoad() // 1. create a gesture recognizer (tap gesture) let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:))) // 2. add the gesture recognizer to a view myView.addGestureRecognizer(tapGesture) } // 3. this method is called when a tap is recognized func handleTap(sender: UITapGestureRecognizer) { print("tap") } } 

笔记

  • sender参数是可选的。 如果你不需要一个手势的参考,那么你可以把它放在外面。 但是,如果您这样做,请在创build手势时删除操作方法名称后的(_:)
  • handleTap方法的命名是任意的。 使用action: #selector( someMethodName (sender:))命名它action: #selector( someMethodName (sender:))

更多的例子

你可以研究我添加到这些视图的手势识别器,看看它们是如何工作的。

在这里输入图像说明

这是该项目的代码:

 import UIKit class ViewController: UIViewController { @IBOutlet weak var tapView: UIView! @IBOutlet weak var doubleTapView: UIView! @IBOutlet weak var longPressView: UIView! @IBOutlet weak var panView: UIView! @IBOutlet weak var swipeView: UIView! @IBOutlet weak var pinchView: UIView! @IBOutlet weak var rotateView: UIView! @IBOutlet weak var label: UILabel! override func viewDidLoad() { super.viewDidLoad() // Tap let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap)) tapView.addGestureRecognizer(tapGesture) // Double Tap let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap)) doubleTapGesture.numberOfTapsRequired = 2 doubleTapView.addGestureRecognizer(doubleTapGesture) // Long Press let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(gesture:))) longPressView.addGestureRecognizer(longPressGesture) // Pan let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(gesture:))) panView.addGestureRecognizer(panGesture) // Swipe (right and left) let swipeRightGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(gesture:))) let swipeLeftGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(gesture:))) swipeRightGesture.direction = UISwipeGestureRecognizerDirection.right swipeLeftGesture.direction = UISwipeGestureRecognizerDirection.left swipeView.addGestureRecognizer(swipeRightGesture) swipeView.addGestureRecognizer(swipeLeftGesture) // Pinch let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(gesture:))) pinchView.addGestureRecognizer(pinchGesture) // Rotate let rotateGesture = UIRotationGestureRecognizer(target: self, action: #selector(handleRotate(gesture:))) rotateView.addGestureRecognizer(rotateGesture) } // Tap action func handleTap() { label.text = "Tap recognized" // example task: change background color if tapView.backgroundColor == UIColor.blue { tapView.backgroundColor = UIColor.red } else { tapView.backgroundColor = UIColor.blue } } // Double tap action func handleDoubleTap() { label.text = "Double tap recognized" // example task: change background color if doubleTapView.backgroundColor == UIColor.yellow { doubleTapView.backgroundColor = UIColor.green } else { doubleTapView.backgroundColor = UIColor.yellow } } // Long press action func handleLongPress(gesture: UILongPressGestureRecognizer) { label.text = "Long press recognized" // example task: show an alert if gesture.state == UIGestureRecognizerState.began { let alert = UIAlertController(title: "Long Press", message: "Can I help you?", preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) self.present(alert, animated: true, completion: nil) } } // Pan action func handlePan(gesture: UIPanGestureRecognizer) { label.text = "Pan recognized" // example task: drag view let location = gesture.location(in: view) // root view panView.center = location } // Swipe action func handleSwipe(gesture: UISwipeGestureRecognizer) { label.text = "Swipe recognized" // example task: animate view off screen let originalLocation = swipeView.center if gesture.direction == UISwipeGestureRecognizerDirection.right { UIView.animate(withDuration: 0.5, animations: { self.swipeView.center.x += self.view.bounds.width }, completion: { (value: Bool) in self.swipeView.center = originalLocation }) } else if gesture.direction == UISwipeGestureRecognizerDirection.left { UIView.animate(withDuration: 0.5, animations: { self.swipeView.center.x -= self.view.bounds.width }, completion: { (value: Bool) in self.swipeView.center = originalLocation }) } } // Pinch action func handlePinch(gesture: UIPinchGestureRecognizer) { label.text = "Pinch recognized" if gesture.state == UIGestureRecognizerState.changed { let transform = CGAffineTransform(scaleX: gesture.scale, y: gesture.scale) pinchView.transform = transform } } // Rotate action func handleRotate(gesture: UIRotationGestureRecognizer) { label.text = "Rotate recognized" if gesture.state == UIGestureRecognizerState.changed { let transform = CGAffineTransform(rotationAngle: gesture.rotation) rotateView.transform = transform } } } 

笔记

  • 您可以将多个手势识别器添加到单个视图。 为了简单起见,我没有这样做(除了滑动手势)。 如果你需要为你的项目,你应该阅读手势识别器的文档 。 这是相当可以理解和有益的。
  • 我上面的例子已知的问题:(1)平移视图重置其框架下一个手势事件。 (2)第一次滑动时,滑动视图来自错误的方向。 (尽pipe我的示例中的这些错误不应该影响您对“手势识别器”如何工作的理解)。

更新了Swift 3

我想你可以简单地使用

 UIControl *headerView = ... [headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown]; 

我的意思是从UIControl扩展headerView。

基于接受的答案,你可以定义一个macros:

 #define handle_tap(view, delegate, selector) do {\ view.userInteractionEnabled = YES;\ [view addGestureRecognizer: [[UITapGestureRecognizer alloc] initWithTarget:delegate action:selector]];\ } while(0) 

这个macros使用ARC,所以没有release调用。

macros用法示例:

 handle_tap(userpic, self, @selector(onTapUserpic:)); 

您可以通过在您的代码中添加手势识别器来实现此目的。

第1步: ViewController.m:

 // Declare the Gesture. UITapGestureRecognizer *gesRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; gesRecognizer.delegate = self; // Add Gesture to your view. [yourView addGestureRecognizer:gesRecognizer]; 

第2步: ViewController.m:

 // Declare the Gesture Recogniser handler method. - (void)handleTap:(UITapGestureRecognizer *)gestureRecognizer{ NSLog(@"Tapped"); } 

注意:这里你的View在我的情况是@property (strong, nonatomic) IBOutlet UIView *localView;

编辑: * localView是从下面Main.storyboard中的白色框

在这里输入图像说明

在这里输入图像说明

下面是一个Swift版本:

 // MARK: Gesture Extensions extension UIView { func addTapGesture(#tapNumber: Int, target: AnyObject, action: Selector) { let tap = UITapGestureRecognizer (target: target, action: action) tap.numberOfTapsRequired = tapNumber addGestureRecognizer(tap) userInteractionEnabled = true } func addTapGesture(#tapNumber: Int, action: ((UITapGestureRecognizer)->())?) { let tap = BlockTap (tapCount: tapNumber, fingerCount: 1, action: action) addGestureRecognizer(tap) userInteractionEnabled = true } } 

Swift 3更新

 import UIKit extension UIView { func addTapGesture(tapNumber : Int, target: Any , action : Selector) { let tap = UITapGestureRecognizer(target: target, action: action) tap.numberOfTapsRequired = tapNumber addGestureRecognizer(tap) isUserInteractionEnabled = true } } 

使用

  yourView.addTapGesture(tapNumber: 1, target: self, action: #selector(yourMethod)) 

这里是ios tapgesture; 首先,您需要在下面的代码中写下以下代码,然后为GestureRecognizer创build操作

 - (IBAction)tapgesture:(id)sender { [_password resignFirstResponder]; [_username resignFirstResponder]; NSLog(@" TapGestureRecognizer tapped"); } 

另一种方法是在视图中添加一个透明button

 UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom]; b.frame = CGRectMake(0, 0, headerView.width, headerView.height); [headerView addSubview:b]; [b addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchDown]; 

然后,处理点击:

 - (void)buttonClicked:(id)sender {} 

创build一个手势识别器(子类),它将实现触摸事件,如touchesBegan 。 之后,您可以将其添加到视图。

这样你将使用组合而不是子类(这是请求)。

Swift 3:

 let tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGestureRecognizer(_:))) view.addGestureRecognizer(tapGestureRecognizer) func handleTapGestureRecognizer(_ gestureRecognizer: UITapGestureRecognizer) { }