get timespan of swipe action in iPhone app - iphone

How can we get the time a user spent to finish a swipe right or swipe left action? Already googled but no luck. If there is not built-in solution already, will touch begin and touch end together work?

Measure the start and end time, and calculate the difference in the UIGestureRecognizer callback method for gestureRecognizer.state == UIGestureRecognizerStateBegan and gestureRecognizer.state == UIGestureRecognizerStateEnded

You can do this by getting the date (which you create as ivar or property) in the touchesBegan method like this:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
touchStartDate = [NSDate date];
}
Then you fetch the difference in the touches end method:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
NSTimeInterval *touchDuration = [[NSDate date] timeIntervalSinceDate:touchStartDate];
NSLog(#"Touchduration %f",touchDuration);
}
If you only want to get the duration of a swipe left/right gesture you also need to check if the x value of the touch changed. This should be easy.

Related

How to pass touch event to another object?

I referenced the apps called "Comic Strip" and "Balloon Stickies Free"
When i add a speech balloon and touch s.b or s.b's tail, it works. But when i touch tail's around or between s.b and s.b's tail, it doesn't work. And Photo gets touch and works below the s.b.
So i tried to use hitTest:withEvent.
It works when i touch rectangle or tailRect first time. But when i touch other place in the object, and i touch rectangle or tailRect again, it doesn't work.
So how to modify this code ? i don't know .. help me please
- (id)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *hitView = [super hitTest:point withEvent:event];
if(CGRectContainsPoint(rectangle, currentPt)==YES || CGRectContainsPoint(tailRect, currentPt)==YES)
return hitView;
else
return nil;
}
Try overriding - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event instead.
Or take a look at Ole Begemann's OBShapedButton. Code can easily be modified
to work with UIView instead of UIButton.
See this post horizontal scrolling. Using this code you can get all touch events in a single UIWindow class. You have to write some code to pass control appropriately.

(cocos2d sneaky input) when setting joystick position with touchLocation, sprite won't move

i want to let user choose where the joystick should be. i.e., when user touch at one location, the joystick will appear there and ready to use and will remove when finger released.
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if ([self getChildByTag:kTagJoyStick] == nil) {
[self addJoystickWithPosition:[Helper locationFromTouches:touches]];
}
}
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if ([self getChildByTag:kTagJoyStick] != nil) {
[self removeChildByTag:kTagJoyStick cleanup:YES];
}
}
-(void) ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[self ccTouchesEnded:touches withEvent:event];
}
(do nothing in ccTouchesMoved method)
the update methods for joystick is:
-(void) sneakyUpdate {
if ([self getChildByTag:kTagJoyStick] != nil) {
if (joystick.velocity.x < 0) {
[self controlLeft];
}
else if (joystick.velocity.x > 0) {
[self controlRight];
}
else {
[self controlStop];
}
}
else {
[self controlStop];
}
}
but the result is, the joystick will appear and auto remove. but my sprite won't move. ( i set the break point, the sneakyUpdate method did get called. but the joystick.velocity is always 0. (and the thumbSprite didn't follow our finger.
please help me.
update:
and it turns out that i have to use 2 fingers (one for touch once and let the joystick show up, move my finger away, and then use another finger to control the joystick)
I'm not 100% sure, but I think you should use ccTouchBegan instead ccTouchesBegan, because sneakyJoystick classes use ccTouchBegan/Moved/Ended/Cancelled. Also, there are for a single touch, that is what you want.
I hope it works!
It looks like the problem is in your joystick class. Every joystick implementation I've seen uses the ccTouchesBegan method to activate the joystick, then in the ccTouchesMoved method, it makes sure its activated before using it. The problem I am seeing is that you create and add the joystick AFTER the touches began method, meaning your joystick never 'activates'. One way of bypassing this is to do all of the joystick's ccTouchesBegan functions in the method that creates the joystick, and 'activate' it from there by passing a reference to the touch that will be using it.

touchBegan timestamp

