Можете ли вы анимировать изменение высоты на UITableViewCell при выборе? - PullRequest
389 голосов
/ 20 января 2009

Я использую UITableView в своем приложении для iPhone, и у меня есть список людей, принадлежащих к группе. Мне бы хотелось, чтобы, когда пользователь нажимает на конкретного человека (выбирая таким образом ячейку), высота ячейки увеличивается, чтобы отобразить несколько элементов управления пользовательского интерфейса для редактирования свойств этого человека.

Возможно ли это?

Ответы [ 21 ]

1 голос
/ 01 августа 2016

Да, это возможно.

UITableView имеет метод делегата didSelectRowAtIndexPath

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [UIView animateWithDuration:.6
                          delay:0
         usingSpringWithDamping:UIViewAnimationOptionBeginFromCurrentState
          initialSpringVelocity:0
                        options:UIViewAnimationOptionBeginFromCurrentState animations:^{

                            cellindex = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
                            NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
                            [violatedTableView beginUpdates];
                            [violatedTableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationAutomatic];
                            [violatedTableView endUpdates];
                        }
                     completion:^(BOOL finished) {
    }];
}

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

1 голос
/ 31 мая 2017

Вот более короткая версия ответа Саймонса для Swift 3. Также позволяет переключать выделение ячейки

var cellIsSelected: IndexPath?


  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    cellIsSelected = cellIsSelected == indexPath ? nil : indexPath
    tableView.beginUpdates()
    tableView.endUpdates()
  }


  func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if cellIsSelected == indexPath {
      return 250
    }
    return 65
  }
1 голос
/ 07 июня 2016

Свифт Версия ответа Саймона Ли.

// MARK: - Variables 
  var isCcBccSelected = false // To toggle Bcc.



    // MARK: UITableViewDelegate
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    // Hide the Bcc Text Field , until CC gets focused in didSelectRowAtIndexPath()
    if self.cellTypes[indexPath.row] == CellType.Bcc {
        if (isCcBccSelected) {
            return 44
        } else {
            return 0
        }
    }

    return 44.0
}

Затем в didSelectRowAtIndexPath ()

  func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    self.tableView.deselectRowAtIndexPath(indexPath, animated: true)

    // To Get the Focus of CC, so that we can expand Bcc
    if self.cellTypes[indexPath.row] == CellType.Cc {

        if let cell = tableView.cellForRowAtIndexPath(indexPath) as? RecipientTableViewCell {

            if cell.tag == 1 {
                cell.recipientTypeLabel.text = "Cc:"
                cell.recipientTextField.userInteractionEnabled = true
                cell.recipientTextField.becomeFirstResponder()

                isCcBccSelected = true

                tableView.beginUpdates()
                tableView.endUpdates()
            }
        }
    }
}
0 голосов
/ 21 августа 2009

Я только что решил эту проблему с небольшим взломом:

static int s_CellHeight = 30;
static int s_CellHeightEditing = 60;

- (void)onTimer {
    cellHeight++;
    [tableView reloadData];
    if (cellHeight < s_CellHeightEditing)
        heightAnimationTimer = [[NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:@selector(onTimer) userInfo:nil repeats:NO] retain];
}

- (CGFloat)tableView:(UITableView *)_tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
        if (isInEdit) {
            return cellHeight;
        }
        cellHeight = s_CellHeight;
        return s_CellHeight;
}

Когда мне нужно увеличить высоту ячейки, я устанавливаю isInEdit = YES и вызываю метод [self onTimer], и он оживляет рост ячейки, пока не достигнет значения s_CellHeightEditing: -)

0 голосов
/ 04 марта 2016

Проверьте этот метод после iOS 7 и более поздних версий.

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return UITableViewAutomaticDimension;
}

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

0 голосов
/ 20 ноября 2015

Я использовал потрясающий ответ @ Joy, и он отлично работал с ios 8.4 и XCode 7.1.1.

Если вы хотите, чтобы ваша ячейка переключалась, я изменил -tableViewDidSelect следующим образом:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//This is the bit I changed, so that if tapped once on the cell, 
//cell is expanded. If tapped again on the same cell, 
//cell is collapsed. 
    if (self.currentSelection==indexPath.row) {
        self.currentSelection = -1;
    }else{
        self.currentSelection = indexPath.row;
    }
        // animate
        [tableView beginUpdates];
        [tableView endUpdates];

}

Я надеюсь, что все это помогло вам.

0 голосов
/ 08 февраля 2018

Swift версия Ответ Саймона Ли :

tableView.beginUpdates()
tableView.endUpdates()

Имейте в виду, что вы должны изменить свойства высоты ДО endUpdates().

0 голосов
/ 28 марта 2018

Входы -

tableView.beginUpdates () tableView.endUpdates () эти функции не будут вызывать

func tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {}

Но, если вы это сделаете, tableView.reloadRows (в: [selectedIndexPath! As IndexPath], с: .none)

Это вызовет func tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {} эта функция.

0 голосов
/ 10 ноября 2015

Вот мой код пользовательского подкласса UITableView, который расширяет UITextView в ячейке таблицы без перезагрузки (и потери фокуса клавиатуры):

- (void)textViewDidChange:(UITextView *)textView {
    CGFloat textHeight = [textView sizeThatFits:CGSizeMake(self.width, MAXFLOAT)].height;
    // Check, if text height changed
    if (self.previousTextHeight != textHeight && self.previousTextHeight > 0) {
        [self beginUpdates];

        // Calculate difference in height
        CGFloat difference = textHeight - self.previousTextHeight;

        // Update currently editing cell's height
        CGRect editingCellFrame = self.editingCell.frame;
        editingCellFrame.size.height += difference;
        self.editingCell.frame = editingCellFrame;

        // Update UITableView contentSize
        self.contentSize = CGSizeMake(self.contentSize.width, self.contentSize.height + difference);

        // Scroll to bottom if cell is at the end of the table
        if (self.editingNoteInEndOfTable) {
            self.contentOffset = CGPointMake(self.contentOffset.x, self.contentOffset.y + difference);
        } else {
            // Update all next to editing cells
            NSInteger editingCellIndex = [self.visibleCells indexOfObject:self.editingCell];
            for (NSInteger i = editingCellIndex; i < self.visibleCells.count; i++) {
                UITableViewCell *cell = self.visibleCells[i];
                CGRect cellFrame = cell.frame;
                cellFrame.origin.y += difference;
                cell.frame = cellFrame;
            }
        }
        [self endUpdates];
    }
    self.previousTextHeight = textHeight;
}
0 голосов
/ 23 ноября 2018

Swift 4 и выше

добавьте приведенный ниже код в метод делегата строки didselect строки таблицы

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