2017-07-11 3 views
1

私はthis article about using custom UICollectionViewLayoutsを読んでおり、私が取り組んでいるプロジェクトにそのアイデアを取り入そうとしています。`invalidateLayout`を使わずにUICollectionViewLayout(iOS 9をサポート)でセルを自動サイズ調整する

以前は、プロトタイプのセルをデキューしてセルのサイズを決定し、サイズを尋ねることによって、セルのサイズを決定する醜い関数を持つUICollectionViewFlowLayoutサブクラスを使用していました。

言うまでもなく、私はこれを行うより良い方法を探したかったのです。

私が抱えている問題は、セルの初期レイアウトです。私たちが使用する多くの細胞には、1つまたは2つのラベルが含まれており、多くのテキストを含み、折り返す必要があります。 Datasource.swiftファイルに自動的にサイズ複数行のラベルを示していますが、ラインがこれを強制的にテキストに侵入挿入された遊び場があるリンク先の記事...

で...

lazy private var values: [String] = { 
    return (0...255).map { 
     _ in 
     switch arc4random_uniform(3) { 
     case 0: return "Hello" 
     case 1: return "Hello\nGoodbye" 
     default: return "Hello\nGoodbye\nAu revoir" 
     } 
    } 
}() 

しかし、これらを自然長さの異なる長さの文字列に変更すると、例が分かりません。最初のレイアウトはラベル内に1行しか表示されません。しかし、スクロールするとラベルが正しく表示されます。

Autosizingファイルにlayout.invalidateLayout()という行を追加することでこれを修正することができます。

今、私は自分のプロジェクトで同じことをしようとしています。 layout.invalidateLayout()の使用は、viewDidAppear機能に入れた場合にのみビューコントローラで機能します。つまり、トランジションが間違っていて、正しいレイアウトに「ジャンプ」した後、ジャンプするのが面倒なことになります。しかし、私はinvalidateLayoutを使用して全体のアプローチが壊れているように感じる。

最初のレイアウトでこれを壊さない方法がありますか?またはintelligentlyセルの初期レイアウトを無効にするには?

GitHub projectは、私が抱えている問題を示しています。現在、コードのために正しくレイアウトされています...

override func viewDidAppear(_ animated: Bool) { 
    super.viewDidAppear(animated) 

    // This invalidation "fixes" the layout but causes a jump in the UI 
    collectionView?.collectionViewLayout.invalidateLayout() 
} 

理想的には私はこれを削除し、レイアウトは "仕事"です。

答えて

1

ここで問題となるのは、初期パスでは、セルによって返された優先レイアウト属性が正しくないことです。一見無制限の幅に基づいてラベルのサイズを調整するので、1行に収まるようになります。

セルにsetUp()方法「修正」の問題を、この行を追加:

label.preferredMaxLayoutWidth = self.bounds.width - (contentView.layoutMargins.left + contentView.layoutMargins.right) 

それは私がより良い方法があると確信している、少し汚いです。

EDIT

OK、ここでのより良い方法です。これによりレイアウトからの元の推定フレームにビューが強制され、ALエンジンはセルのサイズを適切に調整できます。私はストーリーボードで作成したセルは、同じ問題を抱えていたかどうかを確認するために興味があると思い

private var isInitialLayout = true 

public override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes { 
    if isInitialLayout { 
     self.contentView.layoutIfNeeded() 
     isInitialLayout = false 
    } 
    return super.preferredLayoutAttributesFitting(layoutAttributes) 
} 
+0

、うんそこ – jrturton

+0

で起こっ自動な幅のものがありますから、私はしませんでした:あなたの細胞サブクラスでこれを行いますAutoLayoutを使用してセルをレイアウトする全体的な点を打破するので、これを使用したいと考えています。また、セルはコレクション時の相対幅を(ビルド時に)知る必要があります。あなたが多分エッジのインセットまたは列の数を変更する柔軟なレイアウトを持っているなら、そのレイアウト幅を定義することはできません。 – Fogmeister

+0

すべての有効なポイント – jrturton

関連する問題