In my game I need to calculate duration of touch. I did this by :
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
self.endTime = [NSDate date]; //NSDate *endTime in .h
NSLog(#"%#",self.endTime);
}
-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
tStart = [[NSDate date] timeIntervalSinceDate:self.endTime];
NSLog(#"duration %f",tStart);
I am using this time interval as a factor to calculate height of the jump the player makes.
Less is the tStart, low is the jump and more is the tStart, high is the jump. I am doing this as :
if(tStart/1000<=9.430)
{
[player jump:5.0f];
}
else if(tStart>9.430 && tStart<=9.470)
{
[player jump:7.0f];
}
else if(tStart/1000>9.470)
{
[player jump:8.0f];
}
However I want to perform this action on tochBegan so that player may jump as soon as screen is touched. For this need the value of tStart in touchBegan. How should I do that?
Thanks
For a given touch, the UITouch instance is the same, so at ccTouchBegan save the touch/touches with the oldest timestamp and then wait for ccTouchEnded. When you get the UITouch that you previously saved, it means the player lifted the finger.
update
You can
Jump as soon as the user touches the screen.
Jump and boost the jump while the touch is ongoing up to x milliseconds (suggestion from grapefrukt).
Jump when the user releases the touch or a max time of x milliseconds has elapsed.
Jump and boost the jump until the touch is over.
Option 4 is unpractical because the user can keep pressing as long as he wants. So given that you want to make a variable jump, here is code for option 3:
UITouch *jump = nil;
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
// no jump ongoing, start one
if (jump==nil){
jump = touch;
// jump on a separate thread
[NSThread performSelectorInBackground:(SEL)jump withObject:touch];
}
}
-(void) jump:(UITouch*) touch {
NSInterval time = [touch timestamp]; // I *think* this is the time since system uptime :P
int jumpSpeed = 1;
// increase the jump speed for every 100ms up to 'maxTimeYouAreAllowedToJump' ms
while ( ([NSProcessInfo systemUptime]-time < maxTimeYouAreAllowedToJump) && (jump!=nil) ){
jumpSpeed += 1;
[NSThread sleepForTimeInterval:.1]; // sleep for 100ms
}
[self doTheJumpingWithSpeed:jumpSpeed]; // do the actual jump!
}
-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
// user released the touch that initiated the jump
if ((touch!=nil) && (touch==jump)) {
jump =nil;
}
}

Shorten the touch delay in a UIScrollView?

I'm looking to shorten the touch delay on a UIScrollView, but I don't want to use setDelaysContentTouches:NO; I still want there to be a slight delay but my users are complaining about it being too long.
Is there a way to do this?
The doc says
If the user then drags their finger far enough before the timer
elapses, the scroll view cancels any tracking in the subview and
performs the scrolling itself. Subclasses can override the
touchesShouldBegin:withEvent:inContentView:, pagingEnabled, and
touchesShouldCancelInContentView: methods (which are called by the
scroll view) to affect how the scroll view handles scrolling gestures.
So i think there is no easy way to do it. You probably have to reimplement the whole timer system in those methods.
I just came across this problem and this is my solution:
Subclass UIScrolView
Add override these methods:
- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
{
self.lastTimestamp = [NSDate date];
return [super touchesShouldBegin:touches withEvent:event inContentView:view];
}
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
NSDate *now = [NSDate date];
if (-[self.lastTimestamp timeIntervalSinceDate:now] < _delay)
return YES;
return NO;
}

Time between touch began and touch ended

Is there any method in objective-c to find the time between touch began and touch ended??
// add this ivar to your view controller
NSTimeInterval lastTouch;
// assign the time interval in touchesBegan:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
{
lastTouch = [event timestamp];
}
// calculate and print interval in touchesEnded:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
{
NSTimeInterval touchBeginEndInterval = [event timestamp] - lastTouch;
NSLog(#"touchBeginEndInterval %f", touchBeginEndInterval);
}
Each UITouch has it's own time/date stamp. Compare the ones you're interested in. Take a looke at the UIResponder class ref.
Aside- SO needs to update their code or release an iPhone app. Typing into their javascriptoided out text fields with an iPhone is almost comical.
In your touchesBegan:withEvent: method, create an NSDate object and store it in an instance variable. (For non-debugging purposes, create one date per touch and use CFMutableDictionary to associate the date with the touch.) Then, in touchesEnded:withEvent:, retrieve the stored date and create a new date, and send the latter a timeIntervalSinceDate: message to subtract the older date from it, giving you the result in seconds.