SwiftUI VStack 和 List 中被其他视图压缩的视图
Views compressed by other views in SwiftUI VStack and List
在我的 SwiftUI 应用程序中,我正在尝试实现一个类似于此的 UI:
我为类别 1 和类别 2 添加了两行。结果如下所示:
NavigationView {
VStack(alignment: .leading) {
CategoryRow(...)
CategoryRow(...)
Spacer()
}
.navigationBarTitle(Text("Featured"))
}
现在,当添加第三个类别的视图时 - VStack
带有图像 - 会发生以下情况:
这发生了,在我用 VStack
:
替换 Spacer()
之后
VStack(alignment: .leading) {
Text("Rivers")
.font(.headline)
ForEach(self.categories["Rivers"]!.identified(by: \.self)) { landmark in
landmark.image(forSize: 200)
}
}
我的CategoryRow
实现如下:
VStack(alignment: .leading) {
Text(title)
.font(.headline)
ScrollView {
HStack {
ForEach(landmarks) { landmark in
CategoryItem(landmark: landmark, isRounded: self.isRounded)
}
}
}
}
问题
看来浏览量被压缩了。我找不到任何压缩阻力或内容拥抱优先级修改器来解决这个问题。
我还尝试在 CategoryRow
.
上使用 .fixedSize()
和 .frame(width:height:)
如何防止压缩这些视图?
更新
我试过将整个外部堆栈视图嵌入到滚动视图中:
NavigationView {
ScrollView { // also tried List
VStack(alignment: .leading) {
CategoryRow(...)
CategoryRow(...)
ForEach(...) { landmark in
landmark.image(forSize: 200)
}
}
.navigationBarTitle(Text("Featured"))
}
}
...结果更糟:
我认为最顶层的视图(在 NavigationView 中)需要是一个列表,这样它才可以滚动:
NavigationView {
List {
...
或者使用 ScrollView。
堆栈自动适合屏幕。如果你想让你的内容超过这个,你会在 UIKit
中使用 ScrollView 或 TableView 等
编辑:
实际上,稍微谷歌一下就得到了这个结果,这似乎正是你正在做的:
https://developer.apple.com/tutorials/swiftui/composing-complex-interfaces
您在 VStack
中的所有视图似乎都不够 space,它压缩了其中的一些视图。您可以将其嵌入 ScrollView
NavigationView {
ScrollView {
VStack(alignment: .leading) {
CategoryRow(...)
CategoryRow(...)
/// you images and so on
}
}
}
您可以通过使用
来阻止 VStack 中的视图被压缩
.fixedSize(horizontal: false, vertical: true)
例如:
我有以下 VStack:
VStack(alignment: .leading){
ForEach(group.items) {
FeedCell(item: [=11=])
}
}
渲染压缩的 Text()
当我添加 .fixedSize(horizontal: false, vertical: true)
它不再压缩
VStack(alignment: .leading){
ForEach(group.items) {
FeedCell(item: [=12=])
.fixedSize(horizontal: false, vertical: true)
}
}
您可以尝试向您的第一个 VStack
添加一个 layoutPriority()
运算符。这是文档对方法的描述:
In a group of sibling views, raising a view’s layout priority encourages that view to shrink later when the group is shrunk and stretch sooner when the group is stretched.
所以有点像Autolayout中的内容抗压缩优先级。但是这里的默认值是0,所以你只需要将它设置为1就可以得到想要的效果,像这样:
VStack(alignment: .leading) {
CategoryRow(...)
CategoryRow(...)
Spacer()
}.layoutPriority(1)
VStack(alignment: .leading) {
...
}
希望有用!
struct ContentView1: View {
var body: some View {
NavigationView {
ScrollView {
VStack {
CategoryListView {
CategoryView()
}
CategoryListView {
SquareCategoryView()
}
CategoryListView {
RectangleCategoryView()
}
}
.padding()
}
.navigationTitle("Featured")
}
}
}
struct CategoryListView<Content>: View where Content: View {
private let viewSize: CGFloat = 150
var content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
var body: some View {
VStack {
HStack {
Text("Category name")
Spacer()
}
ScrollView(.horizontal, showsIndicators: false){
HStack {
ForEach(0..<10) { _ in
content()
}
}
}
}
}
}
struct ContentView1_Previews: PreviewProvider {
static var previews: some View {
ContentView1()
}
}
struct CategoryView: View {
private let viewSize: CGFloat = 150
var body: some View {
Circle()
.fill()
.foregroundColor(.blue)
.frame(width: viewSize, height: viewSize)
}
}
struct RectangleCategoryView: View {
private let viewSize: CGFloat = 350
var body: some View {
Rectangle()
.fill()
.foregroundColor(.blue)
.frame(width: viewSize, height: viewSize * 9 / 16)
}
}
struct SquareCategoryView: View {
private let viewSize: CGFloat = 150
var body: some View {
Rectangle()
.fill()
.foregroundColor(.blue)
.frame(width: viewSize, height: viewSize)
}
}
在我的 SwiftUI 应用程序中,我正在尝试实现一个类似于此的 UI:
我为类别 1 和类别 2 添加了两行。结果如下所示:
NavigationView {
VStack(alignment: .leading) {
CategoryRow(...)
CategoryRow(...)
Spacer()
}
.navigationBarTitle(Text("Featured"))
}
现在,当添加第三个类别的视图时 - VStack
带有图像 - 会发生以下情况:
这发生了,在我用 VStack
:
Spacer()
之后
VStack(alignment: .leading) {
Text("Rivers")
.font(.headline)
ForEach(self.categories["Rivers"]!.identified(by: \.self)) { landmark in
landmark.image(forSize: 200)
}
}
我的CategoryRow
实现如下:
VStack(alignment: .leading) {
Text(title)
.font(.headline)
ScrollView {
HStack {
ForEach(landmarks) { landmark in
CategoryItem(landmark: landmark, isRounded: self.isRounded)
}
}
}
}
问题
看来浏览量被压缩了。我找不到任何压缩阻力或内容拥抱优先级修改器来解决这个问题。
我还尝试在 CategoryRow
.
.fixedSize()
和 .frame(width:height:)
如何防止压缩这些视图?
更新
我试过将整个外部堆栈视图嵌入到滚动视图中:
NavigationView {
ScrollView { // also tried List
VStack(alignment: .leading) {
CategoryRow(...)
CategoryRow(...)
ForEach(...) { landmark in
landmark.image(forSize: 200)
}
}
.navigationBarTitle(Text("Featured"))
}
}
...结果更糟:
我认为最顶层的视图(在 NavigationView 中)需要是一个列表,这样它才可以滚动:
NavigationView {
List {
...
或者使用 ScrollView。
堆栈自动适合屏幕。如果你想让你的内容超过这个,你会在 UIKit
中使用 ScrollView 或 TableView 等编辑:
实际上,稍微谷歌一下就得到了这个结果,这似乎正是你正在做的: https://developer.apple.com/tutorials/swiftui/composing-complex-interfaces
您在 VStack
中的所有视图似乎都不够 space,它压缩了其中的一些视图。您可以将其嵌入 ScrollView
NavigationView {
ScrollView {
VStack(alignment: .leading) {
CategoryRow(...)
CategoryRow(...)
/// you images and so on
}
}
}
您可以通过使用
来阻止 VStack 中的视图被压缩 .fixedSize(horizontal: false, vertical: true)
例如: 我有以下 VStack:
VStack(alignment: .leading){
ForEach(group.items) {
FeedCell(item: [=11=])
}
}
渲染压缩的 Text()
当我添加 .fixedSize(horizontal: false, vertical: true) 它不再压缩
VStack(alignment: .leading){
ForEach(group.items) {
FeedCell(item: [=12=])
.fixedSize(horizontal: false, vertical: true)
}
}
您可以尝试向您的第一个 VStack
添加一个 layoutPriority()
运算符。这是文档对方法的描述:
In a group of sibling views, raising a view’s layout priority encourages that view to shrink later when the group is shrunk and stretch sooner when the group is stretched.
所以有点像Autolayout中的内容抗压缩优先级。但是这里的默认值是0,所以你只需要将它设置为1就可以得到想要的效果,像这样:
VStack(alignment: .leading) {
CategoryRow(...)
CategoryRow(...)
Spacer()
}.layoutPriority(1)
VStack(alignment: .leading) {
...
}
希望有用!
struct ContentView1: View {
var body: some View {
NavigationView {
ScrollView {
VStack {
CategoryListView {
CategoryView()
}
CategoryListView {
SquareCategoryView()
}
CategoryListView {
RectangleCategoryView()
}
}
.padding()
}
.navigationTitle("Featured")
}
}
}
struct CategoryListView<Content>: View where Content: View {
private let viewSize: CGFloat = 150
var content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
var body: some View {
VStack {
HStack {
Text("Category name")
Spacer()
}
ScrollView(.horizontal, showsIndicators: false){
HStack {
ForEach(0..<10) { _ in
content()
}
}
}
}
}
}
struct ContentView1_Previews: PreviewProvider {
static var previews: some View {
ContentView1()
}
}
struct CategoryView: View {
private let viewSize: CGFloat = 150
var body: some View {
Circle()
.fill()
.foregroundColor(.blue)
.frame(width: viewSize, height: viewSize)
}
}
struct RectangleCategoryView: View {
private let viewSize: CGFloat = 350
var body: some View {
Rectangle()
.fill()
.foregroundColor(.blue)
.frame(width: viewSize, height: viewSize * 9 / 16)
}
}
struct SquareCategoryView: View {
private let viewSize: CGFloat = 150
var body: some View {
Rectangle()
.fill()
.foregroundColor(.blue)
.frame(width: viewSize, height: viewSize)
}
}