XCode 版本 12.4 (12D4e)
每次在 ScrollView 中实现 Lazy 堆栈时,我都会遇到这个问题:
LazyHStack到水平ScrollView或 aLazyVStack到垂直ScrollView场景 1 - 将滚动视图拉出边界(就像拉动以刷新)
预期行为:当滚动视图停留在您的手指下时,它的行为与预期一致
观察到的行为:它口吃和跳跃
场景 2 - 快速滚动到边缘,使其必须弹跳
预期行为:弹跳顺畅
观察到的行为:到达边缘时停止并抖动,但不反弹
我的理论 我的理论是,由于使用了 Lazy 堆栈,当视图离开屏幕时,它会从视图层次结构中移除,从而造成卡顿。
我想知道有没有其他人遇到过这种情况?这是 SwiftUI 中的错误吗?几个月来,我已经在不同的项目中可靠地重现了这一点,但最终还是不使用我希望可以使用的 Lazy 堆栈。
示例代码
ScrollView {
LazyVStack {
ForEach(viewModel.items) { items in
SomeView(viewModel: .init(context: viewModel.context, item: item))
}
}
Run Code Online (Sandbox Code Playgroud)
注意:口吃只发生在滚动视图的顶部
** 2021 年 7 月 10 日更新**
这仍然发生在 iOS 15 版本 13.0 测试版 (13A5155e) 中。
在下面的视频中,注意滚动条的行为和到达底部时的卡顿:
所以我尝试使用 ScrollViewReader 以编程方式滚动水平滚动视图。我认为它会像 UIKit 中带有 .centeredHorizontally 的scrollToItem一样工作,并且在大多数情况下都是如此,但是滚动视图中的最后几个元素被强制滚动到屏幕中心,尽管事实上滚动视图是“通常无法滚动那么远(至少在释放拖动后不会快速返回)。这最终会在屏幕的后半部分创建空白区域。
我已经看到了一些关于此的其他问题,似乎普遍的意见是这不是一个错误?一方面,我想我们告诉滚动视图将项目居中,而它正是这样做的——所以,这不是一个错误吗?另一方面,类似的功能在 UIKit 中并不是这样工作的。此外,这种行为仅发生在滚动视图的尾端!如果这是预期的行为,我希望使用 .center 锚点滚动到滚动视图中的第一个元素将迫使其进入屏幕中心并留下前导空白,但这不会发生。
有一个优雅的解决方案吗?或者我们是否必须计算元素的宽度 + 间距,并根据屏幕宽度计算出是否应该锚定 .center 或只是滚动到带有锚点 .trailing 的最后一个元素,以便复制 UIKit 行为?
我正在尝试创建一个像苹果的一些应用程序一样的轮播。具有TabView分页样式,但它不会“查看”上一个和下一个元素。不会ScrollView(.horizontal)折断。我希望将这两种行为结合起来,而无需重写客户视图。这两种观点中的任何一种都可能发生这样的事情吗:
这就是我正在尝试的:
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .center, spacing: 0) {
GroupBox(label: Text("This is the title 1")) {
Label("Some item 1", systemImage: "checkmark.circle.fill")
Label("Some item 2", systemImage: "checkmark.circle.fill")
Label("Some item 3", systemImage: "checkmark.circle.fill")
Label("Some item 4", systemImage: "checkmark.circle.fill")
}
.padding()
GroupBox(label: Text("This is the title 2")) {
Label("Some item 1", systemImage: "checkmark.circle.fill")
Label("Some item 2", systemImage: "checkmark.circle.fill")
Label("Some item 3", systemImage: "checkmark.circle.fill")
Label("Some item 4", systemImage: "checkmark.circle.fill")
}
.padding()
GroupBox(label: Text("This is the title 3")) { …Run Code Online (Sandbox Code Playgroud) ScrollView当内容足够小以至于不需要滚动时,我试图让 a 中的内容居中,而是与顶部对齐。这是一个错误还是我遗漏了添加一些东西?使用Xcode11.4 (11E146)
@State private var count : Int = 100
var body : some View {
// VStack {
ScrollView {
VStack {
Button(action: {
if self.count > 99 {
self.count = 5
} else {
self.count = 100
}
}) {
Text("CLICK")
}
ForEach(0...count, id: \.self) { no in
Text("entry: \(no)")
}
}
.padding(8)
.border(Color.red)
.frame(alignment: .center)
}
.border(Color.blue)
.padding(8)
// }
}
Run Code Online (Sandbox Code Playgroud)
我正在创建一个应用程序,在分页视图中呈现数据,每个视图都包含一个由scrollView启用的垂直可滚动列表。我还使用scrollViewReader 能够以编程方式滚动到列表中的特定位置。在大多数情况下,这工作正常,但是当我以编程方式滚动到列表底部(到最后一项)时,它滚动得太远。
我隔离了一个可重复的案例:
ScrollView(.vertical, showsIndicators: false) {
ScrollViewReader { scrollView in
LazyVStack(alignment: .leading) {
ForEach((1..<100) , id:\.self) { key in
Text("Hello \(key)")
}
}
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
withAnimation {
scrollView.scrollTo(99, anchor: .center)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您在 iPhone 12 模拟器等设备上运行此命令,您将看到列表中的最后一项位于屏幕中间。如果您手动滚动并释放,列表将“落下”到屏幕底部,这是我希望列表所在的位置,即使我使用 滚动到最后一个项目.anchor: .center。
有办法解决这种行为吗?
编辑:意识到我还不够清楚。只要我的视图中有更多可滚动内容,我希望锚点为 .center。但是,当我到达列表底部时,我希望滚动视图足够智能,知道无法再滚动。现在,它的滚动次数比手动滚动的滚动次数要多。
我做了一个自定义导航栏。并在其下方添加了滚动视图。我遇到的问题是,当我向下滚动时,滚动视图内的数据会出现在导航栏上。这是屏幕截图:
我的代码是:
struct NewsfeedView: View {
var newsfeedModel: [NewsFeedData]
var body: some View {
VStack {
CustomNavBar(navTitle: "Newsfeed")
ScrollView {
LazyVStack{
ForEach(newsfeedModel) { modelData in
NewsFeedTableViewCell(newsFedd: modelData)
}
}
}
}.ignoresSafeArea()
}
}
Run Code Online (Sandbox Code Playgroud)
有谁知道是什么问题?
scrollview navigationbar swiftui swiftui-scrollview swiftui-navigationview
View在 aLazyVGrid和 an之间动画sHStack与它们之间的另一个视图(在本例中为 a Button),使用matchedGeometryEffect,效果很好:
请注意动画视图如何在“完成”按钮上方移动。
但是,当视图包含在 a 中时ScrollView,动画视图现在移动到中间视图的后面:
我已经尝试设置zIndex了的ScrollViews到> 0(或更多),但这似乎并没有改变什么都。
关于如何解决这个问题的任何想法?
人
struct Person: Identifiable, Equatable {
var id: String { name }
let name: String
var image: Image { Image(name) }
static var all: [Person] {
["Joe", "Kamala", "Donald", "Mike"].map(Person.init)
}
}
Run Code Online (Sandbox Code Playgroud)
内容视图
struct ContentView: View {
@State var people: [Person]
@State private var selectedPeople: [Person] = []
@Namespace var …Run Code Online (Sandbox Code Playgroud) 所以我有一个如下所示的 TabView,但是当我尝试在 ScrollView 中实现它时,我总是必须给它一个固定的高度。有没有办法告诉 tabview 使用它在 scrollView 中需要的空间?我不知道 TabView 的内部内容的高度(顺便说一句。随时间变化),因此固定高度对我不起作用。
我试过 .frame(maxHeight: .infinity),但这似乎不起作用
import SwiftUI
struct TEST: View {
var body: some View {
ScrollView {
TabView {
Text("Hello World")
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.frame(maxHeight: .infinity)
// only .frame() with fixed Height works...
}
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个 SwiftUI Scrollview 来拖动其容器,如下所示:https://drive.google.com/file/d/1O92DgsVI1OjM1HEUXUwVywB8gcdShOP-/view ?usp=sharing
许多苹果应用程序都使用它(苹果地图、音乐、钱包等),但我还没有找到一种简单的方法来使用 SwiftUI 来做到这一点。您认为简单地实现这一点的最佳方法是什么?
我查看了这里的大多数库https://github.com/search?q=swiftui+drawer但它们都没有实现带有可以拖动视图的 ScrollView 的抽屉。
我还尝试将自定义 UIScrollView 实现为 UIViewRepresentable ,并尝试调整 scrollViewWillBeginDragging() 但无法使其工作。
我找到了一种用 a和 a保存 ScrollViews偏移量的方法。GeometryReaderPreferenceKey
SwiftUI | 从 ScrollView 获取当前滚动位置
并且有一个滚动到设定位置ScrollViewReader的方法。scrollTo
问题是,第一个方法保存偏移量,而第二个方法需要一个位置(或一个 id,与我的情况下的位置类似)。如何将偏移量转换为位置/id 或者是否有其他方法来保存和加载 ScrollViews 位置?
这是我现在拥有的代码,但它没有按照我想要的方式滚动:
ScrollView {
ScrollViewReader { scrollView in
LazyVGrid(columns: columns, spacing: 0) {
ForEach(childObjects, id: \.id) { obj in
CustomView(obj: obj).id(obj.id)
}
}
.onChange(of: scrollTarget) { target in
if let target = target {
scrollTarget = nil
scrollView.scrollTo(target, anchor: .center)
}
}
.background(GeometryReader {
Color.clear.preference(key: ViewOffsetKey.self,
value: -$0.frame(in: .named("scroll")).origin.y)
})
.onPreferenceChange(ViewOffsetKey.self) { // …Run Code Online (Sandbox Code Playgroud) swiftui ×10
ios ×5
xcode ×2
animation ×1
draggesture ×1
scrollview ×1
swift ×1
swiftui-list ×1