ios 如何向 UIView 添加触摸事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4660371/
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
How to add a touch event to a UIView?
提问by Manni
How do I add a touch event to a UIView?
I try:
如何向 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:'
I don't want to create a subclass and overwrite
我不想创建子类并覆盖
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
回答by Nathan Eror
In iOS 3.2 and higher, you can use gesture recognizers. For example, this is how you would handle a tap 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...
}
There are a bunch of built in gestures as well. Check out the docs for iOS event handling and UIGestureRecognizer
. I also have a bunch of sample code up on githubthat might help.
还有一堆内置的手势。查看有关 iOS 事件处理和UIGestureRecognizer
. 我在github上还有一堆示例代码可能会有所帮助。
回答by Suragch
Gesture Recognizers
手势识别器
There are a number of commonly used touch events (or gestures) that you can be notified of when you add a Gesture Recognizerto your view. They following gesture types are supported by default:
当您将手势识别器添加到视图时,您会收到许多常用的触摸事件(或手势)的通知。默认支持以下手势类型:
UITapGestureRecognizer
Tap(touching the screen briefly one or more times)UILongPressGestureRecognizer
Long touch(touching the screen for a long time)UIPanGestureRecognizer
Pan(moving your finger across the screen)UISwipeGestureRecognizer
Swipe(moving finger quickly)UIPinchGestureRecognizer
Pinch(moving two fingers together or apart - usually to zoom)UIRotationGestureRecognizer
Rotate(moving two fingers in a circular direction)
UITapGestureRecognizer
点击(短暂触摸屏幕一次或多次)UILongPressGestureRecognizer
长按(长时间触摸屏幕)UIPanGestureRecognizer
平移(在屏幕上移动手指)UISwipeGestureRecognizer
滑动(快速移动手指)UIPinchGestureRecognizer
捏合(将两根手指并拢或分开 - 通常用于缩放)UIRotationGestureRecognizer
旋转(沿圆周方向移动两个手指)
In addition to these, you can also make your own custom gesture recognizer.
除了这些,你也可以让自己的自定义手势识别。
Adding a Gesture in the Interface Builder
在界面生成器中添加手势
Drag a gesture recognizer from the object library onto your view.
将手势识别器从对象库拖到您的视图上。
Control drag from the gesture in the Document Outline to your View Controller code in order to make an Outlet and an Action.
控制从文档大纲中的手势拖动到您的视图控制器代码,以制作一个插座和一个动作。
This should be set by default, but also make sure that User Action Enabledis set to true for your view.
这应该是默认设置,但也要确保用户操作已启用为您的视图设置为 true。
Adding a Gesture Programmatically
以编程方式添加手势
To add a gesture programmatically, you (1) create a gesture recognizer, (2) add it to a view, and (3) make a method that is called when the gesture is recognized.
要以编程方式添加手势,您 (1) 创建一个手势识别器,(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
@objc func handleTap(sender: UITapGestureRecognizer) {
print("tap")
}
}
Notes
笔记
- The
sender
parameter is optional. If you don't need a reference to the gesture then you can leave it out. If you do so, though, remove the(sender:)
after the action method name. - The naming of the
handleTap
method was arbitrary. Name it whatever you want usingaction: #selector(someMethodName(sender:))
.
- 该
sender
参数是可选的。如果您不需要对手势的引用,则可以将其省略。但是,如果您这样做,请删除(sender:)
操作方法名称之后的。 handleTap
方法的命名是任意的。使用.action: #selector(someMethodName(sender:))
More Examples
更多例子
You can study the gesture recognizers that I added to these views to see how they work.
您可以研究我添加到这些视图中的手势识别器,看看它们是如何工作的。
Here is the code for that project:
这是该项目的代码:
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
@objc 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
@objc 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
@objc 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
@objc 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
@objc 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
@objc 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
@objc func handleRotate(gesture: UIRotationGestureRecognizer) {
label.text = "Rotate recognized"
if gesture.state == UIGestureRecognizerState.changed {
let transform = CGAffineTransform(rotationAngle: gesture.rotation)
rotateView.transform = transform
}
}
}
Notes
笔记
- You can add multiple gesture recognizers to a single view. For the sake of simplicity, though, I didn't do that (except for the swipe gesture). If you need to for your project, you should read the gesture recognizer documentation. It is fairly understandable and helpful.
- Known issues with my examples above: (1) Pan view resets its frame on next gesture event. (2) Swipe view comes from the wrong direction on the first swipe. (These bugs in my examples should not affect your understanding of how Gestures Recognizers work, though.)
- 您可以向单个视图添加多个手势识别器。不过,为了简单起见,我没有这样做(除了滑动手势)。如果你需要为你的项目,你应该阅读手势识别器文档。这是相当容易理解和有帮助的。
- 我上面的示例的已知问题:(1) 平移视图在下一个手势事件时重置其框架。(2) 第一次滑动时,滑动视图来自错误的方向。(不过,我示例中的这些错误不应该影响您对手势识别器工作方式的理解。)
回答by LiCheng
I think you can simply use
我认为你可以简单地使用
UIControl *headerView = ...
[headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown];
i mean headerView extends from UIControl.
我的意思是 headerView 从 UIControl 扩展。
回答by Indrajit Sinh Rayjada
Swift 3 & Swift 4
斯威夫特 3 和斯威夫特 4
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
}
}
Use
用
yourView.addTapGesture(tapNumber: 1, target: self, action: #selector(yourMethod))
回答by rudyryk
Based on the accepted answeryou can define a macro:
根据接受的答案,您可以定义一个宏:
#define handle_tap(view, delegate, selector) do {\
view.userInteractionEnabled = YES;\
[view addGestureRecognizer: [[UITapGestureRecognizer alloc] initWithTarget:delegate action:selector]];\
} while(0)
This macro uses ARC, so there's no release
call.
这个宏使用ARC,所以没有release
调用。
Macro usage example:
宏使用示例:
handle_tap(userpic, self, @selector(onTapUserpic:));
回答by Annu
You can achieve this by adding Gesture Recogniser in your code.
您可以通过在代码中添加手势识别器来实现这一点。
Step 1:ViewController.m:
步骤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];
Step 2:ViewController.m:
第 2 步:ViewController.m:
// Declare the Gesture Recogniser handler method.
- (void)handleTap:(UITapGestureRecognizer *)gestureRecognizer{
NSLog(@"Tapped");
}
NOTE: here yourView in my case was @property (strong, nonatomic) IBOutlet UIView *localView;
注意:这里 yourView 在我的情况下是 @property (strong, nonatomic) IBOutlet UIView *localView;
EDIT:*localView is the white box in Main.storyboard from below
编辑:*localView 是 Main.storyboard 从下面的白框
回答by iOS
In Swift 4.2and Xcode 10
在Swift 4.2和 Xcode 10 中
Use UITapGestureRecognizerfor to add touch event
使用UITapGestureRecognizer添加触摸事件
//Add tap gesture to your view
let tap = UITapGestureRecognizer(target: self, action: #selector(handleGesture))
yourView.addGestureRecognizer(tap)
// GestureRecognizer
@objc func handleGesture(gesture: UITapGestureRecognizer) -> Void {
//Write your code here
}
If you want to use SharedClass
如果你想使用SharedClass
//This is my shared class
import UIKit
class SharedClass: NSObject {
static let sharedInstance = SharedClass()
//Tap gesture function
func addTapGesture(view: UIView, target: Any, action: Selector) {
let tap = UITapGestureRecognizer(target: target, action: action)
view.addGestureRecognizer(tap)
}
}
I have 3 views in my ViewController called view1, view2 and view3.
我的 ViewController 中有 3 个视图,分别称为 view1、view2 和 view3。
override func viewDidLoad() {
super.viewDidLoad()
//Add gestures to your views
SharedClass.sharedInstance.addTapGesture(view: view1, target: self, action: #selector(handleGesture))
SharedClass.sharedInstance.addTapGesture(view: view2, target: self, action: #selector(handleGesture))
SharedClass.sharedInstance.addTapGesture(view: view3, target: self, action: #selector(handleGesture2))
}
// GestureRecognizer
@objc func handleGesture(gesture: UITapGestureRecognizer) -> Void {
print("printed 1&2...")
}
// GestureRecognizer
@objc func handleGesture2(gesture: UITapGestureRecognizer) -> Void {
print("printed3...")
}
回答by Esqarrouth
Heres a Swift version:
这是一个 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
}
}
回答by Giang
Swift 3:
斯威夫特 3:
let tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGestureRecognizer(_:)))
view.addGestureRecognizer(tapGestureRecognizer)
func handleTapGestureRecognizer(_ gestureRecognizer: UITapGestureRecognizer) {
}
回答by daj mi spokój
Seems quite simple these days. This is the Swift version.
这些天似乎很简单。这是斯威夫特版本。
let tap = UITapGestureRecognizer(target: self, action: #selector(viewTapped))
view.addGestureRecognizer(tap)
@objc func viewTapped(recognizer: UIGestureRecognizer)
{
//Do what you need to do!
}