控制器中的 UIView 触摸事件

118

我该如何在编程中添加UIView的touchbegin动作或touchend动作,因为Xcode没有从Main.storyboard提供此功能?


2
那个是针对按钮的,OP想要为UIView添加事件。 - Miknash
1
使用 UILongPressGestureRecognizer,并将 minimumPressDuration 设置为零。请参见此答案。 不需要子类化或覆盖任何内容。 - Suragch
11个回答

170

你需要通过代码来添加它。首先,创建视图并将其添加到层次结构中:

var myView = UIView(frame: CGRectMake(100, 100, 100, 100))
self.view.addSubview(myView) 

之后初始化手势识别器。直到Swift 2:

let gesture = UITapGestureRecognizer(target: self, action: "someAction:")

在 Swift 2 之后:

let gesture = UITapGestureRecognizer(target: self, action:  #selector (self.someAction (_:)))
然后将其绑定到视图中:
self.myView.addGestureRecognizer(gesture)

    

Swift 3:

func someAction(_ sender:UITapGestureRecognizer){     
  // do other task
}
    

在Swift 4中,只需在func之前添加@objc

@objc func someAction(_ sender:UITapGestureRecognizer){     
    // do other task
}

Swift UI:

Text("Tap me!").tapAction {
    print("Tapped!")
}

1
我已经尝试过,但当我点击uiView时它会给我一个错误。我的代码如下: let gesture = UITapGestureRecognizer(target: self.uiPendingView, action: "touchPending") self.uiPendingView.addGestureRecognizer(gesture) 和方法: func touchPending(sender: AnyObject) { println("METHOD>>>>>>>>>>>>>>>>>") } - dhaval shah
1
只需在 "touchPending:" 中添加冒号,并且在函数中它看起来像这样:func touchPending(sender: UITapGestureRecognizer) - Rizwan Shaikh
1
你的代码中缺少了冒号“:”在操作中。 - Miknash
你好,当多个UIView都有相同的someAction函数时,我该如何区分哪一个UIView被点击了呢? - C Williams
最简单的方法是使用标签属性,然后在函数中确定哪个视图是发送者。 - Miknash
此外,您可以设计一个自定义视图xib,然后将其绑定到触摸事件中。但这取决于您的要求。在这里 - Wimukthi Rajapaksha

103

Swift 4 / 5:

let gesture = UITapGestureRecognizer(target: self, action:  #selector(self.checkAction))
self.myView.addGestureRecognizer(gesture)

@objc func checkAction(sender : UITapGestureRecognizer) {
    // Do what you want
}

Swift 3:

let gesture = UITapGestureRecognizer(target: self, action:  #selector(self.checkAction(sender:)))
self.myView.addGestureRecognizer(gesture)

func checkAction(sender : UITapGestureRecognizer) {
    // Do what you want
}

6
首先两行应该在ViewDidLoad中调用! - J A S K I E R

26

为Swift 3.x更新@Crashalot的答案:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.location(in: self)
        // do something with your currentPoint
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.location(in: self)
        // do something with your currentPoint
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.location(in: self)
        // do something with your currentPoint
    }
}

19

为了适应Swift 2.x,更新@Chackle的答案:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.locationInView(self)
        // do something with your currentPoint
    }
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.locationInView(self)
        // do something with your currentPoint
    }
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.locationInView(self)
        // do something with your currentPoint
    }
}

9

将以下代码放入你的UIView子类中(如果你为此功能创建一个子类,会更加容易)。

class YourView: UIView {

  //Define your initialisers here

  override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    if let touch = touches.first as? UITouch {
      let currentPoint = touch.locationInView(self)
      // do something with your currentPoint
    }
  }

  override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
    if let touch = touches.first as? UITouch {
      let currentPoint = touch.locationInView(self)
      // do something with your currentPoint
    }
  }

  override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
    if let touch = touches.first as? UITouch {
      let currentPoint = touch.locationInView(self)
      // do something with your currentPoint
    }
  }
}

@Chacle,我在我的页面中有超过10个Uiview,并且我想在其中一些子UIView中添加操作。那么我应该改变什么? - dhaval shah
这取决于你想用它来做什么。你想告诉哪个 UIView 被按下了,还是想在每个 UIView 中处理一些按下事件? - Chackle
我只想在一些特定的UIview上实现touchevent。 - dhaval shah

