当用户移动速度非常快时,从superview中删除子视图

时间:2011-07-20 10:16:47

标签: iphone objective-c ipad uiview

如何根据用户触摸点或视点中的移动点非常快速地删除子视图。我能够在视图中获得用户触摸点和移动点,并且还可以根据用户触摸点移除子视图[subview removefromsuperview];。

当用户移动速度非常快时,某些子视图会被删除,而某些图像会被删除。如果用户移动缓慢,则子视图会被删除。我正在将部分代码放在下面

`

-(void)deleteSubView:(CGPoint)userCurrentPoint{

 for(int i=0;i<[subviews count];i++){

if (CGRectContainsPoint([[subviews objectAtIndex:i] CGRectValue], userCurrentPoint)) {

                [[superview viewWithTag:i ] removeFromSuperview];



    }
}

`

有没有办法根据用户的快速移动点删除子视图。我需要你的建议。  谢谢大家

3 个答案:

答案 0 :(得分:2)

将它放在头文件中:

@interface YourView : UIView

@property (nonatomic, assign) CGPoint lastTouchLocation;
@end

这应该是实施:

@implementation YourView
@synthesize lastTouchLocation;

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];

    self.lastTouchLocation = [[touches anyObject] locationInView:self];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];

    CGPoint oldLocation = self.lastTouchLocation;
    CGPoint newLocation = [[touches anyObject] locationInView:self];

    for (UIView *subview in self.subviews)
    {
        if (LineIntersectsRect(oldLocation, newLocation, subview.frame))
        {
            [subview removeFromSuperview];
        }
    }

    self.lastTouchLocation = newLocation;
}

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

    self.lastTouchLocation = CGPointZero;
}

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

    self.lastTouchLocation = CGPointZero;
}
@end

这是做什么的:我们检查最后一次接收到的触摸与当前接触之间的线是否与子视图的帧相交。为什么?请参阅deanWombourne的回答。

这是最初由habjan提供的交叉代码 - 您也应该在标题中输入。

static inline BOOL LineIntersectsLine(CGPoint l1p1, CGPoint l1p2, CGPoint l2p1, CGPoint l2p2)
{
    CGFloat q = (l1p1.y - l2p1.y) * (l2p2.x - l2p1.x) - (l1p1.x - l2p1.x) * (l2p2.y - l2p1.y);
    CGFloat d = (l1p2.x - l1p1.x) * (l2p2.y - l2p1.y) - (l1p2.y - l1p1.y) * (l2p2.x - l2p1.x);

    if(d == 0)
    {
        return false;
    }

    CGFloat r = (q / d);
    q = (l1p1.y - l2p1.y) * (l1p2.x - l1p1.x) - (l1p1.x - l2p1.x) * (l1p2.y - l1p1.y);

    CGFloat s = (q / d);

    if((r < 0) || (r > 1) || (s < 0) || (s > 1))
    {
        return false;
    }
    else
    {
        return true;
    }
}

static inline BOOL LineIntersectsRect(CGPoint p1, CGPoint p2, CGRect r)
{
    if (CGRectContainsPoint(r, p1) || CGRectContainsPoint(r, p2))
    {
        return YES;
    }
    else
    {
        CGPoint topLeft = CGPointMake(r.origin.x, r.origin.y);
        CGPoint topRight = CGPointMake(r.origin.x + r.size.width, r.origin.y);
        CGPoint bottomLeft = CGPointMake(r.origin.x, r.origin.y + r.size.height);
        CGPoint bottomRight = CGPointMake(r.origin.x + r.size.width, r.origin.y + r.size.height);

        return (LineIntersectsLine(p1, p2, topLeft, topRight) ||
                LineIntersectsLine(p1, p2, topRight, bottomRight) ||
                LineIntersectsLine(p1, p2, bottomRight, bottomLeft) ||
                LineIntersectsLine(p1, p2, bottomLeft, topLeft));
    }
}

答案 1 :(得分:1)

这与你的枚举无关:)

如果用户快速移动手指,则无法获得他们触摸的每个像素的列表,您可以一些。如果他们移动得足够快,你可能只得到起点和终点。

你不能只使用他们的手指被拖动的点,你必须弄清楚最后一个事件和这个之间触摸了哪些子视图:)

将其视为在起点和终点之间画一条线,并确定哪些子视图与该线重叠。

答案 2 :(得分:0)

如果我正确理解了您的问题,您希望删除用户在您的视图中拖动手指时触摸的所有子视图。

你的问题是touchesMoved:withEvent:以有限的频率发射。不保证为用户触摸的每个像素触发。结果,当用户快速移动他的手指时,touchesMoved:withEvent中报告的点之间存在间隙。如果用户足够快地移动他的手指,这些间隙可能足够大,以至于他们完全跳过某些子视图。

要解决此问题,您的代码需要记住上一个点的位置,然后测试前一个点和当前点形成的线段,以查看它是否与子视图的帧相交。有效的算法描述如下:How to test if a line segment intersects an axis-aligned rectange in 2D?