Ignoring touch events on UIView except for the Buttons on them. - uiview

I have a MainViewController(A) and another DetailedViewController(B) as its subview. In "B" I have a UIView containing some UIControls like a UIButton, UILabel and some UIViews.
I need to ignore all the touch events within this UIView except for Button clicks and I have to remove the subView if clicked outside the UIView.
How can I accomplish this ?

A option might be to set a custom view in the detail view controller.
In that view you can override the hittest function.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *resultView = [super hitTest:point withEvent:event];
if (![resultView isKindClass:[UIButton class]])
{
resultView = nil;
}
return resultView;
}
Touches not on the buttons will than be ignored. But if you have a scroll view under it and you will start dragging on the buttons the scrollview will be ignored.

Related

forwarding UISwipeGestureRecognizer to underlying UIScrollView

in my viewController I have an imageSlider which is above a UITableView.
I want to forward vertical swipeGesture from imageSlider to the underlying tableview. so when I swipe vertically on imageSlider, underlying tableView begins to scrolling. (tableview can scroll below imageSlider)
what I did:
I have created a custom view for my viewController View and have override hitTest:WithEvent: method:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *targetView = self.flexibleHeader;
// Convert the point to the target view's coordinate system.
// The target view isn't necessarily the immediate subview
CGPoint pointForTargetView = [targetView convertPoint:point fromView:self];
if (CGRectContainsPoint(targetView.bounds, pointForTargetView)) {
// The target view may have its view hierarchy,
// so call its hitTest method to return the right hit-test view
UIView *finalView = [targetView hitTest:pointForTargetView withEvent:event];
//final view should be UIButton or other UIControl element in RestaurantFlexibleHeader view
if (![finalView isKindOfClass:[targetView class]]) {
return finalView;
}
}
return [super hitTest:point withEvent:event];
}
but the problem is that I can't detect swipe gesture from UIEvent. because allTouches property is empty!
I can put imageSlider below tableView, so When I start to scroll vertically on imageSlider tableView begins to start scrolling. but how can I forward horizontal swipe and tap event to imageSlider?
so whats your idea? how do you handle this dilemma?

UIButton action not get worked in UIView

I have a view of UIView subclass and 2 buttons and UITableview inside the view. In design part, one button first, then UITableView and then second button. When I click the first button(that is the button above the tableview), It gets the button action. But when I click the second button that is the button below UITableView it do not get the button action. If i drag the second button to above the position of tableview it get the action. Please help me.!
Well, when you have a UIView with userInteractionEnabled = YES, it gets all the touches, therefore, any UIView behind this view wont get touched.
You can use a solution with - hitTest:withEvent::
You need to subClass your UITableView, pass it a pointer to you 'behind' UIButton, and override - hitTest:withEvent: in your CustomTableView, like this:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
BOOL isInsideButton = CGRectContainsPoint(self.behindButton.frame, point);
return isInsideButton ? nil : [super hitTest:point withEvent:event];
}
Hope it will help.

How to make the subview outside the bounds recognize the touches

I have a view with a subview. When a button in the subview is tapped, the subview expands outside the bounds of a view, presenting couple of other buttons. However, I cannot find a way to interact with them.
I found a code at Apple's site:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
// Convert the point to the target view's coordinate system.
// The target view isn't necessarily the immediate subview
CGPoint pointForTargetView = [self.targetView convertPoint:point fromView:self];
if (CGRectContainsPoint(self.targetView.bounds, pointForTargetView)) {
// The target view may have its view hierarchy,
// so call its hitTest method to return the right hit-test view
return [self.targetView hitTest:pointForTargetView withEvent:event];
}
return [super hitTest:point withEvent:event];
}
However, I cannot understand how should I use it, so that my subview will recognize the touches.
Any help would be greately appreciated.
You need to subclass the UIView or which ever class you need and override that method. Then create an object of that subclass and use it. It will then recognize the touches.

UIView blocking UIScrollView's gesture recognizer

Hi I have a UIView on top of a UIScrollView like this. The UIView is a container that is itself transparent but has many subviews which are not.
-------------------------
- UIScrollView -
- -
- ------------- -
- - UIView - -
- ------------- -
-------------------------
The UIView is transparent but it prevents the UIScrollView from scrolling when touched. Some of the subviews are buttons so they have tap gestures that override the scrolling action but the transparent gaps in the frame of the UIView still blocks the scrolling gesture. Is there a way to prevent this from happening? I would still like to use it as a container to hold my other subviews.
You should not set userInteractionEnabled to NO hence you want it intractable. I think the right way is to subclass a UIView and override - pointInside: withEvent: like below.
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
CGPoint localPoint = [self convertPoint:point fromView:self];
for (UIView *subview in self.subviews) {
if ([subview pointInside:localPoint withEvent:event]) {
return YES;
}
}
return NO;
}
Use this view you can interact with subviews inside the view and scroll scroll view if not touch on subviews.
Thanks for the answers guys. But I found this solution which worked well for me:
How to get touches when parent view has userInteractionEnabled set to NO in iOS
Set userInteractionEnabled to FALSE on your view inside the scroll view.
myView.userInteractionEnabled = FALSE;

UIView handle and pass touch events to next sibling view

I'm building an iOS app that has a custom UIView upon a UIScrollView which in turn has a subview.
Here's the layout structure:
Note that the custom UIView(called "Detected Object Hint View") is not a subview of ScrollView, it's a sibling view of UIScrollView. And I want to respond to tap gesture on the custom UIView, so I've added UITapGestureRecognizer to the UIView, and it works for tap, but the UIScrollView will never get any touch events (not responding to scroll or zoom gesture).
I've googled a while, and a lot of people pointed out that in order for other view to respond to the touch events, I should implement the following method:
- (id)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *hitView = [super hitTest:point withEvent:event];
if (hitView == self){
return nil;
}
else {
return hitView;
}
}
But once I've added this method to my custom UIView, it will not respond to tap gesture either (of course).
So I'm wondering how can I handle the tap gesture on my custom UIView and pass the touch events to UIScrollView as well?
Big thanks!

Resources