web-dev-qa-db-ja.com

向きを変更した後のUITableViewレイアウトのバグ

自動レイアウト(制約)ベースのアプリケーションがあり、向きを変更した後、テーブルビューに問題があることに気付きました。再現手順は次のとおりです(私は非常に基本的な再現アプリを持っています-テーブルビューと新しいアイテムを追加する追加ボタンがあります)。

  1. アプリケーションを横向きモードに回転して、テーブルビューが横向きになるようにします。
  2. テーブルビューにアイテムを追加します。以下を参照してください 1
  3. 回転して縦向きに戻すと、テーブルビューが水平パンに浮かびます(スクロールビューアのコンテンツサイズが横向きであるかのように)。[2]を参照してください。

1 追加するコード

- (IBAction)onAdd:(id)sender {
    count ++;
    [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:count-1 inSection:0]] withRowAnimation:UITableViewRowAnimationBottom];
}

[2]フローティングテーブルビュー

enter image description here

この問題を回避する方法についてのアイデアはありますか?また、これが既知の問題なのか、Appleに報告すべきものなのかをどうやって見分けることができますか?

18
ConfusedNoob

これはバグだと思います。プロジェクトを自動レイアウトから変換し、適切なサイズ変更マスクを設定すると、すべてが正常に機能します。特に、バグをうまく再現する単純なサンプルプロジェクトがあるため、バグを報告する必要があります。

あなたのケースで起こっていることは、あなたが疑ったとおりです-ビュー自体が縦向きにサイズ変更されていても、スクロールビューのコンテンツビューは横向きの幅のままなので、突然水平方向にドラッグできるようになります。

幸いなことに、かなり簡単な回避策があります。 setNeedsLayoutまたはsetNeedsUpdateConstraintsのさまざまな組み合わせを試しましたが、成功しませんでしたが、次の2つのソリューションのいずれかを実装できます。

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [self.tableView beginUpdates];
    [self.tableView endUpdates];
}

または、

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    CGSize contentSize = self.tableView.contentSize;
    contentSize.width = self.tableView.bounds.size.width;
    self.tableView.contentSize = contentSize;
}
30
jrturton

上記の答えはほとんどの場合機能しますが、常に機能するとは限りません。最も堅牢なソリューションは、UITableViewをサブクラス化し、layoutSubviews内でcontentSizeを設定することです。

- (void)layoutSubviews
{
    [super layoutSubviews];

    CGSize contentSize = self.contentSize;
    contentSize.width  = self.bounds.size.width;
    self.contentSize   = contentSize;
}
3
phatmann