我正在创建一个聊天应用程序,我希望 ScrollView 的内容位于输入字段下方(向上滚动时)。我已经将 ScrollView 和输入字段放入 ZStack 中。 ScrollView 上的底部填充将内容放在上面,但我也希望滚动指示器随内容一起向上移动。
有什么方法可以更改滚动指示器的插入以匹配填充,或任何其他解决方法来实现我正在寻找的东西?
这是当前代码:
ZStack(alignment: .bottom) {
ScrollView {
ScrollViewReader { value in
VStack(spacing: 5) {
ForEach(MOCK_MESSAGES) {
mMessage in
MessageView(mMessage: mMessage)
}
.onAppear {
value.scrollTo(MOCK_MESSAGES.count - 1)
}
}
.padding(.top, 10)
.padding(.bottom, 40)
}
}
MessageInputView(messageText: $messageText)
}
总结:想法是让 ScrollView 位于输入视图上方,但向上滚动时将内容移动到输入视图下方。
iOS 15 / 斯威夫特 3
您可以使用
.safeAreaInset
而不是填充来完成此操作,然后它也会为您处理滚动指示器插入。
ScrollView {
ScrollViewReader { value in
VStack(spacing: 5) {
// stuff
}
}
}
.safeAreaInset(edge: .bottom) {
MessageInputView(messageText: $messageText)
}
注意:从 Xcode 13.1 开始,
.safeAreaInsets
似乎无法在 List
上工作。
更新:从 iOS 15.2 开始,
safeAreaInsets()
也适用于列表和表单。
iOS 14 / Swift 2 或使用列表
与 SwiftUI 中的许多事情一样,如果不修改底层 UIKit 组件,似乎就无法做到这一点。不过,对于这个问题有一个简单的解决方案,使用 Introspect 库:
ZStack(alignment: .bottom) {
ScrollView {
ScrollViewReader { value in
VStack(spacing: 5) {
// stuff
}
.padding(.top, 10)
.padding(.bottom, 40)
}
}
.introspectScrollView { sv in
sv.verticalScrollIndicatorInsets.top = 10
sv.verticalScrollIndicatorInsets.bottom = 40
}
MessageInputView(messageText: $messageText)
}
您也可以用
List
和 introspectTableView
来完成。
从 iOS 17 开始,ScrollViews 有一个修饰符来解决这个问题:
ScrollView {
}.contentMargins(.top, 100.0, for: .scrollIndicators)