Stacking UITableViews does not pass touch events beneath its view
Asked Answered
D

2

6

I am having 3 UIViews stacked one on top of another

UITableview
planeView
rootView

TableView is at the top and rootView at the bottom. (rootView is not visible as TableView is on top of it)

I have implemented the following code in rootView

/*code in rootView*/



- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {}  

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {} 

expecting that these functions will be called when the top most view ie TableView is touched or moved,but on the contrary none of the functions were called.

I also tried putting the following code in TableView so that the rootView methods are called

 /*code in TableView so that the rootView methods are called(TableView is the subview of rootView)*/

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
 {
[super touchesBegan:touches withEvent:event];
[self.superview touchesBegan:touches withEvent:event];
 }

As expected it did so but the problem is that the TableView delegates like

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath    

are not called.

Is there any way by which it can be ensured that the TableView delegates implemented in TableView class(didSelectRow:) and the touchesBegan:,touchesMoved.. functions in rootView are also called accordingly?

ie When i click on a TableCell both (didSelectRow:atIndex) function in--> TableView and (touchesBegan and touchesEnd) method in-->rootView are called.

Dineric answered 14/11, 2011 at 20:35 Comment(0)
P
6

In your subclass of UITableView you should have touch methods like this:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.nextResponder touchesBegan:touches withEvent:event];
    [super touchesBegan:touches withEvent:event];
}

The difference here is that you're passing the touch to the next responder instead of the superview, and you're doing this before passing the touch to super.

Then in planeView you need to pass touches like this:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.superview touchesBegan:touches withEvent:event];
}

Keep in mind that this still may not work exactly as you expect. UITableView does a lot of mangling of the responder chain under the hood, in order to make it seem as if a UITableView (which is actually a complex collection of subviews) is just another view like a button or a label.

Parricide answered 14/11, 2011 at 20:43 Comment(4)
great resolution.Thanks for the helpDineric
But still at certain point of time touchesEnded: are not called.I have done some adjustment of the view position at the touchesEnded: message but since the message is not passed always the view adjustments are not working as i expected.Dineric
@prajul: yeah, I'm currently wrestling with a similar problem. The table view is a really complex beast. Depending on what you're using the underlying touches for, another thing I've tried is to place a fully transparent UIView over top of my table view. If you pass through the touches like my above code, the table view still doesn't work right (you can click it but not scroll it in any way). However, if you instead pass through hitTest:withEvent:, the table view will work like normal, and you can use the initial hitTest in your overlay uiview to do something like click a button or whatever.Parricide
I know this question is quite old, but I'm curious if a solution was found for some of the touches not passing through. I have a tableview inside of a tableview cell and overriding touchesBegan, touchesMoved, touchesEnded and touchesCancelled as suggested. It works for the most part, but there are a couple of cases where it behaves a little strangely.Decarburize
G
0

None of this worked for me

What solved it was simply:

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    let view = super.hitTest(point, with: event)
    return view == self ? nil : view
}

Ref this article: https://medium.com/@nguyenminhphuc/how-to-pass-ui-events-through-views-in-ios-c1be9ab1626b

Giles answered 18/5, 2018 at 15:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.