I have a superview with a grid of subviews. When I drag over/out of the subviews I want to alter its properties (similar to UIKeyboard on iPhone). The subviews are UIButton subclasses.
I'm thinking I need to do some kind of touch forwarding from the superview but I'm not clear how it works. What is the right combination of these methods?
– touchesBegan:withEvent:
– touchesMoved:withEvent:
– touchesEnded:withEvent:
– touchesCancelled:withEvent:
hitTest:withEvent:
I think you can use:
– touchesBegan:withEvent:
– touchesMoved:withEvent:
– touchesEnded:withEvent:
– touchesCancelled:withEvent:
on your superview.
A possible approach is identifying in touchesMoved which subview is currently "under the touch" (i.e., which the touch location is in) and change its status accordingly.
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
if(CGRectContainsPoint(subview1.frame, location)) {
...
}
}
touchesBegan and touchesEnded would not play a major role in this; they would only be useful to start and end the "tracking" you do in touchesMoved.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSSet *allTouches = [event allTouches];
<save initial touch if you need it>
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
<do whatever>
}
Related
I am using - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event touch method in imageView but I have taken imageView under the scrollview thats why touch event not perform because it is take directly scrollview
My code is
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// get touch event
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
if ([touch view] == imagedisplay) {
// move the image view
imagedisplay.center = touchLocation;
}
}
imagedisplay my imageView object but in not work touch event I have work in scrollview in that taken imageView so give any solution and source code related touch which apply in both scrollview and imageView
use below code, where you are creating imageView-
imageView.userInteractionEnabled = YES;
As it is NO by default.
I have a UIView containing a UIScrollView.
This UIView is supposed to respond to some touch events but it is not responding because of the scrollView it contains.
This scrollView's contentView is set to a MoviePlayer inside the OuterView.
Now whenever I click in the area where the MoviePlayer is, touch events of my OuterView are not responding.
I have even set the movie player's userInteraction to NO.
but now scrollView is interfering it seems.
I have referred to this post on SO itself.
How can a superview interecept a touch sequence before any of its subviews?
But the solution there, asks me to set the userInteractionEnabled to NO for the scrollView
But if I do so, my pinch zoom doesn't take place either!
What to do?
An UIScrollView intercepts all touch events because it has to decide if/when the user has movd their finger in order to scroll the scroll view.
You may want to subclass UIView, then in the
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)evt;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)evt;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)evt;
methods, check for the neccessary touches, then forward all these methods to your UIScrollViewInstance. For example:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface MyView: UIView {
UIScrollView *scrollView;
}
#end
#implementation MyView
/* don't forget to alloc init your ScrollView init -init
and release it in -dealloc! Then add it as a subview of self. */
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)evt
{
/* check for a gesture */
[scrollView touchesBegan:touches withEvent:evt];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)evt;
{
/* check for a gesture */
[scrollView touchesMoved:touches withEvent:evt];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)evt;
{
/* check for a gesture */
[scrollView touchesEnded:touches withEvent:evt];
}
#end
I have a subview, which also contains a UIButton.
Now, once I enter the touchesEnded, I want to execute some instructions only if the main subview was touched (and not the UIButton).
Is there a way to do this??
Thanks in advance.
ezbz
Use write your logic using these events ,by comparing the coordinates accordingly .
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *aTouch = [touches anyObject];
CGPoint point = [aTouch locationInView:self.view];
NSLog(#"X%f",point.x);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
}
I tried the following code, but it doesn't work. How should it be modified?
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
location = [touches locationInView:self];
}
In the h files I have defined location like this:
CGPoint location;
The (NSSet *)touches will give you all the current touches on the screen. You will need to go on each touch on this set and get it's coordinate.
These touches are members of UITouch class. Have a look at the UITouch class reference.
for instance you would do:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint location = [touch locationInView:self];
// Do something with this location
// If you want to check if it was on a specific area of the screen for example
if (CGRectContainsPoint(myDefinedRect, location)) {
// The touch is inside the rect, do something with it
// ...
// If one touch inside the rect is enough, break the loop
break;
}
}
}
Cheers!
Actually I'm having a scroll-view. In that I'm using 30-buttons. what's my requirement is I need to rearrange the buttons. Like, when i touched any button it should be selected with our touch. and where ever we move in the scroll-view it should move along with our touch. after i ended the touch, the buttons should be swapped. Can any one help me regarding this.........
You can do this behavior but there a lot of work. You need next:
1. Create UIControl subclass that will be your buttons.
2. Override all touches* methods there.
3. Implement there support of standard uicontrol behavior + moving behavior.
#pragma mark -
#pragma mark Touches delegate methods
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
[self performSelector:#selector(delayedTouchBeging:) withObject:touch afterDelay:0.15];
[super touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if ( dragging ) {
// move your view in new position here
} else {
[super touchesMoved:touches withEvent:event];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if ( dragging ) {
// Do other stuff if you need
} else {
[super touchesEnded:touches withEvent:event];
}
dragging = NO;
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesEnded:touches withEvent:event];
}
- (void) delayedTouchBeging:(UITouch*) touch {
dragging = YES;
[self cancelTrackingWithEvent:nil];
// Do here stuff about begin moving (animation, etc)
}
You may want to look into how they do the "Launcher" code as a part of the three20 code catalog that's available for free. They do exactly something like this (and mimicks the iPhone apps view where you can move apps around or delete them).
http://github.com/facebook/three20