如何向UIView添加触摸事件?

Man*_*nni 272 events objective-c touch uiview ios

如何向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:'
Run Code Online (Sandbox Code Playgroud)

我不想创建子类和覆盖

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
Run Code Online (Sandbox Code Playgroud)

Nat*_*ror 571

在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...
}
Run Code Online (Sandbox Code Playgroud)

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

  • 非常简洁的回答,谢谢.但是,谢谢,如果这更容易一点,那不是很好吗?!:) (5认同)
  • CGPoint系列有什么作用? (2认同)
  • @yourfriendzak`CGPoint`表示点击视图的超级视图中的点击位置.您可以使用此点将点击的视图(或同级视图)移动到点击的位置.这在用于拖动屏幕周围视图的`UIPanGestureRecognizer`的处理程序中更有用. (2认同)

Sur*_*gch 119

手势识别器

当您向视图添加手势识别器时,可以通知许多常用的触摸事件(或手势).默认情况下支持以下手势类型:

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

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

在Interface Builder中添加手势

将手势识别器从对象库拖到视图上.

在此输入图像描述

控制从文档大纲中的手势拖动到View Controller代码,以便制作插座和操作.

在此输入图像描述

这应该在默认情况下设置,但也要确保为您的视图将User Action Enabled设置为true.

在此输入图像描述

以编程方式添加手势

要以编程方式添加手势,您(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")
    }
}
Run Code Online (Sandbox Code Playgroud)

笔记

  • sender参数是可选的.如果您不需要对手势的引用,则可以将其保留.但是,如果这样做,请删除(sender:)操作方法名称后面的内容.
  • handleTap方法的命名是任意的.将它命名为您想要的任何名称.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
    @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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

笔记

  • 您可以向单个视图添加多个手势识别器.但是为了简单起见,我没有这样做(滑动手势除外).如果您需要用于项目,则应阅读手势识别器文档.这是相当容易理解和有帮助的.
  • 我的上述示例的已知问题:(1)平移视图在下一个手势事件上重置其帧.(2)第一次滑动时滑动视图来自错误的方向.(但是,我的示例中的这些错误不应影响您对手势识别器如何工作的理解.)

  • 为了使这个工作在'UIView`上,你还需要添加:`self.isUserInteractionEnabled = true;` (3认同)
  • 您的答案非常好,有用,详细说明.这就是为什么我有投票你也回答.但是你错过了一条我认为必须包含在你的答案中的指令,因为你已经详细解释了它.该指令是关于设置"<yourView> .EnableUserInteraction = TRUE".我希望你同意我的意见. (2认同)

LiC*_*eng 51

我想你可以简单地使用

UIControl *headerView = ...
[headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown];
Run Code Online (Sandbox Code Playgroud)

我的意思是headerView从UIControl扩展.

  • `UIView`不是`UIControl`,因此无法访问`addTarget:action:forControlEvents:`. (61认同)
  • 另请注意,UIControl继承自UIView.为了我的目的,我所要做的只是一个子类型的简单切换. (8认同)
  • 这是更好的答案.`UITapGestureRecognizer`不是'UIControlEventTouchDown`的替代品."Tap"通常由`UIControlEventTouchDown`和`UIControlEventTouchUpInside`组成. (6认同)
  • 那么为什么这是一个更好的解决方案,因为我正在改变继承只是为了处理水龙头? (2认同)

rud*_*ryk 18

根据接受的答案,您可以定义一个宏:

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

这个宏使用ARC,所以没有release调用.

宏用法示例:

handle_tap(userpic, self, @selector(onTapUserpic:));
Run Code Online (Sandbox Code Playgroud)

  • 如果您在故事板中创建视图,请不要忘记启用"启用用户交互"选项. (4认同)

Ind*_*ada 18

Swift 3和Swift 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
  }
}
Run Code Online (Sandbox Code Playgroud)

使用

yourView.addTapGesture(tapNumber: 1, target: self, action: #selector(yourMethod))
Run Code Online (Sandbox Code Playgroud)


Ann*_*nnu 8

您可以通过在代码中添加Gesture Recogniser来实现此目的.

第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]; 
Run Code Online (Sandbox Code Playgroud)

第2步: ViewController.m:

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

注意:在我的案例中你的视图是 @property (strong, nonatomic) IBOutlet UIView *localView;

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

在此输入图像描述

在此输入图像描述


iOS*_*iOS 7

Swift 4.2和Xcode 10中

使用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
}
Run Code Online (Sandbox Code Playgroud)

如果要使用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)
    }
} 
Run Code Online (Sandbox Code Playgroud)

我的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...")
}
Run Code Online (Sandbox Code Playgroud)


Esq*_*uth 6

这是一个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
    }
}
Run Code Online (Sandbox Code Playgroud)


Gia*_*ang 5

斯威夫特3:

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

func handleTapGestureRecognizer(_ gestureRecognizer: UITapGestureRecognizer) {

}
Run Code Online (Sandbox Code Playgroud)