Touch Event on Uiview

How to add a touch event to a UIView?

In iOS 3.2 and higher, you can use gesture recognizers. For example, this is how you would handle a tap event:

//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 github that might help.

UIView touch event in controller

You will have to add it through code. First, create the view and add it to the hierarchy:

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

After that initialize gesture recognizer. Until Swift 2:

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

After Swift 2:

let gesture = UITapGestureRecognizer(target: self, action:  #selector (self.someAction (_:)))

Then bind it to the view:

self.myView.addGestureRecognizer(gesture)


Swift 3:

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

Swift 4 just add @objc before func:

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

Swift UI:

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

Touch Event on UIView

A very general way to get touches is to override these methods in a custom UIView subclass:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

The official docs for these methods is under Responding to Touch Events in the UIResponder class docs (UIView inherits those methods since it's a subclass of UIResponder). Longer and more introductory docs can be found in the Event Handling Guide for iOS.

If you just want to detect a tap (touch-down, then touch-up within your view), it's easiest to add a UIButton as a subview of your view, and add your own custom method as a target/action pair for that button. Custom buttons are invisible by default, so it wouldn't affect the look of your view.

If you're looking for more advanced interactions, it's also good to know about the UIGestureRecognizer class.

How to send touch event to a UIView on iOS

UIButton *btnInPicker = nil;
for( UIView *_subView in self.broadcastPicker.subviews) {
if( [_subView isKindOfClass:[UIButton class]] ) {
btnInPicker = (UIButton *)_subView;
break;
}
}

if(btnInPicker) {
[btnInPicker sendActionsForControlEvents:UIControlEventTouchDown];
}

but it has a issue:
Unbalanced calls to begin/end appearance transitions for

iOS Detect tap down and touch up of a UIView

A Gesture Recognizer is probably overkill for what you want. You probably just want to use a combination of -touchesBegan:withEvent: and -touchesEnded:withEvent:.

This is flawed, but it should give you and idea of what you want to do.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.touchDown = YES;
self.backgroundColor = [UIColor redColor];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// Triggered when touch is released
if (self.isTouchDown) {
self.backgroundColor = [UIColor whiteColor];
self.touchDown = NO;
}
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
// Triggered if touch leaves view
if (self.isTouchDown) {
self.backgroundColor = [UIColor whiteColor];
self.touchDown = NO;
}
}

This code should go in a custom subclass of UIView that you create. Then use this custom view type instead of UIView and you'll get touch handling.

Touch events does not get called in UIView class iOS Objective c

This answer will help in swift

In ViewDidLoad enable userInteraction for yourCustomView

 yourCustomView.userInteractionEnabled = true

call this method

 override func touchesBegan(touches: Set, withEvent event: UIEvent) {

super.touchesBegan(touches, withEvent: event)

let touch: UITouch = touches.first as! UITouch

if (touch.view == yourCustomView){
print("touchesBegan | This is an yourCustomView")
}else{
print("touchesBegan | This is not an yourCustomView")
}

}

Hopefully this will help..! :D

How can I detect a tap event in a child class of UIView?

You can simply add the gesture to the subclass of UIView as other said, but if you want to include the gesture within the definition of the subclass and make it more modular, you can use the notification dispatch mechanism to broadcast the gesture to the registered view controller.

First, you create a name for the notification:

extension Notification.Name {
static let CustomViewTapped = Notification.Name("CustomViewTapped")
}

Then, you add the gesture to your custom view:

class CustomView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)

let tap = UIGestureRecognizer(target: self, action: #selector(tapped))
self.addGestureRecognizer(tap)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

@objc func tapped(_ sender: UIGestureRecognizer) {
NotificationCenter.default.post(name: .CustomViewTapped, object: self)
}
}

And, finally, observe the broadcast from your view controller:

class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

NotificationCenter.default.addObserver(self, selector: #selector(customViewTapped), name: .CustomViewTapped, object: nil)

let customView = CustomView()
self.view.addSubview(customView)
}

@objc func customViewTapped(_ sender: UIGestureRecognizer) {

}
}

How to handle touches by an UIView on top of a UIScrollView and the UIScrollView both at the same time

Following this answer worked for me, though with some slight changes. Do note that for this solution, the UIScrollView is on top of the UIView. Firstly, you need to create a subclass of UIScrollView and override the touch methods.

protocol CustomScrollViewDelegate {
func scrollViewTouchBegan(_ touches: Set<UITouch>, with event: UIEvent?)
func scrollViewTouchMoved(_ touches: Set<UITouch>, with event: UIEvent?)
func scrollViewTouchEnded(_ touches: Set<UITouch>, with event: UIEvent?)
}

class CustomScrollView: UIScrollView {

var customDelegate: CustomScrollViewDelegate?

override func awakeFromNib() {
super.awakeFromNib()

for gesture in self.gestureRecognizers ?? [] {
gesture.cancelsTouchesInView = false
gesture.delaysTouchesBegan = false
gesture.delaysTouchesEnded = false
}
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
customDelegate?.scrollViewTouchBegan(touches, with: event)
super.touchesBegan(touches, with: event)
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
customDelegate?.scrollViewTouchMoved(touches, with: event)
super.touchesMoved(touches, with: event)
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
customDelegate?.scrollViewTouchEnded(touches, with: event)
super.touchesEnded(touches, with: event)
}
}

Take note of the code in awakeFromNib(). UIScrollView has its own set of gestures. So for each gesture, delaysTouchesBegan and delaysTouchesEnded needs to be false to prevent delays for the touch events.

Finally, just assign the delegate to your ViewController and implement the methods like so.

class ViewController: UIViewController {

@IBOutlet weak var scrollView: CustomScrollView!
@IBOutlet weak var touchView: UIView!

override func viewDidLoad() {
super.viewDidLoad()
scrollView.customDelegate = self
}
}

extension ViewController: CustomScrollViewDelegate {
func scrollViewTouchBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// Check if touch location is within the bounds of the UIView
if let touch = touches.first {
let position = touch.location(in: view)
if touchView.bounds.contains(position) {
print("Began")
}
}
}

func scrollViewTouchMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
// Check if touch location is within the bounds of the UIView
if let touch = touches.first {
let position = touch.location(in: view)
if touchView.bounds.contains(position) {
print("Moved")
}
}
}

func scrollViewTouchEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
// Check if touch location is within the bounds of the UIView
if let touch = touches.first {
let position = touch.location(in: view)
if touchView.bounds.contains(position) {
print("Ended")
}
}
}
}


Related Topics



Leave a reply



Submit