Анимация на UITableViewCell - PullRequest
0 голосов
/ 18 марта 2019

Я пытаюсь поместить анимацию в UITableViewCell.Анимация состоит в том, что ячейка табличного представления onClick меняет рамку tableCell на рамку tableview.

У меня есть следующий код:

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 10;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

    return cell;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell*cell = [tableView cellForRowAtIndexPath:indexPath];

    if(cell.frame.size.height == tableView.bounds.size.height){
        [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }else{
        cell.frame = tableView.bounds;
        [[cell superview] bringSubviewToFront:cell];
    }

    [UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:0.2 options:UIViewAnimationOptionCurveEaseOut animations:^{
         [self.view layoutIfNeeded];
    } completion:^(BOOL finished) {

    }];
}

Он работает нормально, но после изменения кадра ячейки я могу коснуться также других ячеек, которые мне не нужны.Как мне этого добиться?

enter image description here

enter image description here

Ответы [ 2 ]

2 голосов
/ 18 марта 2019

Одним из возможных решений было бы объявить переменную, которая будет содержать массив indexPath расширенной ячейки, например:

// Will hold the indexPath of expanded cell
var expandedCell : [IndexPath] = []

Вторым шагом будет добавление и удаление ячейки, которые являются / aren 'Расширение и для этого вам необходимо обновить свой делегат UITableView didSelectRowAt

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let index = expandedCell.firstIndex { (localIndexPath) -> Bool in
        return indexPath == localIndexPath
    }
    if let index = index  {
        expandedCell.remove(at: index)
    } else {
        expandedCell.append(indexPath)
    }
    tableviewMessageList.reloadRows(at: [indexPath], with: .fade)
} 

И, наконец, вам нужно добавить еще один делегат UITableView heightForRowAt для возврата высоты ячейки, если indexPath ячейкинаходится в массиве, он возвратит расширенный размер, иначе вернет нормальный размер вашей ячейки, например: -

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if expandedCell.contains(indexPath) {
        return tableView.frame.height
    }
    return 200.0 //NormalHeight
}

Примечание: мой ответ на языке Swift, но тот же принцип применим к Objective-Cвам просто нужно изменить синтаксис.

0 голосов
/ 20 марта 2019

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

Вот как я понимаю, ваша текущая проблема:

Вы хотели бы показать развернутую ячейку, и когда в этом расширенном состоянии касания проходят через представление ячейки, ударяются о представление таблицы позади него и повторно запускают метод делегата didSelectRowAtIndexPath: tableview (в других ячейках, кроме расширенной). один).

Вот несколько возможных решений, которые я вижу:

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

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapOnExpandedCell:)];
    [cell addGestureRecognizer:tap];
    cell.frame = tableView.bounds;
    [[cell superview] bringSubviewToFront:cell];
    UIView *bgView = [[UIView alloc] init];
    bgView.backgroundColor = [UIColor purpleColor];
    cell.selectedBackgroundView = bgView;
    [UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:0.2 options:UIViewAnimationOptionCurveEaseOut animations:^{
        [self.view layoutIfNeeded];
    } completion:nil];
}

-(void)didTapOnExpandedCell:(UIGestureRecognizer *)recognizer {
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.tableView.indexPathForSelectedRow];
    // do whatever you were planning on doing when tapping on the
    // expanded cell
    [self.tableView reloadRowsAtIndexPaths:@[self.tableView.indexPathForSelectedRow] withRowAnimation:UITableViewRowAnimationNone];
    [cell removeGestureRecognizer:recognizer];
}
  1. Подкласс UITableViewПеревести и переопределить касания. Начало:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    R4NTableViewCell *cell = (R4NTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
    cell.frame = tableView.bounds;
    [[cell superview] bringSubviewToFront:cell];
    UIView *bgView = [[UIView alloc] init];
    bgView.backgroundColor = [UIColor purpleColor];
    cell.selectedBackgroundView = bgView;
    [UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:0.2 options:UIViewAnimationOptionCurveEaseOut animations:^{
        [self.view layoutIfNeeded];
    } completion:nil];
}

// in R4NTableViewCell.m implementation override touchesBegan
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // if we're not selected, don't intercept the touch so the tableview can handle it
    // calling back to super will give the default tableview behavior and get our delegate callback
    if (self.selected == NO) {
        self.frameBeforeExpansion = self.frame;
        [super touchesBegan:touches withEvent:event];
    } else { // we're in the expanded state so intercept the touch
        NSSet <UITouch *> *singleTouches = [[event allTouches] objectsPassingTest:^BOOL(UITouch * _Nonnull obj, BOOL * _Nonnull stop) {
            return obj.tapCount == 1;
        }];
        if (singleTouches.count > 0) {
            // the user single tapped our view
            [UIView animateWithDuration:1.0 delay:0.0 usingSpringWithDamping:0.7 initialSpringVelocity:0.2 options:UIViewAnimationOptionCurveEaseOut animations:^{
                self.frame = self.frameBeforeExpansion;
                [self.superview layoutIfNeeded];
            } completion:^(BOOL finished) {
                [self setSelected:NO];
                self.backgroundView.backgroundColor = [UIColor greenColor];
            }];
        }
    }
}

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

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