web-dev-qa-db-ja.com

戻るときにUITableViewをリロードしますか?

UIViewControllerを含むトップレベルUITableViewがあります。最上位のUIViewControllerNavigationControllerをインスタンス化し、別のUIViewControllerNavigationControllerにプッシュします。 I.E.新しい2番目のビューにプッシュします。この2番目のビューの左上隅には通常の「戻る」ボタンがあり、トップレベルビューに戻ることができます。

2番目のビューからトップレベルビューに戻るときに、2番目のビューで生成されたデータを使用して、トップレベルでUITableViewを呼び出すことにより、トップレベルビューでcellForRowAtIndexPathを再描画できますか?もしそうなら、どのようにこれを行うのですか?

54
James Testa

あなたがする必要があるのはこれだけです(UITableViewを持つUIViewControllerで)。この時点でセルレベルで何が起こるか心配する必要はありません。

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.tableView reloadData]; // to reload selected cell
}

上記のコードをコントローラーに追加するだけで、2番目のビューから戻ったときに正しいことが起こることがわかります。 reloadDataの呼び出しは、モデルからセルを更新する必要があることをTable Viewに伝え、他のすべてはうまくいきます。

110
Zoran Simic

選択したセルのみをリロードする場合は、UITableViewControllerのカスタムサブクラスでviewWillAppear:を次のようにオーバーライドします。

- (void)viewWillAppear:(BOOL)animated
{
    NSIndexPath *selectedRowIndexPath = [self.tableView indexPathForSelectedRow];
    [super viewWillAppear:animated]; // clears selection
    if (selectedRowIndexPath) {
        [self.tableView reloadRowsAtIndexPaths:@[selectedRowIndexPath] withRowAnimation:UITableViewRowAnimationNone];
    }
}

注:clearsSelectionOnViewWillAppearYES(デフォルト)に設定したままにすると、superを呼び出す前に、選択した行のインデックスパスを取得する必要があります。

また、 @ ZoranSimicのソリューション は、[self.tablView reloadData]を呼び出すだけでも、コードが少なくて済み、効率的であるため受け入れられます。

最後に、おそらくテーブルビューのセルを、それらが表すモデルオブジェクトと同期を保つ最良の方法は、NSFetchedResultsControllerのようにし、キー値監視(KVO)やNSNotificationを使用して通知することです。モデルオブジェクトが変更され、対応するセルをリロードできるようになったときに、Table View Controller。 Table View Controllerは、viewDidLoadでモデルオブジェクトの変更の監視を開始し、deallocで監視を終了することができます(そして、 手動でself.view をアンロードします)。

12
ma11hew28

Zoran Simicの回答 に加えて、ここでSwiftコード:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    tableView.reloadData()
}
7
Michael Dorner

UINavigationControllerDelegateのメソッドを実装し、View Controllerをポップする際の更新のロジックを作成できます。

これを行う別の方法は、Table View ControllerにviewWillAppearのロジックを実装し、ポップされたView Controllerのデータに基づいて更新することです。

2番目のView Controllerから最初のView Controllerにデータを送信する必要がある場合、2番目のView Controllerは前のView Controllerの存在を「知らない」ことに注意してください。それは透明でなければなりません。プロトコルを実装して、2番目のView Controllerが最初のView Controllerにデータを送信するようにする必要があります。最初のView Controllerがデリゲートになり、2番目のView Controllerがデリゲートに情報を送信するため、この問題の3番目のオプションになります。受信したデータ。

5
vfn

viewWillAppearは、ビューが初めて表示されるたびに呼び出されます。ここに戻ったときにのみビューをリロードするための私のソリューションです

このViewControllerに初めてアクセスするとき、または戻るときに、ViewController.h fileに1つの変数を作成します

@property (nonatomic) BOOL isViewExist;

その後、viewWillAppear

-(void)viewWillAppear:(BOOL)animated{
    if(!self.isViewExist){
        self.isViewExist = YES; // check it is the first time you go to this ViewController -> don't reload anything
    }else{
        [self.tableView reloadData]; // to reload the tableview data
        // or your can refresh anything in your ViewController as you want
    }
}

この助けを願っています

3
Phan Van Linh

たぶん今助けることができます。

Swift 2 +の場合

ViewDidAppearメソッドで:

すべてのテーブルをリロードする場合:

tableView.reloadData()

選択したセルのみをリロードする場合。

let index = tableView.indexPathForSelectedRow
if (index != nil){
  self.tableView.reloadRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimation.Automatic)
}
1
Dasoga

Swift 3で更新

let index = tableView.indexPathForSelectedRow
    if (index != nil){
        self.tableView.reloadRows(at: [index!], with: UITableViewRowAnimation.automatic)
    }
0
Robin Thomson