web-dev-qa-db-ja.com

Swiftui - 要素数に依存するサイズのリストの高さ

要素数に依存するリストの高さを動的に変更することでいくつかの問題があります。

私はこの解決策を試してみましたがそれはうまくいきませんでした。

List {
    ForEach(searchService.searchResult, id: \.self) { item in
        Text(item)
        .font(.custom("Avenir Next Regular", size: 12))
    }
}.frame(height: CGFloat(searchService.searchResult.count * 20))
 _
6
Abjox

tl; dr

これは、Swiffの設計者がリストを使用してほしいのでしょうか。あなたはおそらく将来壊れるようなハッキーな解決策を思い付く必要があります(下記参照)、またはリスト以外のものを使用してください。

背景

Swiffiiは2種類の景色を浴びる傾向があります

  1. 簡単に変更可能で構成可能になるように設計されたもので、ユニークなルックアンドフィールのための無制限のカスタマイズ可能性を提供します。
  2. それらが使用されているアプリケーションに関係なく、ある種のインタラクションに標準的で一貫性のある感触を提供するように設計されたもの。

タイプ1の例はテキストになります。フォントサイズ、重量、書体、色、背景、パディングなどを変更できます。変更するために設計されています。

タイプ2の例が一覧表示されます。あなたは行の高さを直接管理していません、あなたはビューの周りのパディングを変えることはできません、あなたはそれほど多くの行だけを表示することはできません。彼らはそれを非常にカスタマイズ可能にすることを望まない、それから各アプリのためリストは違法に振る舞い、標準管理の目的を破っていきます。

リストは、空になっているか、または部分的にのみ部分的にのみ部分的にのみ、または部分的にのみ(一度に表示するには多すぎる場合はスクロールしてください)。

あなたの問題

リストのサイズがその行のサイズに影響を与えないために、あなたが持っている問題は、何らかの方法で行われています。 Swiffiiはあなたの好みのサイズに合うために多すぎる行が多すぎるかどうかに気にしません。たとえそれがすべて表示されないことを意味していても、コンテンツに従ってその行を楽しくサイズにします。

自分の親のサイズに応じて行のサイズ変更に行が本当に必要な場合は、VSTACKを使用する必要があります。スクロールする必要がある場合は、ScrollViewでvStackをラップする必要があります。

ハッキーな解決策

それでもリストの使用を主張する場合は、次のようなことをする必要があります。

struct ContentView: View {

    @State private var textHeight: Double = 20
    let listRowPadding: Double = 5 // This is a guess
    let listRowMinHeight: Double = 45 // This is a guess
    var listRowHeight: Double {
        max(listRowMinHeight, textHeight + 2 * listRowPadding)
    }

    var strings: [String] = ["One", "Two", "Three"]

    var body: some View {
        VStack {
            HStack {
                Text(String(format: "%2.0f", textHeight as Double))
                Slider(value: $textHeight, in: 20...60)
            }
                VStack(spacing: 0) {
                    Color.red
                    List {
                        ForEach(strings, id: \.self) { item in
                            Text(item)
                                .font(.custom("Avenir Next Regular", size: 12))
                                .frame(height: CGFloat(self.textHeight))
                                .background(Color(white: 0.5))
                        }
                    }
                    // Comment out the following line to see how List is expected to work
                    .frame(height: CGFloat(strings.count) * CGFloat(self.listRowHeight))
                    Color.red
            }.layoutPriority(1)
        }
    }
}
 _

スライダは、リストの行の高さが子ビューの高さでどのように変わるかを示すためのものです。あなたはあなたの期待に最も適した外観を得るために手動でlistRowPaddinglistRowMinHeightを選ぶ必要があります。 Apple]の場合は、リストの外観(パディング、最小行の高さなど)を変更する必要があることを忘れずに手動で調整する必要があります。

7
John M.

セルフサイズList

Listがすべてのコンテンツを一度に表示する場合は、リサイクル機能(リストの重要な機能)を必要としないことを意味しますので、必要なのはList!代わりに、ForEachを直接使用することができますから、それはその内容に基づいてサイズを大きくします。

ForEach(searchService.searchResult, id: \.self) { item in
    VStack(alignment: .leading) {
        Text(item).font(.custom("Avenir Next Regular", size: 12))
        Divider()
    }.padding(.horizontal, 8)
}
 _

あなたはあなたのニーズに応じてすべてのサイズと間隔を変更することができます

1