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.
Related
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.
How do you record the duration of a touch and print it after on screen?
Here is the code above:
// add this ivar to your view controller
NSTimeInterval lastTouch;
int textTime;
// 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;
textTime = touchBeginEndInterval;
NSLog(#"touchBeginEndInterval %f", touchBeginEndInterval);
dynLabel.text = textTime;
}
dynLabel.text = textTime;
A label's text property expects a NSString*, but you're giving it a NSTimeInterval I.e. a number. That's what the error means. Create a string using e.g. NSString's -stringWithFormat: method.
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;
}
}
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;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
touchStartTime = [event timestamp];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSTimeInterval touchTimeDuration = [event timestamp] - touchStartTime;
}
touchStartTime is defined at class level.
Any idea why this won't recognise the touch events?
Thanks for the help!
Yes, this is possible to do. I setup a test project with a custom UITableViewCell subclass and defined the methods in the same way that you have, adding a log to the touchesEnded to print the touchTimeDuration. I ran it in the simulator and it seems to work for me.
How are you determining if your code is recognizing the events?
Personally, from my experience with the UITableView, I don't think that you can use the touch events.
You may have to look into other ways of dealing with this. For example, try using the selection as a helper?