0

Are there one or two idiomatic ways to handle the kind of UI interaction described below? Perhaps a custom class is unnecessary?

I am implementing drag and drop in an iPadd app and would like to handle the case where the draggable is not released upon the droppable and the pan gesture leaves the UIView.

  • The view expands and gets a border when the draggable is over it, and it will return to its previous size and lose the border when the draggable leaves the area. There will be a noticeable delay before the down-scale animation begins.
  • It is possible the draggable will be brought back over the zone before the scale-down animation begins, suggesting the need for some kind of debouncing, i.e., something to collect the events that occur within a period of time and treat them as one event.
  • I know a large number of events are fired off during a pan gesture, and I don't want to allocate unnecessary resources (e.g., timers).

I was thinking of using a single custom timer, perhaps along these lines, but perhaps there's something much simpler for this?

4

1 に答える 1

0

次のコードは、指がビュー上を移動するたびに 300 ミリ秒のインフレート アニメーションでビューを膨張させ、タッチが外側にあるたびにビューを通常の状態に収縮させます。panGestureRecognizer は必要ありません。

@interface CustomView : UIView
{
    BOOL hasExpanded;
    CGRect initialFrame;
    CGRect inflatedFrame;
}
@end

@implementation CustomView
-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if(self)
    {
        hasExpanded = NO;

        initialFrame = frame;

        CGFloat inflateIncrement = 50.0f;

        inflatedFrame = CGRectMake(self.frame.origin.x-(inflateIncrement*0.5f),
                                        self.frame.origin.y-(inflateIncrement*0.5f),
                                        self.frame.size.width+inflateIncrement,
                                        self.frame.size.height+inflateIncrement);

    }
    return self;
}


-(void)forceDeflate
{
    if (hasExpanded)
    {
        //start deflating view animation
        [UIView animateWithDuration:0.3 animations:^{
            self.frame = initialFrame;

        }];
        hasExpanded = NO;
    }
}


-(void)inflateByCheckingPoint:(CGPoint)touchPoint
{
    if(!hasExpanded)
    {
        if(CGRectContainsPoint(self.frame,touchPoint))
        {
            //start inflating view animation
            [UIView animateWithDuration:0.3 animations:^{
                self.frame = inflatedFrame;

            }];

            hasExpanded = YES;
        }

    }
    else
    {
        if(!CGRectContainsPoint(self.frame,touchPoint))
        {
            //start deflating view animation
            [UIView animateWithDuration:0.3 animations:^{
                self.frame = initialFrame;

            }];

            hasExpanded = NO;
        }
    }
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *singleTouch = [touches anyObject];
    CGPoint touchPoint = [singleTouch locationInView:self.superview];
    [self inflateByCheckingPoint:touchPoint];
}

-(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    UITouch *singleTouch = [touches anyObject];
    CGPoint touchPoint = [singleTouch locationInView:self.superview];
    [self inflateByCheckingPoint:touchPoint];
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self forceDeflate];
}

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self forceDeflate];
}

@end
于 2013-08-07T05:46:19.277 に答える