ScrollView 内的 ForEach 不占用整个宽度
ForEach inside ScrollView doesn't take whole width
我正在尝试使用 SwiftUI 重新创建我当前应用程序的 UI。而且这比我最初要困难得多。
我想实现像卡片一样的细胞,背后有一些背景。我发现 List
不支持,至少现在是这样。 List
非常有限 - 它不允许您删除单元格分隔符。
所以我搬到了ScrollView
里面的ForEach
。我想这不是应该在长桌生产中使用的东西,但现在应该可以使用。我遇到的问题是 ForeEach
视图没有占用 ScrollView
提供的所有宽度。我可以设置 .frame(...)
修饰符,但这需要硬编码宽度,我绝对不想这样做。
有什么想法可以强制 VStack
占据 ScrollView 的整个宽度吗?我尝试在没有 VStack
的情况下使用 ForeEach
,但它有同样的问题。看起来 ScrollView
(父视图)"tells" 它的子视图 (VStack) 它的框架小于实际 ScrollView
的框架。并基于该信息,子视图构建它们的布局和大小。
这是我目前的结果:
这是代码:
struct LandmarkList : View {
var body: some View {
NavigationView {
ScrollView() {
VStack {
Spacer().frame(height: 160)
ForEach(landmarkData) { landmark in
LandmarkRow(landmark: landmark).padding([.leading, .trailing], 16)
}
}.scaledToFill()
.background(Color.pink)
}
.background(Color.yellow)
.edgesIgnoringSafeArea(.all)
.navigationBarTitle(Text("Landmarks"))
}
}
}
struct LandmarkRow : View {
var landmark: Landmark
var body: some View {
HStack {
VStack(alignment: .leading) {
Text(landmark.name).font(.title)
Text("Subtitle")
.font(.callout)
.color(.gray)
}
Spacer()
Text("5 mi")
.font(.largeTitle)
}.frame(height: 80)
.padding()
.background(Color.white)
.cornerRadius(16)
.clipped()
.shadow(radius: 2)
}
}
我遇到了同样的问题,到目前为止我找到的唯一方法是修复 ScrollView
和内容视图 width,以便每个子视图您在内容视图中添加的内容将居中。
我创建了一个将宽度作为初始参数的简单包装器
struct CenteredList<Data: RandomAccessCollection, Content: View>: View where Data.Element: Identifiable {
public private(set) var width: Length
private var data: Data
private var contentBuilder: (Data.Element.IdentifiedValue) -> Content
init(
width: Length = UIScreen.main.bounds.width,
data: Data,
@ViewBuilder content: @escaping (Data.Element.IdentifiedValue) -> Content)
{
self.width = width
self.data = data
self.contentBuilder = content
}
var body: some View {
ScrollView {
VStack {
ForEach(data) { item in
return self.contentBuilder(item)
}.frame(width: width)
}
.frame(width: width)
}
.frame(width: width)
}
}
默认情况下它采用屏幕宽度 (UIScreen.main.bounds.width
)。
它就像 List
视图一样工作:
var body: some View {
TileList(data: 0...3) { index in
HStack {
Text("Hello world")
Text("#\(index)")
}
}
}
可能的答案可能只是将您的 scrollView 包装在 GeometryReader
中
就像这里的答案一样 ->
我正在尝试使用 SwiftUI 重新创建我当前应用程序的 UI。而且这比我最初要困难得多。
我想实现像卡片一样的细胞,背后有一些背景。我发现 List
不支持,至少现在是这样。 List
非常有限 - 它不允许您删除单元格分隔符。
所以我搬到了ScrollView
里面的ForEach
。我想这不是应该在长桌生产中使用的东西,但现在应该可以使用。我遇到的问题是 ForeEach
视图没有占用 ScrollView
提供的所有宽度。我可以设置 .frame(...)
修饰符,但这需要硬编码宽度,我绝对不想这样做。
有什么想法可以强制 VStack
占据 ScrollView 的整个宽度吗?我尝试在没有 VStack
的情况下使用 ForeEach
,但它有同样的问题。看起来 ScrollView
(父视图)"tells" 它的子视图 (VStack) 它的框架小于实际 ScrollView
的框架。并基于该信息,子视图构建它们的布局和大小。
这是我目前的结果:
这是代码:
struct LandmarkList : View {
var body: some View {
NavigationView {
ScrollView() {
VStack {
Spacer().frame(height: 160)
ForEach(landmarkData) { landmark in
LandmarkRow(landmark: landmark).padding([.leading, .trailing], 16)
}
}.scaledToFill()
.background(Color.pink)
}
.background(Color.yellow)
.edgesIgnoringSafeArea(.all)
.navigationBarTitle(Text("Landmarks"))
}
}
}
struct LandmarkRow : View {
var landmark: Landmark
var body: some View {
HStack {
VStack(alignment: .leading) {
Text(landmark.name).font(.title)
Text("Subtitle")
.font(.callout)
.color(.gray)
}
Spacer()
Text("5 mi")
.font(.largeTitle)
}.frame(height: 80)
.padding()
.background(Color.white)
.cornerRadius(16)
.clipped()
.shadow(radius: 2)
}
}
我遇到了同样的问题,到目前为止我找到的唯一方法是修复 ScrollView
和内容视图 width,以便每个子视图您在内容视图中添加的内容将居中。
我创建了一个将宽度作为初始参数的简单包装器
struct CenteredList<Data: RandomAccessCollection, Content: View>: View where Data.Element: Identifiable {
public private(set) var width: Length
private var data: Data
private var contentBuilder: (Data.Element.IdentifiedValue) -> Content
init(
width: Length = UIScreen.main.bounds.width,
data: Data,
@ViewBuilder content: @escaping (Data.Element.IdentifiedValue) -> Content)
{
self.width = width
self.data = data
self.contentBuilder = content
}
var body: some View {
ScrollView {
VStack {
ForEach(data) { item in
return self.contentBuilder(item)
}.frame(width: width)
}
.frame(width: width)
}
.frame(width: width)
}
}
默认情况下它采用屏幕宽度 (UIScreen.main.bounds.width
)。
它就像 List
视图一样工作:
var body: some View {
TileList(data: 0...3) { index in
HStack {
Text("Hello world")
Text("#\(index)")
}
}
}
可能的答案可能只是将您的 scrollView 包装在 GeometryReader
就像这里的答案一样 ->