iphone - UIView with labels, detect touch when moved fingers on it - iphone

I've a view with 10 character labels (big letters). Each character (label) has a different tag. The functionality that I'm developing is "Trace".
When user moves his finger over the view, i want to detect which character is touched.
I think I've to implement,
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
But I'm not knowing how to identify touch on the label and identify the character.
Can some one help me?

If you want to know the view that the touch began on (which view the user put their finger down on), you can read any of the touch items returned in the NSSet like so:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSInteger viewTag = [[[touches anyObject] view] tag];
//Check your view using the tags you've set...
}
However, even as the finger moves across the screen, this view property will ONLY return the view initially touched and not the view currently under the finger. To do this, you will need to track the coordinates of the current touch and determine which view it falls into, perhaps like this:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self.view];
//If all your views are collected as an array
for(UIView *view in views) {
if (CGRectContainsPoint([view frame], point))
{
//Bingo
}
}
}
The key to success on this is to make sure that you are getting your touches in coordinates reference to the proper views, so make sure to call locationInView: and CGRectContainsPoint() appropriately with values that match your application's view hierarchy and where your placing this code (i.e. the View, ViewController, etc.)

To detect simple touches you can use UIGestureRecognizer. Read the documentation for more on those. For more complex operations you do need to implement:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
To identify which item was touched you can give your item's tags values:
myView.tag = 4;
Then just check the tag value of the view reporting the touch and you know which it is.

Related

ccTouchesMoved works but ccTouchMoved does not

self.isTouchEnabled = YES;
in init method ofcourse.
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
}
-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
}
in Above code ccTouchesMoved works fine but ccTouchMoved doesn't call..
any help ?!
Cocos2d supports two different ways of handling touch events. These are defined by two different types of delegates (both defined in CCTouchDelegateProtocol.h).
Standard Touch Delegate:
#optional
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
These are the same sorts of events you'd get in a standard CocoaTouch app. You'll get all events, and all touches; it will be up to you to sort out which touches you care about in a multi-touch environment.To get these events in a CCLayer subclass, you simply set isTouchEnabled = YES, like so:
self.isTouchEnabled = YES;
Targeted Touch Delegate
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event;
#optional
- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event;
Note two important differences between the targeted and the standard touch delegate:
These methods provide only a single touch, rather than a set of them – and for that reason, the method names start with “ccTouch” rather than “ccTouches”.
The ccTouchBegan method is required and returns a boolean value.
So ccTouchBegan will be invoked separately for each of the available touches, and you return YES to indicate a touch you care about. Only touches claimed by ccTouchBegan will be subsequently passed on to the Moved, Ended, and Cancelled events (all of which are optional).
To receive these events, you must register as a targeted touch delegate with the global dispatcher. In a CCLayer subclass, override registerWithTouchDispatcher as follows:
-(void) registerWithTouchDispatcher {
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
(which will mean importing “CCTouchDispatcher.h” at the top of your file).
Which to use?
Apart from the more complex registration, the targeted touch delegate is generally easier to use, since you don't have to split the NSSet up yourself, and you don't have to keep checking whether the event is the one you want in the Moved/Ended/Cancelled events. But if you want to deal with multiple touches in one method (for example, because you combine them into a zoom or rotate input), you'll probably want to use the standard touch delegate instead.
Note that you can only use one or the other.
There's 2 behaviours: one for standard touches, one for multiple touches. You don't have to addTargetedDelegate:::, you can simply set the touchMode property to the value you like. The CCLayer will take care of the registration for you.
- (void)onEnter
{
[self setTouchMode: kCCTouchesAllAtOnce]; //resp kCCTouchesOneByOne
}
Behind the scenes, changing the touchMode will disable then re-enable the touches, and enabling the touches (enableTouch) will register the proper delegate for you, by calling either addStandardDelegate or addTargetedDelegate.

Get the touch event to a specific area like photo gallery in iphone

In my app for iPhone/iPad (in Objective-C), there are some UiButton's and other events and an UiImageView. Image covers the whole screen and i want that when one touches the upper or bottom area of screen(means suppose one button in the upper area), then the image resizes to a specific size.
But i am not able to recognize if one touches the upper area or not, like in the Photo Gallery of the iPhone(where if i touches the upper/lower area the navigation button appears, the same thing I want in my app).
I already have the touch events in my app:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {}
If somebody has any idea or solution please let me know.
The most obvious solution would be to subclass the UIImageView, then override it's touchesBegun:withEvent: method and in that method check where the actual touch happened:
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch * touch = (UITouch *)[touches anyObject];
CGPoint location = [touch locationInView:self];
if (location.y > some_arbitrary_value || location.y < some_other_arbitrary_value)
{
//touched upper or lower part
}
}

