我正在学习 iOS 版 SwiftUI,并且正在使用 XCode 13。如何"到底"左右滑动我的视口以更改同一"容器"或"集合"中的不同视图,同时允许上下滑动以更改该主视图?(...到下一个或上一个,如果它们在"提要"中。
这是我制作的一个视频,可以完美地可视化我的情况:https://youtu.be/6MhFQu0AZx4
*(在视频中,红框是用户看到的屏幕,我正在尝试可视化如何在视图之间导航)
我有一个时间线,上面垂直显示"帖子"列表。我可以上下滑动以导航到下一篇文章(与 TikTok 视频一样,一次只显示 1 个"帖子")。我可以垂直导航以转到下一个或上一个"帖子"。
但每个"帖子"都包含多个视图。我可以左右滑动以在每个帖子的视图之间导航(例如具有多个媒体的Insta)。每个视图都有不同的布局,但都附加到"帖子"(例如,带有一些图像的主封面视图,然后:评论、完整详细信息、关于作者视图或更多)。
在这种情况下,我应该如何"到底"计划iOS应用程序的设计?我正在寻找建议,基本信息,一些方向 - 不是解决方案。
我找到了垂直和水平滑动的解决方案,但是当您可以同时做到这两点时 - 游戏就会改变......
首先,在开发过程中,您需要学习一项关键技能,以推动您前进。这种技能是将大问题分解成小问题,一次处理一个单独的部分。例如,您的问题可以分解为三个单独的组件。相同的主体可以帮助您定义方法、可重用视图等。这个想法被称为"单一责任原则",这意味着每一件事都应该只做一件事,并且把那一件事做好。我可以采用此代码并将其重用于具有正确更改的其他视图。
分解它
- 可水平滚动
- 可垂直滚动
- 每个
Row
都需要支持多个Columns
因此,一旦分解了它,您需要一次处理一个问题。让我们从水平滚动开始。
水平滚动
这是一个快速而肮脏的解决方案来解决水平滚动问题。这只是问题的一部分,但它为我们解决其余问题奠定了基础。
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)
}
}
}
}
这里要注意的另一件事是,在我的内部 ForEach 循环中,我使用了一个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)
.
我希望这对一些小有帮助,祝你好运!