61

現在、3 つのアプリを iOS 7 に更新しましたが、3 つすべてで、コードを共有していないにもかかわらず、ユーザーが (戻るボタンをタップするのではなく) スワイプしてナビゲーション コントローラーに戻ると、すぐに戻るという問題があります。 、セルは選択された状態のままになります。

3 つのアプリの場合、1 つはプログラムで作成されたカスタム セルを使用し、もう 1 つはストーリーボードで作成されたカスタム セルを使用し、3 つ目は同じくストーリーボードで UITableView の非常に基本的なサブクラスのデフォルト セルを使用します。3 つのケースすべてで、セル自体が選択解除されることはありません。ユーザーがゆっくりとスワイプするか、戻るボタンを押すと、通常どおり選択が解除されます。

これは私の iOS 7 アプリでのみ発生しており、iOS 7 用にアップグレードされた Apple 自身のアプリとサードパーティのアプリはすべて正常に動作しているように見えます (ただし、セルが選択解除される速度にはわずかな違いがあります)。

私が間違っていることがあるはずですが、何がわかりませんか?

4

16 に答える 16

19

Fabio の答えはうまく機能しますが、ユーザーが少しだけスワイプして気が変わった場合、適切な外観にはなりません。そのケースを正しく取得するには、選択したインデックス パスを保存し、必要に応じてリセットする必要があります。

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    self.savedSelectedIndexPath = nil;
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    if (self.savedSelectedIndexPath) {
        [self.tableView selectRowAtIndexPath:self.savedSelectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
    }
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.savedSelectedIndexPath = self.tableView.indexPathForSelectedRow;

    if (self.savedSelectedIndexPath) {
        [self.tableView deselectRowAtIndexPath:self.savedSelectedIndexPath animated:YES];
    }
}

UITableViewController を使用している場合は、組み込みのクリアを無効にしてください。

self.clearsSelectionOnViewWillAppear = NO;

そして、savedSelectedIndexPath のプロパティを追加します。

@property(strong, nonatomic) NSIndexPath *savedSelectedIndexPath;

いくつかの異なるクラスでこれを行う必要がある場合は、たとえば、この要点で行ったように、ヘルパーで分割するのが理にかなっています: https://gist.github.com/rhult/46ee6c4e8a862a8e66d4

于 2014-09-13T07:30:57.913 に答える
9

このソリューションは、遷移コーディネーター (ユーザー主導の VC 解除の場合) と共に行の選択解除をアニメーション化し、ユーザーが遷移をキャンセルした場合に選択を再適用します。SwiftのCaleb Davenportによるソリューションから適応。iOS 9 でのみテスト済み。ユーザー主導の (スワイプ) トランジションと古いスタイルの「戻る」ボタンのタップの両方で動作することがテスト済みです。

UITableViewControllerサブクラスでは:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    // Workaround. clearsSelectionOnViewWillAppear is unreliable for user-driven (swipe) VC dismiss
    NSIndexPath *indexPath = self.tableView.indexPathForSelectedRow;
    if (indexPath && self.transitionCoordinator) {
        [self.transitionCoordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
            [self.tableView deselectRowAtIndexPath:indexPath animated:animated];
        } completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
            if ([context isCancelled]) {
                [self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
            }
        }];
    }
}
于 2015-12-04T16:11:44.350 に答える
3

シンプルなスウィフト 3/4 回答:

override func viewWillAppear(_ animated: Bool) {
    if tableView.indexPathForSelectedRow != nil {
        self.tableView.deselectRow(at: tableView.indexPathForSelectedRow! as IndexPath, animated: true)
    }
}
于 2016-11-06T18:06:45.167 に答える
2

私は使用しています

[tableView deselectRowAtIndexPath:indexPath animated:YES];

メソッドの最後に

(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

このような:

(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

    //doing something according to selected cell...

    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}
于 2014-03-27T12:50:16.190 に答える
1

この問題に対する非常に簡単な解決策を見つけました。これは、デフォルトの動作を正常に機能させるだけです。deselectRowAtIndexPath結果として得られる視覚効果がわずかに異なるため、関連するソリューションには満足できませんでした。

この奇妙な動作を防ぐために必要なのは、ビューが表示されているときにテーブルをリロードすることだけです。

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self.tableView reloadData];
}
于 2014-12-20T00:39:01.243 に答える
0

Rhult のソリューションは、iOS 9.2 で完全に機能します。これは Swift での実装です。

MasterViewControllerIndexPath を保存する変数を宣言します。

var savedSelectedIndexPath: NSIndexPath?

次に、わかりやすくするためにコードを拡張機能に入れることができます。

extension MasterViewController {
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        self.savedSelectedIndexPath = nil
    }

    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        if let indexPath = self.savedSelectedIndexPath {
            self.tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: .None)
        }
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        self.savedSelectedIndexPath = tableView.indexPathForSelectedRow
        if let indexPath = self.savedSelectedIndexPath {
            self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
        }
    }
}
于 2015-12-29T10:14:42.720 に答える
0

スイフト用

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    guard let indexPath = tableView.indexPathForSelectedRow else{
        return
    }
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
于 2016-09-01T07:06:06.647 に答える