Reputation: 601
In my app I have a UIView with two UITableViews side by side. Layered on top of these is a UIView (all done in Storyboards).
It is set up to drag and drop cells between the tables by attaching to the top UIView, DnD Overlay View (using some open source code, https://github.com/josh2112/iPad-UITableView-DnD-Demo). All of this works fine until the tables have enough cells to warrant scrolling - I can't get them to scroll, because every time I touch a cell it pops it out to be dragged.
So, I want to try to make the pop out function from a long press instead of instantly. Here's what I have:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog( @"touchesBegan" );
UITouch* touch = [touches anyObject];
longPress = NO;
[self performSelector:@selector(longPress:) withObject:touch afterDelay:2.0];
}
- (void)longPress:(UITouch *)touch{
BOOL inDragSource = NO;
longPress = YES;
// Was the touch over a drag source?
for( UIView<DragSource>* dragSource in dragSources ) {
CGPoint point = [touch locationInView:dragSource];
if( CGRectContainsPoint( dragSource.bounds, point )) {
NSLog( @"Detected touch inside drag source!!!" );
inDragSource = YES;
// Ask the drag source for a draggable
UIView* draggable = [dragSource popItemForDragFrom:point];
if( draggable != nil ) {
NSLog( @"Start drag on thing: %@", draggable );
dragOperation = [[DragOperation alloc] initWithDraggable:draggable dragSource:dragSource initialPoint:draggable.center];
// Unattach the draggable from its parent view and attach it to the overlay view, using the touch
// location as the center point.
[self addSubview:draggable];
draggable.center = [self convertPoint:draggable.center fromView:dragSource];
draggable.layer.masksToBounds = NO;
draggable.layer.cornerRadius = 8;
draggable.layer.shadowOffset = CGSizeMake( 7, 7 );
draggable.layer.shadowRadius = 5;
draggable.layer.shadowOpacity = 0.5;
[UIView animateWithDuration:0.1f animations:^{
draggable.center = [touch locationInView:self];
draggable.transform = CGAffineTransformMakeScale( 1.2f, 1.2f );
}];
// If the drag source is also a drop target, tell it the draggable is hovering over it.
if( [dragSource conformsToProtocol:@protocol(DropTarget)] ) {
[self notifyDraggableEntered:(UIView<DropTarget>*)dragSource atPoint:point];
}
return;
}
}
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if( dragOperation == nil ) return;
UITouch* touch = [touches anyObject];
if(!longPress){
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(longPress:) object:touch];
}
else{
[self setHighlight:NO onDropTarget:dragOperation.currentDropTarget];
// If we have a current drop target, drop the draggable there
if( dragOperation.currentDropTarget != nil ) {
NSLog( @"Transferring draggable to drop target!" );
CGPoint point = [touch locationInView:dragOperation.currentDropTarget];
CGPoint adjustedPoint = [dragOperation.currentDropTarget actualDropPointForLocation:point];
[self animateDropOn:dragOperation.currentDropTarget atPoint:adjustedPoint withDuration:0.1f];
}
else {
// If the original drag source is also a drop target, put the draggable back in its
// original spot.
if( [dragOperation.dragSource conformsToProtocol:@protocol(DropTarget)] ) {
NSLog( @"Transferring draggable back to source" );
[self animateDropOn:(UIView<DropTarget>*)dragOperation.dragSource atPoint:dragOperation.initialPoint withDuration:0.3f];
}
else {
// Otherwise, just kill it?
NSLog( @"Killing draggable, nobody wants it :-(" );
[dragOperation.draggable removeFromSuperview];
dragOperation = 0;
}
}
}
}
So now, if I touch anywhere, touchesBegan is fired, then longPress, even if it isn't a long press. touchesEnded doesn't get hit to cancel the previous perform request. touchesCancelled doesn't get hit either.
Is there anything obvious I'm doing wrong here?
Upvotes: 1
Views: 1429
Reputation: 47059
You need to add UILongPressGestureRecognizer
on your controller
Here i provide UILongPressGestureRecognizer
on UIButton
just for example
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(btnCaptureTapped:)];
longPress.minimumPressDuration = 1.30f; // here you can set it as per your requirement.
[self.MyButtonName addGestureRecognizer:longPress];
And method call of UILongPressGestureRecognizer
- (void)btnCaptureTapped:(UILongPressGestureRecognizer*)gesture
{
// do your stuff
}
And also add click even on UIButton
is also work for you.
such like
[self.MyButtonName addTarget:self action:@selector(MyButtonNameTapped:) forControlEvents:UIControlEventTouchUpInside];
Upvotes: 1