iOS11で奇妙なuitableviewの動作。 セルがナビゲーションプッシュアニメーションでスクロールアップする


Answers

Maggyの答えに加えて

目的 - C

if (@available(iOS 11.0, *)) {
    scrollViewForView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}

この問題は、iOS 11のバグによって発生しました。ここでは、ビューコントローラのビューのsafeAreaInsetsがナビゲーション遷移中に正しく設定されていないため、iOS 11.2で修正する必要があります。 contentInsetAdjustmentBehavior.never設定することは、他の望ましくない副作用を持つ可能性があるため、大きな回避策ではありません。 回避策を使用する場合は、iOSバージョンが11.2以上であることを確認してください

- スマイリーボルグ(ソフトウェアエンジニア、アップル)

Question

私は最近、いくつかのコードを新しいiOS 11 beta 5 SDKに移行しました。

私は今、UITableViewから非常に混乱した動作をします。 テーブルビューそのものはそれほど素晴らしいものではありません。 私はカスタムセルを持っていますが、ほとんどの場合、それはちょうどその高さです。

ViewViewでビューコントローラをプッシュすると、セルが「スクロールアップ」(またはテーブルビューフレーム全体が変更される可能性があります)およびプッシュ/ポップナビゲーションアニメーションに沿った追加のアニメーションが表示されます。 gifをご覧ください:

私は手動でloadViewメソッドでloadViewを作成し、自動レイアウト制約をtableviewのスーパービューの先頭、末尾、上、下に等しくなるように設定します。 スーパービューはView Controllerのルートビューです。

コントローラをプッシュするView Controllerは、非常に標準的ですself.navigationController?.pushViewController(notifVC, animated: true)

同じコードは、iOS 10で正常な動作を提供します。

あなたは何が間違っているのかを指摘してください。

編集:私は非常にシンプルなtableviewコントローラを作って、私はそこに同じ動作を再現することができます。 コード:

class VerySimpleTableViewController : UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
    }


    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 4
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

        cell.textLabel?.text = String(indexPath.row)
        cell.accessoryType = .disclosureIndicator

        return cell
    }


    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)

        let vc = VerySimpleTableViewController.init(style: .grouped)

        self.navigationController?.pushViewController(vc, animated: true)
    }
}

編集2:UINavigationBarのカスタマイズまで問題を絞り込むことができました。 私はこのようなカスタマイズがあります:

rootNavController.navigationBar.setBackgroundImage(createFilledImage(withColor: .white, size: 1), for: .default)

createFilledImageは、指定されたサイズと色で正方形のイメージを作成します。

私がこの行をコメントアウトすると、私は正常な動作に戻ります。

私はこの問題についてどんな考えにも感謝します。




これは意図した動作よりもバグのようです。 ナビゲーションバーが半透明でない場合、または背景画像が設定されている場合に発生します。

contentInsetAdjustmentBehaviorを.neverに設定しただけでは、コンテンツセットはiPhone Xでは正しく設定されません。たとえば、スクロールバーの下のコンテンツが下部に表示されます。

2つのことをする必要があります:
1. push / popでアニメーションをスクロールしないようにする
2. iPhone Xのために必要なので、自動動作を維持します。これがなければ、例えば肖像画では、コンテンツは下のスクロールバーの下に移動します。

新しいシンプルなソリューション: XIBで:スーパービューと高さが0に設定された先頭、先頭、末尾にメインビューの上に新しいUIViewを追加するだけです。他のサブビューなどに接続する必要はありません。

古い解決策:

注意:UIScrollViewをランドスケープモードで使用している場合、水平インセットを正しく設定しない(別のバグ?)ので、scrollViewの先行/後尾をIBのsafeAreaInsetsに固定する必要があります。

注2:以下の解決策では、tableViewが下にスクロールされ、コントローラとポップバックを押すと、もはや底面には表示されないという問題もあります。

override func viewDidLoad()
{
    super.viewDidLoad()

    // This parts gets rid of animation when pushing
    if #available(iOS 11, *)
    {
        self.tableView.contentInsetAdjustmentBehavior = .never
    }
}

override func viewDidDisappear(_ animated: Bool)
{
    super.viewDidDisappear(animated)
    // This parts gets rid of animation when popping
    if #available(iOS 11, *)
    {
        self.tableView.contentInsetAdjustmentBehavior = .never
    }
}

override func viewDidAppear(_ animated: Bool)
{
    super.viewDidAppear(animated)
    // This parts sets correct behaviour(insets are correct on iPhone X)
    if #available(iOS 11, *)
    {
        self.tableView.contentInsetAdjustmentBehavior = .automatic
    }
}



このコードを削除する

self.edgesForExtendedLayout = UIRectEdgeNone



また、タブバーを使用する場合、コレクションビューの下部のコンテンツインセットはゼロになります。 そのためには、以下のコードをviewDidAppearに入れてください:

if #available(iOS 11, *) {
    tableView.contentInset = self.collectionView.safeAreaInsets
}



私の場合、これはうまくいきました(viewDidLoadに入れてください):

self.navigationController.navigationBar.translucent = YES;





Links