iPhone - ignoring the second touch on an area

I have a view that the users are allowed to finger paint. The code is working perfectly if the area is touched with one finger. For example: I touch it with one finger and move the finger. Then, a line is drawn as I move the first finger. If I touch with a second finger the same view, the line that was being drawn by the first finger stops.
I would like to ignore any touch beyond the first, i.e., to track the first touch but ignore all others to the same view.
I am using touchesBegan/moved/ended.
I have used this to detect the touches
UITouch *touch = [[event allTouches] anyObject];
lastPoint = [touch locationInView:myView];
I have also tried this
lastPoint = [[touches anyObject] locationInView:myView];
but nothing changed.
How do I do that - track the first touch and ignore any subsequent touch to a view?
thanks.
NOTE: the view is NOT adjusted to detect multiple touches.
A given touch will maintain the same memory address as long as it is in contact with the screen. This means you can save the address as an instance variable and ignore any events from other objects. However, do not retain the touch. If you do, a different address will be used and your code won't work.
Example:
Add currentTouch to your interface:
#interface MyView : UIView {
UITouch *currentTouch;
...
}
...
#end
Modify touchesBegan: to ignore the touch if one is already being tracked:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if(currentTouch) return;
currentTouch = [touches anyObject];
...
}
Modify touchesMoved: to use currentTouch instead of getting a touch from the set:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if(!currentTouch) return;
CGPoint currentPoint = [currentTouch locationInView:myView];
...
}
Modify touchesEnded: and touchesCancelled: to clear currentTouch, but only if currentTouch has ended or been cancelled.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if(currentTouch && currentTouch.phase == UITouchPhaseEnded) {
...
currentTouch = nil;
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
if(currentTouch && currentTouch.phase == UITouchPhaseCancelled) {
...
currentTouch = nil;
}
}
yourView.multipleTouchEnabled = NO;
From the reference documents on UIView
multipleTouchEnabled
A Boolean value that indicates whether
the receiver handles multitouch
events.
#property(nonatomic, getter=isMultipleTouchEnabled) BOOL
multipleTouchEnabled Discussion
When set to YES, the receiver receives
all touches associated with a
multitouch sequence. When set to NO,
the receiver receives only the first
touch event in a multitouch sequence.
The default value of this property is
NO.
Other views in the same window can
still receive touch events when this
property is NO. If you want this view
to handle multitouch events
exclusively, set the values of both
this property and the exclusiveTouch
property to YES.

iphone touchesbegan

I am using touchesBegan:.
I touch an object and drag-and-drop it to some other place, but I also want to make a copy of it on its original. That is, after touching and dragging, there should be a copy of it at its original position.
Below is my code:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch=[[event allTouches]anyObject];
CGPoint location=[touch locationInView:touch.view];
image1.center=location;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesBegan:touches withEvent:event];
}
Instead of moving image1 create and image2 (in touchesBegan) and move it (in touchesMoved)
You have to get touches from the superview of the object you want to move I believe.
You didn't show what image1 is, hence nobody can tell certainly how to copy that.

How to create hotlinks on image?

I'm not sure what the iPhone version of this is called but in HTML it is an image map. Certain areas of the map route you to different pages. I'd like to use an image, mostly in a scrollview, that I can have certain areas perform different actions. For example, Chemical Touch, http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=288060442&mt=8, does this. Click on an element and it grows in size to reveal more details. What is this type of technique called and how is it created?
I'd like to be a little more interactive with the user, how can I do any of these:
drop map pins onto this image
display a UITextField depending if I have text in that area
overlay text depending on user actions
Any suggestions here are greatly appreciated.
What you basically need to do is override any or all of:
- (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;
in your UIView subclass (or actually any subclass of UIResponder). Then you can handle the event however you wish, such as doing any of the things you mentioned in your question.
For example, here is Apple's sample code for a simple event handler:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch* touch = [touches anyObject];
NSUInteger numTaps = [touch tapCount];
if (numTaps < 2) {
[self.nextResponder touchesBegan:touches withEvent:event];
} else {
[self handleDoubleTap:touch];
}
}
The Event Handling section in the iPhone Application Programming Guide should give you all the info you need to get started.