根据元素数量动态更改列表高度会遇到一些麻烦。
我尝试了这种解决方案,但是没有用。
thisDSMatrix=newdsarray(1,2)
FirstCol={1,2,3}
FirstCol.name="FirstCol" //.name will pass the name into the matrix
thisDSMatrix.PutCell(FirstCol,1,1)
SecondCol={4,5,6}
SecondCol.name="SecondCol"
thisDSMatrix.PutCell(SecondCol,1,2)
Mcols=thisDSMatrix.ColCount //returns 2
Mrows=thisDSMatrix.RowCount //returns 1
thisDSMatrix.AddColumn("MyNewCol") //a column is added and thisDSMatrix.ColCount will now show 3
thisDSMatrix.PutCell({7,8,9},1,thisDSMatrix.ColCount)
return thisDSMatrix
答案 0 :(得分:7)
TL; DR
这不是SwiftUI的设计者希望您使用列表的方式。您将不得不提出一种可能会在将来中断的hacky解决方案(请参阅下文),或者使用列表以外的其他方法。
背景
SwiftUI倾向于具有两种视图类型
类型1的示例为文本。您可以更改字体大小,粗细,字体,颜色,背景,填充等。它是供您修改的。
类型2的一个示例是列表。您不能直接控制行高,不能更改视图周围的填充,也不能告诉它仅显示这么多行,等等。他们不希望它具有很高的可定制性,因为那样每个应用程序的列表的行为会有所不同,从而违反了标准控件的目的。
列表旨在将整个父视图填充为尽可能多的行,即使它们为空或仅部分显示在屏幕上(如果一次显示太多,也可以滚动)。
您的问题
您遇到的问题是因为List的大小不会以任何方式影响其行的大小。 SwiftUI不在乎是否有太多或太少的行适合您的首选大小;它将高兴地根据内容调整行的大小,即使这意味着行没有全部显示或显示的行为空。
如果您确实需要根据行的大小调整行的大小,则应使用VStack。如果需要滚动,则需要将VStack包裹在ScrollView中。
棘手的解决方案
如果您仍然坚持使用列表,则必须执行以下操作:
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)
}
}
}
滑块在那里显示列表行的高度如何随其子视图的高度而变化。您必须手动选择listRowPadding
和listRowMinHeight
才能获得最符合您期望的外观。如果Apple曾经更改过List的外观(更改了填充,最小行高等),则必须记住要手动返回并手动调整这些值。
答案 1 :(得分:1)
List
:如果您希望List
一次显示所有内容,则意味着您不需要回收功能(列表的关键功能),因此,您所需要的就是不使用{{ 1}}!相反,您可以直接使用List
,然后它将根据其内容调整大小:
ForEach
您可以根据需要更改所有大小和间距
答案 2 :(得分:0)
从 iOS 14 开始,您可以使用 LazyVStack
代替 List
。
列表似乎跨越整个父视图高度,与行高或计数无关。
LazyVStack {
ForEach(searchService.searchResult, id: \.self) { item in
Text(item)
.font(.custom("Avenir Next Regular", size: 12))
}
}.frame(height:
其他解决方案是基于.frame(height: )
或其他rowCount*rowHeight
在List上设置GeometryReader -> geometry.size.height