UIButton - used full screen to catch touches - cocoa-touch

I am a definite beginner to iPhone programming. I have two simple questions.
1) I thought UIView would respond to touches like a UIButton but it appears I have to sub-class it. I'm not quite there yet. So my dirty little solution has been to place a UIButton over everything, make it full-screen, and turn off any color changes when it's pressed or disabled and so on. This works great, my app now responds to any part of the screen and it doesn't look like a button is being pressed. So the first part of my question is this: is this bad? If so, why?
2) Well nearly any part of the screen responds. For some reason, the very bottom 5% or so of the display doesn't respond to the touch and I've no idea why. The button is stretched down to the bottom and there's nothing else down there to intercept the touch. Any ideas?
Thanks!

To capture touches, you simply need to implement whichever of the following methods you require within a view controller - using a UIButton for this is (at best) somewhat perverse and will end up limiting the type of functionality you can provide.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
For more information on these events, see the UIResponder class reference.
In terms of your second point - I've personally noticed a small "dead zone" towards the bottom of the display (the home button being the "bottom") - I think this is just the nature of the display, but I must confess I've never really looked into it in any detail.

Related

touchesBegan not called in a UIView subclass

I am trying to mimic the GLPaint app and I have a TDPaintingView that has methods for -(void)touchesBegan... as well touchesMoved, touchesEnded, and touchesCanceled. However, I am not seeing any of them fire.
I have a TDAppDelegate that is hooked up to a Window in IB and a TDPaintingView in IB. The initWithCoder method for my TDPaintingView definitely fires, so I know it is being initialized. Furthermore, I can see from logging the object TDPaintingView from the context of applicationDidFinishLaunching that it is definitely there. When I change the view in trivial ways in IB (making bg red for example) it is reflected on simulator.
However, my view doesn't receive touches, and it's driving me crazy!
I set a breakpoint on -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event and it never stops, regardless of where I touch on the screen.
My TDPaintingView has no subviews, and it explicitly defines methods for those touches actions.
Where am I going wrong?

Change the appearance of a UIView while tapped down (but not yet released up)

I have a custom UIView, to which I have added a UITapGestureRecognizer to the view in order to detect taps (i.e. finger press and release) on the view. This works fine.
However, I now want to change the appearance of the UIView (making it a bit darker) while the finger is pressed on the view (just like the behavior of a UIButton).
How do I do this?
Change the appearance in -(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event.

How to capture ALL touch events in iOS?

I want to make an application that it capture all touch events and display x,y value in toolbar。
If it's possible to capture all events although event not happened in this app ?
How to show this app in the Toolbar like the Battery icon (when app run in background) ?
1) You can capture touch events when your own app is running is pretty easy. One way would be to a single root view controller, implement
- (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;
If you really are interested in displaying their coordinates, you will also have to think about questions like what happens in cases of multitouch.
However,
This is not possible for other apps. 2) is not possible at all. You don't have access to the status bar and you will not be able to do anything like capturing touch events when the application is in the background anyway. You can only capture events when your application is in the foreground.
Neither of your goals can be accomplished on a non-jailbroken device (and probably not even on a rooted one), because it violates the spirit of the Application Sandbox.

Conflicts between UIGestureRecognizer and in iPhone

I'm working in small app for iPhone which uses openGL.
The app is supposed to :
Move around the screen with a moving touch.
Zoom in/Out by tapping
I'm overwriting this functions to handle the coordinates of the touches and move around the screen with my finger, with success, working perfectly:
(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
I'm using UIGesture recognizers to double taps, pinch gestures, swipes, counter pinch with success as well, all gestures being detected perfectly.
But I'm having conflicts. Some times for example, I do a double tap and it's recognized correctly, but it's also passed to my touchedMoved function, resulting in erratic movements. Same thing happens with pinch and counter pinch gestures, most of the time they work well in zooming in and out, but some times my touchesMoved function detect the touches as well and moves the screen.
It's a bad practice to overwrite this functions and use UIGesturerecognizer at the same time ?. If not, it's there a way to work with both without conflicts ?
I tried setting setDelaysTouchesBegan and setDelaysTouchesEnded to Yes in my recognizers, but this results in my touches not being passed to none of my overwritten functions!
I was thinking in using UIGestureRecognizer to handle swipes and scrap the overwritten functions to receive touches, and use the value of the swipe to calculate how much move my screen, is it possible ?
I can't answer for why you sometimes receive spurious touchesMoved: events, but it does sound like you may want to just ditch the overwritten functions and use a UIPanGestureRecognizer to handle moving around the screen.

Intercept UITableView scroll touches

Is it possible to control when the UITableView scrolls in my own code.
I am trying to get behaviour where a vertical swipe scrolls and a horizontal swipe gets passed through to my code (of which there are many example)
BUT
I want a DIAGONAL swipe to do nothing, i.e the UITableView should not even begin scrolling.
I tried catching it in here
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
but the scrollView.contentOffset.x is always 0 so I cannot detect a horizontal movement.
I also tried subclassing UITableView and implementing
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
etc..
but the UITableView (and I guess it's parent UIScrollView) start to scroll before the touches are notified?
To re-iterate, I want the UITableView scrolling to be locked if a diagonal swipe is made, but to scroll vertically normally.
(This behaviour can be seen in Tweetie(Twitter) for the iPhone)
Thanks for any help!
If you can work with 3.2 or later, the UIGestureRecognizer suite should allow this. There are a series of calls allowing some gestures to cancel or interoperate with other gestures, and you should be able to create a custom diagonal swipe gesture that cancels other gestures but does not actually do anything itself.
Prior to 3.2 the UIScrollView gesture handling is essentially undocumented. You can detect taps but not movements through the standard touchesBegan UIResponder calls. I think that once it detects movement it commandeers the run loop and captures all events, bypassing the normal event chain.
Note that setContentOffset is always called. You can create a subclass of UIScrollView and when you detect a diagonal shift during event tracking do not pass it to super. I do not know if, or how well this would work but it is somewhere to start.