Правильный способ реализации TouchesMoved? - PullRequest
5 голосов
/ 18 октября 2008

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

Код ниже является пользовательским UIView, который содержит плитки:

- (id)initWithFrame:(CGRect)frame {

    if (self = [super initWithFrame:frame]) {
        int i, j;
        int maxCol = floor(self.frame.size.width/TILE_SPACING);
        int maxRow = floor(self.frame.size.height/TILE_SPACING);

        CGRect frame = CGRectMake(0, 0, TILE_WIDTH, TILE_HEIGHT);
        UIView *tile;       

        for (i = 0; i<maxCol; i++) {
            for (j = 0; j < maxRow; j++) {
                frame.origin.x =  i * (TILE_SPACING) + TILE_PADDING;
                frame.origin.y =  j * (TILE_SPACING) + TILE_PADDING;
                tile = [[UIView alloc] initWithFrame:frame];

                [self addSubview:tile];
                [tile release]; 
            }
        }

    }
    return self;
}


- (void)touchesBegan: (NSSet *)touches withEvent:(UIEvent *)event {
    UIView *tile = [self hitTest:[[touches anyObject] locationInView:self] withEvent:nil];

    if (tile != self)
        [tile setHidden:YES];
}



- (void)touchesMoved: (NSSet *)touches withEvent:(UIEvent *)event {
    UIView *tile = [self hitTest:[[touches anyObject] locationInView:self] withEvent:nil];

    if (tile != self)
        [tile setHidden:YES];
}

Этот подход работает, но, тем не менее, если плитки становятся более плотными (то есть маленькие плитки и больше плиток на экране). IPhone меньше реагирует на движение пальца. Это может быть хит-тест, который отнимает у процессора все меньше усилий, но ему хотелось бы получить некоторые мнения.

Мои вопросы:

  1. Является ли это эффективным / правильным способом реализации touch-Moveed?

  2. Если это не так, каков будет рекомендуемый подход?

  3. Я попытался переместить функциональность в пользовательский класс Tile (под UIView), который класс, созданный выше, будет создавать и добавлять в качестве подпредставления. Эта плитка подпредставления может обрабатывать TouchesBegan, но при перемещении пальца другие плитки не получают TouchesBegan, даже если касания все еще являются частью начальной последовательности касаний. Есть ли способ реализовать его через класс плиток subview, как другие плитки получают событие TouchesBegan / TouchesMoved при движении пальца?

Ответы [ 3 ]

11 голосов
/ 19 октября 2008
  1. Не совсем, по моему опыту.
  2. Исходя из того, как вы настроили свои представления, может показаться, что существует гораздо более эффективный способ определить, какое из них было задействовано:

<pre></p> <pre><code> //In your init method, make sure each tile doesn't respond to clicks on its own ... tile.userInteractionEnabled = NO; ... - (void) touchesMoved: (NSSet *)touches withEvent:(UIEvent *)event { CGPoint tappedPt = [[touches anyObject] locationInView: self]; int xPos = tappedPt.x / (TILE_SPACING + TILE_PADDING); int yPos = tappedPt.y / (TILE_SPACING + TILE_PADDING); int tilesAcross = (self.bounds.size.width / (TILE_SPACING + TILE_PADDING)); int index = xPos + yPos * tilesAcross; if (index < self.subviews.count) { UIView *tappedTile = [self.subviews objectAtIndex: index]; tappedTile.hidden = YES; } }

  1. Вам нужно более четко решить, что должно происходить у вашего родителя, и что должно происходить в каждой клетке. Вы упомянули выше, что хотите, чтобы плитки получали события touchesBegan, но вы не включили никакого кода для этого. Представляя это, вы, вероятно, должны подумать об использовании слоев вместо представлений (если вы не выполняете какую-либо обработку событий, относящуюся к плитке). Все, что у вас есть, может быть сделано с помощью отслеживания событий в родительском элементе. Имейте в виду, что если у вас слишком много видов (или слоев), это будет медленно. Мы попробовали сетки размером 15x15 в кроссвордах, и, хотя в некоторых случаях это было нормально, в конце концов мы отказались от подхода с сеткой слоев.

(Не уверен, почему нумерация возобновлена ​​с 1 здесь ...)

5 голосов
/ 23 января 2009

одно дополнение, вместо проверки попадания, вы можете просто проверить, лежит ли точка в CGRect, который представляет кадр каждого подпредставления. У меня есть похожее приложение, и это лучше всего сработало для меня.

for (UIView* aSubview in self.subviews) {

    if([aSubview pointInside: [self convertPoint:touchPoint toView:aSubview] withEvent:event]){

       //Do stuff
    }
}
1 голос
/ 31 декабря 2008

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

Полагаю, это поможет немного увеличить скорость, так как iPhone не будет использовать ресурсы, пытаясь найти, какое изображение прослушивается при перетаскивании. То же самое относится и к мультитач.

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