2015-03-15 2 views
1

Я пытаюсь получить мои клетки перелистываемой с gestureRecognizer:GestureRecognizer работает только на одной клетке

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *CellIdentifier = @"Cell Identifier"; 

    self.cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    // Fetch Bookmark 
    NSDictionary *bookmark = [self.bookmarks objectAtIndex:indexPath.row]; 

    // Configure Cell 
    self.cell.textLabel.numberOfLines = 0; 
    self.cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping; 
    self.cell.textLabel.text = [bookmark objectForKey:@"name"]; 
    self.cell.detailTextLabel.text = [bookmark objectForKey:@"url"]; 

    //Swipe recognizer 
    UIGestureRecognizer* recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
    [self.cell addGestureRecognizer:recognizer]; 

    return self.cell; 
} 

И у меня есть те методы, которые, как предполагается, чтобы мои клетки двигаться, но и вернуться в исходное положение, когда Я отпускаю сенсорный жест:

-(BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer { 
    CGPoint translation = [gestureRecognizer translationInView:self.cell]; 
    // Check for horizontal gesture 
    if (fabsf(translation.x) > fabsf(translation.y)) { 
     return YES; 
    } 
    return NO; 
} 

-(void)handlePan:(UIPanGestureRecognizer *)recognizer { 
    // 1 
    if (recognizer.state == UIGestureRecognizerStateBegan) { 
     // if the gesture has just started, record the current centre location 
     _originalCenter = self.cell.center; 
    } 

    // 2 
    if (recognizer.state == UIGestureRecognizerStateChanged) { 
     // translate the center 
     CGPoint translation = [recognizer translationInView:self.cell]; 
     self.cell.center = CGPointMake(_originalCenter.x + translation.x, _originalCenter.y); 
     // determine whether the item has been dragged far enough to initiate a delete/complete 
     _deleteOnDragRelease = self.cell.frame.origin.x < -self.cell.frame.size.width/2; 

    } 

    // 3 
    if (recognizer.state == UIGestureRecognizerStateEnded) { 
     // the frame this cell would have had before being dragged 
     CGRect originalFrame = CGRectMake(0, self.cell.frame.origin.y, 
              self.cell.bounds.size.width, self.cell.bounds.size.height); 
     if (!_deleteOnDragRelease) { 
      // if the item is not being deleted, snap back to the original location 
      [UIView animateWithDuration:0.2 
          animations:^{ 
           self.cell.frame = originalFrame; 
          } 
      ]; 
     } 
    } 
} 

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

Вы видели, откуда могла произойти ошибка?

ответ

1

Я вижу ряд проблем с вашим кодом.

Во-первых, вы используете свойство self.cell, чтобы создать свой распознаватель жестов, а также в вашем методе handlePan:.

Подумайте об этом в течение минуты. Если вы попытаетесь кастрюлю из 3-й ячейки в вашем представлении таблицы, почему бы self.cell волшебным образом содержать правильную ячейку? Ответ, это не так.

Вам необходимо преобразовать свой код, чтобы выяснить, какая ячейка используется на основе информации от распознавателя жестов. У распознавателя жестов есть связанное с ним представление, которое является видом, который вызвал жест. Поскольку вы прикрепляете свой распознаватель жестов непосредственно к соте, свойство представления распознавателя жеста должно быть ячейкой, которую пользователь перетаскивает. (Возможно, вам нужно будет прикрепить распознаватель жестов к cell.contentView вместо cell.view. Это то, что я всегда делал, но если привязывать его непосредственно к ячейке, отлично, это упрощает.)

Next Проблема: ваш код добавляет распознаватель жестов в ячейку каждый раз, когда вызывается cellForRowAtIndexPath. Если ячейка будет переработана, у нее уже будет установлен распознаватель жестов, поэтому у вас будет 2 распознавателя жестов, прикрепленных к ячейке. Тогда, если у вас есть длинный вид таблицы и прокручивается больше, когда он снова будет возвращен, он будет равен 3. Затем 4 и т. Д. Плохо.

Вам нужно каким-то образом добавить распознаватель жестов в ячейку, если у нее ее еще нет. Один из способов сделать это - создать пользовательский подкласс UITableViewCell и прикрепить распознаватель жестов к ячейке непосредственно в файле XIB для этой ячейки (или в методе init для вашей настраиваемой ячейки). Это подход, который я бы использовал.

Другой способ сделать это, который будет включать в себя меньше изменений в вашем коде: после удаления ячейки проверьте cell.gestureRecognizers.count. Если он равен нулю, добавьте свой распознаватель жестов. В противном случае он уже имеет один. (Примечание. Я не уверен, что если система присоединяет к ячейке один или несколько распознавателей жестов. Если это так, вам может потребоваться изменить свою логику, чтобы выяснить, есть ли у ячейки уже один из ваших распознавателей жестов, прикрепленных к ней.)

0
 BOOL addGesture = true; 
     for (int i = 0;i < cell.gestureRecognizers.count;i ++) { 
      id gest = cell.gestureRecognizers[i]; 
      if ([gest isKindOfClass:[UIPanGestureRecognizer class]]) { 
       addGesture = false; 
       break; 
      } 

     } 
     if (addGesture) { 
      UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
      [cell.userImageView addGestureRecognizer: panRecognizer]; 
     } 

так, что мы не зависим от изменений структуры яблока клеток безопасна :)

Смежные вопросы