Determining which view touch was in for all touches - iphone

I want to determine which view touches occurred in for the entire application, for the purpose of logging touches so that I can go through the logs later and determine what the user did. I know I could subclass UIView and override touchesBegan/Ended to log those, but I am using many instances of UIButton, UISlider, etc in Interface Builder so that wouldn't work unless I also subclassed those classes.
For determining the time since last touch (for an idle screen timeout method) I already have UIApplication subclasses and sendEvent: overridden. The only way I can see to do what I want is to iterate through the main window's subviews, calling touchesForView: on the UIEvent passed into sendEvent:, but I was wondering if there was a cleaner way to tell which view was touched (whether it's through the sendEvent: method or not). Thanks!

See if this will do what you want: Observing pinch multi-touch gestures in a UITableView

Related

How do I enable user interaction in two overlapped UIViews?

I have two overlapping UIViews, and I want both to respond to user touches. At the moment, only the last view that was loaded responds.
How do I get both to respond to touch events?
you could provide a simple protocol which sends all touch events from the first view to the view in the background. So let the view in the background be a delegate of the first view would be a very simple approach.
Otherwise override the method touchesBegan:withEvent: of the view in the front and call the corresponding method of the view in the background.
Cheers,
anka
If you call touchesBegan/Moved/Ended on super after you handle them I think you will achieve what you want.
Finally, since I don't need that both responds at the same time, I made a workaround. I used the methods bringSubViewToFront: and sendSubViewToBack:. This methods made the work.

backgroundView for a UITableViewCell that is being reordered?

I'm trying to change the background view for cells that the user starts to drag with the handle out on the right hand side.
Apparently the selectedBackground view is not used in this state, is there any other solution?
This seems to be a tough one. It doesn't seem as if Apple has provided a way to notify the developer that the user has started reordering a table view cell. So I think this is what you'd have to do:
Subclass UITableViewCell.
Override the touchesBegan et al methods (this might get you started: http://devblog.wm-innovations.com/2010/03/30/custom-swipe-uitableviewcell/)
If you detect a "drag" touch event and the cell's showsReorderControl property (see http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewCell_Class/Reference/Reference.html) returns YES, swap out the backgroundView, remembering the previous one.
When the touch event ends, restore the old view.
Realize that it's not as easy as above 4 steps.
Custom touch handling inside a tableview is possible but hard. You might have to temporarily disable touch events in the UITableView (climbing up the responder chain) to make this work.
I hope these pointers get you moving in the right direction, though.

UIScrollView event handling

I'm trying to make my own custom UIScrollView for some reason. The question is, is it possible to exactly mimic the event handling behavior of UIScrollView including 'delayed content touches' and 'cancellable content touches'? That is, the custom scroll view should delay handling the event until it can determine if scrolling is the intent, and it should also be able to cancel its subviews' touches later. The problem is as follows:
1) hitTest: should return immediately so I can't delay the determination of the touch owner.
2) We can't cancel a touch event later programmatically. There's no such api.
3) I tried to override the sendEvent: method, but it didn't help. Having to call [super sendEvent:] will send events to unintended views. Moreover, hit test has been already done when sendEvent: was called and we can't alter the value of UITouch.view later.
So again the question is, is it possible to make a custom UIScrollView including it's touch handling behavior without using UIScrollView?
Thanks in advance!
One thing to keep in mind is that the gestureRecognizers (Pan and Zoom) that are used for regular UIScrollViews are private properties until iOS 5.0 comes out. I suppose when they are public you could transfer them to your own scroll view.

How to intercept touch events globally?

I have an view which is sometimes covered by some other views. However, if the user slides the finger across the screen, I want to slide that underlying view across the screen, too.
I could start making custom views for all those covering subviews and forward all kinds of touch events, but that's somewhat cumbersome. Maybe there's some kind of notification or another way that a UIView or UIControl subclass can be aware of touch events happening right now, no matter where they are.
In short: I need an UIView subclass or UIControl subclass which knows about any touch events happening on the entire screen. Or at least if tht's not possible, knowing about any touch events happening above itself in the same underlying superview.
Another description: There are 20 views, all reside inside the same superview. The first view is covered by 19 others. But if the user slides across the screen, that first view must slide too, so it must be aware of touch events.
Is there any better solution that making all 19 views forward touch events? (yes, all 19 views respond to touch events in this example)
Perhaps the hitTest:withEvent: method of UIView will help, it's helped me achieve what you are trying in the past.

Do CALayers block Touch Events in underlying views?

I have an application with a view containing several subviews. The subviews did not implement any touchesbegins logic. The Superview implemented all touchesbegins logic and manipulated each subview respectively if it was touched (determined by hit testing).
I have since been converting my subviews to layers. My problem now is that if I touch a layer, the hosting view of the superlayer never gets the touchesbegins method called. However if I touch the background, the touchesbegin method fires.
I understood from documentation that layers cannot handle events, if this is so why would it block events to the hosting view?
Thanks for any help, can't get my head around this.
-Corey
I found the problem... I was releasing the sublayers I was creating using [CALayer layer]. Since I didn't have control of them, I shouldn't have been managing them.
CALayers should not block touch events. Is your userInteractionEnabled flag set in the hosting view (sounds like it is, if you're getting SOME touches)? Is it inside a UIScrollView, which may be doing its own touch-handling.
What class is your touchesBegan method in?
I was having a similiar problem because my touchesBegan method was in a UIView subclass.
After moving the method to a UIViewController subclass, my problem was fixed.
Try doing that.