UITableViewの単一のUITableViewCellを更新することは可能ですか?


182

s UITableViewを使用するカスタムがありますUITableViewCell。それぞれUITableViewCellに2つのボタンがあります。これらのボタンをクリックするとUIImageView、セル内の画像が変更されます。

各セルを個別に更新して新しい画像を表示することはできますか?どんな助けでもありがたいです。

回答:


323

セルのindexPathを取得したら、次のようなことができます。

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPathOfYourCell, nil] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates]; 

Xcode 4.6以降:

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[indexPathOfYourCell] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates]; 

もちろん好きなものをアニメーション効果として設定できます。


4
ここでは気にしないでください。もちろん、単一のセルのみを更新する場合は、[NSArray arrayWithObject:]代わりに使用することをお勧めします。
Leo Cassarani、2011

57
また、この状況では、beginUpdatesおよびendUpdatesは不要です。
kubi

2
OPは何をアニメーションされていないので、開始/ endupdatesコールする必要はありません
kubi

2
メソッドが最後のパブリックXcodeバージョンで非推奨と表示れない限り、すべてのiOSバージョンで問題ありません。
AlejandroIván2015

1
@Supertecnoboffはtrueですが、ある時点で置き換えられるか、その動作が変更されます。廃止はできるだけ早く処理することをお勧めします
AlejandroIván

34

とだけ呼ん-[UITableView cellForRowAtIndexPath:]でみましたが、うまくいきませんでした。しかし、例えば私にとっては次のように動作します。I allocとのためのタイトなメモリ管理。releaseNSArray

- (void)reloadRow0Section0 {
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    NSArray *indexPaths = [[NSArray alloc] initWithObjects:indexPath, nil];
    [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
    [indexPaths release];
}

ここに[indexPaths release]は必要ですか?オブジェクトを自分で割り当てた場合にのみ必要だと思いました。
powerj1984

4
彼はindexPaths配列を割り当てました。しかし、より良い質問は、彼が「厳格なメモリ管理」が必要であると考える理由です。自動解放はここで完全にうまく機能します。
John Cromartie 2013年

22

迅速:

func updateCell(path:Int){
    let indexPath = NSIndexPath(forRow: path, inSection: 1)

    tableView.beginUpdates()
    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) //try other animations
    tableView.endUpdates()
}

このメソッドを呼び出す場所は?
Master AgentX

18

reloadRowsAtIndexPaths:結構ですが、UITableViewDelegateメソッドを強制的に起動します。

私が想像できる最も簡単なアプローチは次のとおりです。

UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
[self configureCell:cell forIndexPath:indexPath];

非UIスレッドでは機能しないので、メインスレッドで実装を呼び出すことが重要です(/ と同じストーリー)。追加すると役立つ場合があります。configureCell:reloadDatareloadRowsAtIndexPaths:

dispatch_async(dispatch_get_main_queue(), ^
{
    [self configureCell:cell forIndexPath:indexPath];
});

現在表示されているビューの外で行われる作業を回避することも価値があります。

BOOL cellIsVisible = [[self.tableView indexPathsForVisibleRows] indexOfObject:indexPath] != NSNotFound;
if (cellIsVisible)
{
    ....
}

なぜデリゲートを呼び出さないのですか?
kernix

reloadRowsAtIndexPaths:またはreloadDataメソッドとは対照的に、テーブルビューを強制的に最上部までスクロールしないので、これは最良のアプローチです。
ZviBar 2015

私はこれを行い、最終的には電池がリサイクルされたという事実に捕まりました
Traveling Man

16

カスタムTableViewCellsを使用している場合、一般的な

[self.tableView reloadData];    

現在のビューを離れない限り、この質問に効果的に回答しませんを終了して戻ってこ。最初の答えもどちらもしません。

ビューを切り替えずに最初のテーブルビューセルを正常に再読み込みするには、次のコードを使用します。

//For iOS 5 and later
- (void)reloadTopCell {
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    NSArray *indexPaths = [[NSArray alloc] initWithObjects:indexPath, nil];
    [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
}

上記のメソッドを呼び出す次の更新メソッドを挿入して、トップセルのみ(または必要に応じてテーブルビュー全体)をカスタムで再読み込みできるようにします。

- (void)refresh:(UIRefreshControl *)refreshControl {
    //call to the method which will perform the function
    [self reloadTopCell];

    //finish refreshing 
    [refreshControl endRefreshing];
}

これで並べ替えが完了したのでviewDidLoad、次のコードを追加します。

//refresh table view
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];

[refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];

[self.tableView addSubview:refreshControl];

これで、最上位のセルを再読み込みするカスタムのテーブル更新機能があります。テーブル全体をリロードするには、

[self.tableView reloadData]; 新しい更新メソッドに。

ビューを切り替えるたびにデータを再ロードする場合は、メソッドを実装します。

//ensure that it reloads the table view data when switching to this view
- (void) viewWillAppear:(BOOL)animated {
    [self.tableView reloadData];
}

6

スウィフト3:

tableView.beginUpdates()
tableView.reloadRows(at: [indexPath], with: .automatic)
tableView.endUpdates()

4

iOS 6の新しいリテラル構文でこれらの回答を少し更新するだけです。単一のオブジェクトにはPaths = @ [indexPath]を、複数のオブジェクトにはPaths = @ [indexPath1、indexPath2、...]を使用できます。

個人的には、配列と辞書のリテラル構文が非常に便利で時間を大幅に節約できることがわかりました。一つには、それは単に読みやすいだけです。また、常に個人的なバガブーであったマルチオブジェクトリストの最後にnilを挿入する必要がなくなります。私たちは皆、傾斜させる風車を持っています、そうですか?;-)

これをミックスに投入すると思いました。それが役に立てば幸い。


グレッグと言って、実際にその構文の例は何ですか?ありがとう!
Fattie 2013年

3

Swift 5のUITableView拡張機能は次のとおりです。

import UIKit

extension UITableView
{    
    func updateRow(row: Int, section: Int = 0)
    {
        let indexPath = IndexPath(row: row, section: section)

        self.beginUpdates()
        self.reloadRows(at: [indexPath as IndexPath], with: UITableView.RowAnimation.automatic)
        self.endUpdates()
    }

}

と電話する

self.tableView.updateRow(row: 1)

0

アップグレードセルが必要ですが、キーボードを閉じます。私が使うなら

let indexPath = NSIndexPath(forRow: path, inSection: 1)
tableView.beginUpdates()
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) //try other animations
tableView.endUpdates()

キーボードが消える

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.