удаление подпредставления из суперпредставления, когда пользователь перемещается очень быстро - PullRequest
1 голос
/ 20 июля 2011

как быстро удалить подпредставления в соответствии с точкой касания пользователя или точкой перемещения в виде. Я могу получить точку касания пользователя и точку перемещения в виде, а также я могу удалить подпредставление в соответствии с точкой касания пользователя, используя[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 ]

2 голосов
/ 20 июля 2011

Поместите это в свой заголовочный файл:

@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

Что это делает: мы проверяем, пересекает ли линия между последним полученным касанием и текущим касание фрейм подпредставления. Зачем? См. Ответ Дина Уомбурна.

Вот код пересечения, первоначально по 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 голос
/ 20 июля 2011

Это не связано с вашим перечислением:)

Если пользователь быстро двигает пальцем, вы не получаете список каждого пикселя, к которому он прикоснулся, вы получаете некоторых из них. Если бы они двигались достаточно быстро, вы могли бы получить только начальную и конечную точки.

Вы не можете просто использовать точку, к которой перетаскивается их палец, вы должны выяснить, какие подпредставления были затронуты между последним событием и этим:)

Думайте об этом как о проведении линии между начальной и конечной точками и определении того, какие подпредставления пересекаются с этой линией.

0 голосов
/ 20 июля 2011

Если я правильно понимаю ваш вопрос, вы хотите удалить все подпредставления, к которым пользователь прикасается, когда он проводит пальцем по вашему виду.

Ваша проблема в том, что touchesMoved:withEvent: срабатывает с ограниченной частотой. Не гарантируется выстрел для каждого пикселя, которого касается пользователь. В результате, когда пользователь быстро двигает пальцем, между точками, указанными в touchesMoved:withEvent, есть промежутки. Если пользователь перемещает палец достаточно быстро, эти промежутки могут быть достаточно большими, чтобы полностью пропустить некоторые подпредставления.

Чтобы решить эту проблему, ваш код должен запомнить положение предыдущей точки, а затем проверить отрезок, образованный предыдущей точкой и текущей точкой, чтобы увидеть, пересекается ли он с рамкой подпредставления. Эффективный алгоритм для этого описан в: Как проверить, пересекается ли отрезок прямой с выровненным по оси прямоугольником в 2D?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...