SwiftUI - 取决于元素计数的可调整大小的列表高度 [英] SwiftUI - Resizable List height that dependent on an element count

查看:12
本文介绍了SwiftUI - 取决于元素计数的可调整大小的列表高度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在动态更改依赖于元素数量的列表高度时遇到了一些麻烦.

I have some troubles with dynamically changing List height that dependent on elements count.

我尝试了这个解决方案,但没有奏效.

I tried this solution but it didn't work.

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

推荐答案

TL;DR

这不是 SwiftUI 的设计者希望您使用列表的方式.要么你必须想出一个在未来可能会失效的hacky解决方案(见下文),要么使用列表以外的其他方法.

This is not how the designers of SwiftUI want you to use lists. Either you will have to come up with a hacky solution that will probably break in the future (see below), or use something other than a list.

背景

SwiftUI 往往有两种类型的视图

SwiftUI tends to have two types of Views

  1. 那些易于修改和组合的设计,为独特的外观和感觉提供无限的可定制性.
  2. 旨在为某种类型的交互提供标准、一致的感觉的那些,无论它们在什么应用中使用.

类型 1 的示例是文本.您可以更改字体大小、粗细、字体、颜色、背景、填充等.它是专为您修改而设计的.

An example of type 1 would be Text. You can change font size, weight, typeface, color, background, padding, etc. It is designed for you to modify it.

类型 2 的示例是列表.你不能直接控制行高,你不能改变视图周围的填充,你不能告诉它只显示这么多行等等.他们不希望它非常可定制,因为每个应用程序的列表的行为会有所不同,违背了标准控件的目的.

An example of type 2 would be List. You are not in direct control of row height, you can't change the padding around views, you can't tell it to show only so many rows, etc. They don't want it to be very customizable, because then each app's lists would behave differently, defeating the purpose of a standard control.

List 旨在用尽可能多的行填充整个父视图,即使它们是空的或仅部分在屏幕上(如果一次显示太多,则滚动).

您的问题

您遇到的问题是因为 List 的大小不会以任何方式影响其行的大小.SwiftUI 不在乎是否有太多或太少的行以适合您的首选大小;它会很高兴地根据内容调整其行的大小,即使这意味着它们没有全部显示或显示空行.

The problem you are having comes about because the size of the List does not affect the size of its rows in any way. SwiftUI doesn't care if there are too many or too few rows to fit in your preferred size; it will happily size its rows according to content, even if it means they don't all show or there are empty rows shown.

如果你真的需要根据父级的大小调整行的大小,你应该使用 VStack.如果需要滚动,则需要将 VStack 包裹在 ScrollView 中.

If you really need rows to resize according to the size of their parent, you should use a VStack. If it needs to scroll, you will need to wrap the VStack in a ScrollView.

hacky 解决方案

如果您仍然坚持使用列表,则必须执行以下操作:

If you still insist on using a list, you will have to do something like the following:

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 更改了 List 的外观(更改填充、最小行高等),您将必须记住返回并手动调整这些值.

The slider is there to show how the list row heights change with the height of their child view. You would have to manually pick listRowPadding and listRowMinHeight to get the appearance that best matches your expectation. If Apple ever changes how a List looks (changes padding, minimum row heights, etc.) you will have to remember to come back and adjust these values manually.

这篇关于SwiftUI - 取决于元素计数的可调整大小的列表高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