問題タブ [nscollectionviewlayout]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
339 参照

macos - カスタム NSCollectionViewLayout サブクラスで無効化コンテキスト (forPreferredLayoutAttributes:withOriginalAttributes:) が呼び出されない

関連するサンプル プロジェクトへのリンク

説明

NSCollectionViewLayout自動レイアウトを使用してアイテムのサイズを決定するカスタム サブクラスを作成しようとしています。このレイアウトでは、アイテムが上から下に配置されます。すべてのアイテムは同じ幅を共有しますが、各アイテムの高さはそのコンテンツによって決定されます。UITableViewmacOSのレイアウトと考えてください。

予測

初期レイアウト属性は、レイアウトのprepare()メソッドで計算され、 を介してコレクション ビューに渡されます layoutAttributesForElements(in:)。これらの属性は、表示する必要がある項目を決定するためにコレクション ビューによって使用されます。これらのアイテムはコレクション ビューのデリゲートによって提供され、各アイテムのapply(_:)メソッドが呼び出されてそのビュー プロパティが設定されます。

次に、コレクション ビューはアイテムのpreferredLayoutAttributesFitting(_:)メソッドを呼び出して、そのコンテンツのフィッティング サイズを計算します。返された属性は、コレクション ビュー レイアウトのメソッドに渡されますshouldInvalidateLayout(forPreferredLayoutAttributes:withOriginalAttributes:)。ここで、レイアウトは、新しい属性に応じて調整を行う必要があるかどうかを判断し、そのブール値の決定をコレクション ビューに返します。

レイアウトを無効にする必要があるとレイアウトが判断した場合、コレクション ビューはそれinvalidationContext(forPreferredLayoutAttributes:withOriginalAttributes:)自体を更新する方法について、レイアウトから特定の情報を取得するために呼び出します。その後、コレクション ビューが を呼び出すinvalidationContext(forPreferredLayoutAttributes:withOriginalAttributes:)と、レイアウトはこれらの変更を適用できます。

このプロセスは、レイアウト アイテムごとshouldInvalidateLayout(forPreferredLayoutAttributes:withOriginalAttributes:)に返されるまで繰り返され、コレクション ビューがアイテムを画面に表示するように促されます。false

前提

ListLayoutサブクラスは、「推定された」ポイントの初期高さを持つNSCollectionViewLayoutそれぞれのレイアウト属性の初期セットを作成できます。Auto Layout を使用して各アイテムの実際の高さを決定することを想定しているため、この初期値は重要ではありません。NSCollectionViewItem10

その後、レイアウトは を介し​​てこれらの初期属性の正しいセットを提供できますlayoutAttributesForElements(in:)

TextFieldItemサブクラスには、とプロパティの両方に設定さNSCollectionViewItemれた単一のNSTextFieldインスタンスが含まれます。このビューのプロパティは false に設定されており、垂直方向のコンテンツの圧縮耐性の優先順位が必要です。項目のメソッドがオーバーライドされ、テキスト フィールドが指定された属性によって提供される幅に設定されます。項目のメソッドがオーバーライドされ、優先属性の高さがテキスト フィールドのプロパティと等しくなるように設定されます。viewtextFieldtranslatesAutoresizingMaskIntoConstraintsapply(_:)preferredMaxLayoutWidthpreferredLayoutAttributesFitting(_:)intrinsicContentSize

コレクション ビューにはTextFieldItem、複数行のテキストが入力されたインスタンスが用意されています。

それぞれのメソッドの後にそのメソッドが呼び出されTextFieldItem、続いてレイアウトのとメソッドの両方が呼び出されることが予想されます。preferredLayoutAttributesFitting(_:)apply(_:)shouldInvalidateLayout(forPreferredLayoutAttributes:withOriginalAttributes:)invalidationContext(forPreferredLayoutAttributes:withOriginalAttributes:)

ただし、 もpreferredLayoutAttributesFitting(_:)も も、プレイグラウンドの実行時に呼び出されるshouldInvalidateLayout(forPreferredLayoutAttributes:withOriginalAttributes:)ことはありません。invalidationContext(forPreferredLayoutAttributes:withOriginalAttributes:)その結果、各アイテムの高さは最初の「推定」高さのままになります。

各テキスト フィールドには 3 行のテキストが表示されますが、最初の行の上部しか表示されません。

質問

私が見逃しているものNSCollectionViewLayoutと自動レイアウトがあるに違いありませんが、それを示すドキュメントは見つかりませんでした。

コレクション ビューのライフサイクルのさまざまな時点でこれらのメソッドを手動で呼び出してみましたが、計算された属性を調整するためにレイアウトを正しくトリガーすることはできませんでした。

呼び出す必要があることを示すために、コレクション ビュー、そのレイアウト、またはアイテムに設定する必要があるプロパティはありますpreferredLayoutAttributesFitting(_:)か? 自動レイアウトはNSCollectionViewFlowLayoutとのサブクラスでのみサポートされNSCollectionViewGridLayoutますか? NSCollectionViewLayoutまたは、インスタンスのライフサイクルを誤解していますか?

0 投票する
1 に答える
246 参照

swift - 下から上への迅速な NSCollectionView フロー

私は、Swift で書かれた macOS 用のメッセージング クライアントに取り組んでいます。メッセージを表示するために、documentView として NSCollectionView と共に NSScrollView を使用します。現在、私は無限スクロールを実装していますが、今の問題は、collectionView がセルを一番上からロードし、それが NSCollectionView のデフォルトの動作であるということです。代わりに、一般的なメッセージング アプリケーションがメッセージを表示する方法と同じように、下部から開始して上に向かっていく必要があります。

私が試した解決策:

  • ビューが読み込まれるか、ユーザーが別の会話を選択するとすぐに、collectionView の一番下までスクロールします。このソリューションは目に見えてぎくしゃくしており、無限スクロールを本当に台無しにしています。
  • scrollView、scrollView の contentView、および collectionView で isFlipped 変数をオーバーライドします。これを行っても、どのビューにも目に見える影響はありません。
  • scrollView、collectionView、contentView、または collectionView セル全体を pi ラジアンで回転します。必死の対策として、scrollView 全体を回転させようとしましたが、それを行うことも、collectionView アイテムを回転させることもできませんでした。の線に沿って何かをしましたwantsLayer = true layer!.setAffineTransform(CGAffineTransform(rotationAngle: .pi)) updateLayer() setNeedsDisplay(frameRect)。これも目に見える影響はありません。

NSCollectionView を下から上に移動させる最善の方法は何ですか? ちなみにストーリーボードは使っていません。