*(在视频中,红色帧是用户看到的屏幕,我正在尝试可视化如何在视图之间导航)
我有一个时间表,其中包含垂直显示的“帖子”列表。我可以向上滑动以导航到下一篇文章(例如Tiktok视频,一次只显示1个“帖子”)。我可以垂直导航到下一个或上一个“帖子”。但每个“帖子”都包含多个视图。我可以在每个帖子中左右滑动以在这些视图之间导航(例如带有多个媒体的Insta)。每个视图都有不同的布局,但是所有视图都附在“帖子”上(例如,带有某些图像的主封面视图,然后:注释,详细信息,有关作者视图或更多内容)。 我应该为这种情况计划设计iOS应用的设计吗?我正在寻找建议,基本信息,某个方向 - 不是解决方案。 我找到用于垂直和水平刷新的解决方案,但是当您可以同时做两者时 - 游戏会改变...
首先,最重要的是,在开发中,您需要学习一项至关重要的技能,这将使您前进。该技能将大问题分解为小问题,并一次解决单个部分。例如,您的问题可以分为三个单独的组件。相同的主体可以帮助您定义方法,可重复使用的观点等。这个想法称为“单一责任主管”。这意味着每件事都只能做一件事,并且做一件事情真的很好。我可以使用此代码并将其重新使用以获取其他视图,并具有正确的更改。将其拆除
可滚动水平
可滚动的垂直旋转
EACHRow
Columns
因此,一旦打破了它,就需要一次解决一个问题。让我们从水平滚动开始。 Horizontal卷轴
这里是一个快速而肮脏的解决方案,可以解决水平滚动。这只是问题的一部分,但它使我们为解决其余的问题解决了基础。struct FirstView: View {
var body: some View {
ScrollView {
ForEach(0..<5) { index in
// NOTE: ANY VIEW can go in here, including collections :D
Rectangle()
.fill(.black)
.frame(width: UIScreen.main.bounds.size.width * 0.8,
height: UIScreen.main.bounds.size.height * 0.8)
}
}
}
}
ForEach
struct FirstView: View {
var body: some View {
ScrollView(.vertical) {
ForEach(0..<5) { _ in
// NOTE: Notice I just added another ScrollView and changed it's direction to horizontal.
ScrollView(.horizontal) {
LazyHStack {
ForEach(0..<5) { _ in
Rectangle()
.fill(.black)
.frame(width: UIScreen.main.bounds.size.width * 0.8,
height: UIScreen.main.bounds.size.height * 0.8)
}
}
}.frame(height: UIScreen.main.bounds.height)
}
}
}
}
告诉它可以水平布局,这是使它们朝那个方向铺设的要求。要启动它也有助于节省内存,因为只有在呈现时,才会加载视图。您也可以将外部包裹在
LazyHStack
中以产生相同的效果。使它接受不同的观点
LazyVStack
QOL
0..<5
ForEach
内部阵列可以包含您的[[<someObject>]]
Rows
Columns
var posts: [[Post]] = [[Post1, Post2, Post3],
[Post1, Post2, Post3]]
two rows
three columns
。您可以以这种方式将其计数插入您的ForEach
ForEach(0..<posts.count)
然后在内部
ForEach(0..<posts[index].count)
。
我希望这有所帮助,祝你好运!这里是一个从一种视图到另一种视图水平滑动的片段:
struct SwipingView: View {
@State var currentIndex: Int = 0
var body: some View {
ScrollViewReader { proxy in
ScrollView (.horizontal) {
HStack {
ForEach(0..<4) { index in
YourView(index: index)
.frame(width: UIScreen.main.bounds.width)
.id(index)
.onAppear {
currentIndex = index
}
.gesture(DragGesture(minimumDistance: 3.0, coordinateSpace: .local)
.onEnded { value in
switch(value.translation.width, value.translation.height) {
case (...0, -30...30):
let scrollTarget = index + 1
withAnimation {
proxy.scrollTo(scrollTarget, anchor: .leading)
}
case (0..., -30...30):
let scrollTarget = index - 1
withAnimation {
proxy.scrollTo(scrollTarget, anchor: .leading)
}
default :
break
}
})
}
}
}
}
}
}