ios - 追加 - あなたが選択されたときにUITableViewCellの高さの変化をアニメーション化できますか?




uitableviewcell 高 さ 変更 (13)

私はiPhoneアプリでUITableViewを使用していUITableView 。グループに所属する人のリストがあります。 ユーザーが特定の人物(セルを選択する)をクリックするとセルの高さが増え、その人物のプロパティを編集するためのUIコントロールがいくつか表示されるようにしたいと思います。

これは可能ですか?


@ 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];

}

私はこれがあなたを助けたことを願っています。


Simon Leeの答えのSwift版。

// 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()
            }
        }
    }
}

iOS 7以降でこの方法をチェックしてください。

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

iOS 8ではこれが改善されました。テーブルビュー自体のプロパティとして設定できます。


ここで私のカスタム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;
}

はい、可能です。

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: calls heightForRowAtIndexPath:それに応じて処理します。


アニメーションがないので、reloadDataはいいことではありません...

これは私が現在試みていることです:

NSArray* paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];

それはほぼ正しく動作します。 ほぼ。 私はセルの高さを増やしています。テーブルビューのスクロール位置が保持されているかのように、セルが置き換えられたときにテーブルビューに小さなヒカップがあることがあります。新しいセル(最初のセル表の中の)はオフセットが高すぎるため、スクロールビューがバウンスして位置を変更します。


入力 -

tableView.beginUpdates()tableView.endUpdates()これらの関数は呼び出しません

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

しかし、もしそうなら、 tableView.reloadRows(at:[selectedIndexPath!as IndexPath]、with:.none)

関数func tableView(_ tableView:UITableView、cellForRowAt indexPath:IndexPath) - > UITableViewCell()を呼び出します。


私のような人のためのメモは、カスタムセルの "More Details"を追加するだけです。

[tableView beginUpdates];
[tableView endUpdates];

優れた作品でしたが、セルビューを "トリミング"することを忘れないでください。 Interface Builderから、Property Inspectorから「Cell」 - >「Content View」 - >「 Clip subview 」を選択します。


私はSimon Leeの答えが好きです。 私は実際にその方法を試しませんでしたが、リスト内のすべてのセルのサイズが変わるように見えます。 私はタップされているセルだけの変更を望んでいました。 私はちょっとシモンのようなものでしたが、ちょっとした違いがありました。 セルが選択されると、セルの外観が変わります。 そしてアニメーション化します。 それを行う別の方法。

現在選択されているセルインデックスの値を保持するintを作成します。

int currentSelection;

次に:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    int row = [indexPath row];
    selectedNumber = row;
    [tableView beginUpdates];
    [tableView endUpdates];
}

次に:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    if ([indexPath row] == currentSelection) {
        return  80;
    }
    else return 40;


}

tableView:cellForRowAtIndexPath:セルのタイプを変更したり、セルのxibファイルを読み込んだりすることもできます。

このように、currentSelectionは0から始まります。リストの最初のセル(インデックス0)がデフォルトで選択されないようにするには、調整が必要です。


私はbeginUpdates / endUpdatesを連続して呼び出すことについて、このようなことが何であるか分かりません。ちょうど-[UITableView reloadRowsAtIndexPaths:withAnimation:]使うことができます。 ここにはプロジェクトの例があります


私はちょうど少しハックでこの問題を解決しました:

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値に達するまでセルの成長をアニメーション化します.-)


選択された行のインデックスパスを取得します。 テーブルをリロードします。 UITableViewDelegateのheightForRowAtIndexPathメソッドでは、選択された行の高さを異なる高さに設定し、それ以外の場合は通常の行の高さを返します


BOOL flag;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    flag = !flag;
    [tableView beginUpdates];
    [tableView reloadRowsAtIndexPaths:@[indexPath] 
                     withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView endUpdates];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES == flag ? 20 : 40;
}






uitableview