9

针对Swift 4

@IBOutlet weak var someView: UIView!  
let gesture = UITapGestureRecognizer(target: self, action:  #selector (self.someAction (_:)))
self.someView.addGestureRecognizer(gesture)

@objc func someAction(_ sender:UITapGestureRecognizer){
    print("view was clicked")
}

9

从在StoryBoard中创建的视图中创建出口。

@IBOutlet weak var redView: UIView!
@IBOutlet weak var orangeView: UIView!
@IBOutlet weak var greenView: UIView!   

重写touchesBegan方法。有两个选项,每个人都可以确定哪一个更适合他。

  1. Detect touch in special view.

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
         if let touch = touches.first {
            if touch.view == self.redView {
                tapOnredViewTapped()
            } else if touch.view == self.orangeView {
                orangeViewTapped()
            } else if touch.view == self.greenView {
                greenViewTapped()
            } else {
                return
            }
        }
    
    }
    
  2. Detect touch point on special view.

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = touches.first {
            let location = touch.location(in: view)
            if redView.frame.contains(location) {
                redViewTapped()
            } else if orangeView.frame.contains(location) {
                orangeViewTapped()
            } else if greenView.frame.contains(location) {
                greenViewTapped()
            }
        }
    
    }
    
最后,您需要声明将根据用户单击的视图调用的函数。
func redViewTapped() {
    print("redViewTapped")
}

func orangeViewTapped() {
    print("orangeViewTapped")
}

func greenViewTapped() {
    print("greenViewTapped")
}

非常好的示例,谢谢你向我展示!我们也可以使用touchEvent来实现这个.. 我只知道两种方法:按钮和手势.. 谢谢 +1 - Yogesh Patel
顺便提一下,在模拟器上这个触摸功能是不起作用的。因此,如果你正在使用模拟器进行开发,就无法测试代码。 - Keval Langalia

6
你可以使用这种方式; 创建一个扩展程序。
extension UIView {
    
    func addTapGesture(action : @escaping ()->Void ){
        let tap = MyTapGestureRecognizer(target: self , action: #selector(self.handleTap(_:)))
        tap.action = action
        tap.numberOfTapsRequired = 1
        
        self.addGestureRecognizer(tap)
        self.isUserInteractionEnabled = true
        
    }
    @objc func handleTap(_ sender: MyTapGestureRecognizer) {
        sender.action!()
    }
}

class MyTapGestureRecognizer: UITapGestureRecognizer {
    var action : (()->Void)? = nil
}

并采用以下方式:

@IBOutlet weak var testView: UIView!
testView.addTapGesture{
   // ...
}
    

6

Swift 4.2:

@IBOutlet weak var viewLabel1: UIView!
@IBOutlet weak var viewLabel2: UIView!
  override func viewDidLoad() {
    super.viewDidLoad()

    let myView = UITapGestureRecognizer(target: self, action: #selector(someAction(_:)))
    self.viewLabel1.addGestureRecognizer(myView)
}

 @objc func someAction(_ sender:UITapGestureRecognizer){
   viewLabel2.isHidden = true
 }

2

关于上面回答的更新:

如果你希望在点击事件中看到变化,即每当用户点击UIView时,UIView的颜色应更改,则请按照以下方式进行更改...

class ClickableUIView: UIView {
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
            if let touch = touches.first {
                let currentPoint = touch.locationInView(self)
                // do something with your currentPoint
            }

            self.backgroundColor = UIColor.magentaColor()//Color when UIView is clicked.
        }

        override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
            if let touch = touches.first {
                let currentPoint = touch.locationInView(self)
                // do something with your currentPoint
            }

            self.backgroundColor = UIColor.magentaColor()//Color when UIView is clicked.
        }

        override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
            if let touch = touches.first {
                let currentPoint = touch.locationInView(self)
                // do something with your currentPoint
            }

            self.backgroundColor = UIColor.whiteColor()//Color when UIView is not clicked.

}//class closes here

同时,在Storyboard和ViewController中调用这个类的方法如下:
@IBOutlet weak var panVerificationUIView:ClickableUIView!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接