swiftui ScrollViewReader scrollTo 无法正常工作
swiftui ScrollViewReader scrollTo not correct working
我正在使用 swiftui 开发一个应用程序。缩放后,当我说用 ScrollViewReader 滚动到角落时,它会离开屏幕。我的代码在下面。尝试几次后失败。它不是每次都这样做。
import SwiftUI
struct ContentView: View {
@State var zoomIn = false
var body: some View {
GeometryReader { g in
ScrollViewReader { reader in
ScrollView([.horizontal,.vertical], showsIndicators: false) {
VStack(spacing: 20) {
ForEach(0 ..< 11, id:\.self) { row in
HStack(spacing: 20) {
ForEach(0 ..< 11, id:\.self) { column in
Text("Item \(row) \(column)")
.foregroundColor(.white)
.frame(width: zoomIn ? 70 : 35, height: zoomIn ? 70 : 35)
.background(Color.red)
.id("\(row)\(column)")
.onTapGesture {
withAnimation {
reader.scrollTo( ["00", "010","100","1010"].randomElement()!)
}
}
}
}
}
}
Button("Zoom") {
withAnimation {
zoomIn.toggle()
}
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我的主屏幕。
在 scrollTo
之后
我认为您遇到的问题是 2 ForEach
似乎无法与 ScrollReader
配合使用。我采用了不同的方法并使用了可识别的结构和 LazyVGrid
。这让我可以使用一个 ForEach
并用 UUID
标识各个方块。然后我在 scrollTo()
中使用了相同的 UUID
。我 运行 遇到的唯一困难是 ScrollReader
不知道如何处理双向 ScrollView
,所以我创建了一个返回 UnitPoint
的函数并将其用作scrollTo()
中的锚点。这似乎已经成功了,而且工作起来非常可靠。
struct BiDirectionScrollTo: View {
let scrollItems: [ScrollItem] = Array(0..<100).map( { ScrollItem(name: [=10=].description) })
let columns = [
// Using 3 grid items forces there to be 3 columns
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80))
]
init() {
}
var body: some View {
ScrollViewReader { reader in
ScrollView([.horizontal,.vertical], showsIndicators: false) {
LazyVGrid(columns: columns, spacing: 20) {
ForEach(scrollItems, id: \.id) { item in
Text("Item \(item.name)")
.foregroundColor(.white)
.frame(width: 80, height: 80)
.background(Color.red)
.id(item.id)
.onTapGesture {
withAnimation {
if let index = [0, 9, 55, 90, 99].randomElement() {
print(index)
reader.scrollTo(scrollItems[index].id, anchor: setUnitPoint(index))
}
}
}
}
}
}
}
}
private func setUnitPoint(_ index:Int) -> UnitPoint {
switch true {
case index % 10 < 2 && index / 10 < 2:
return .topLeading
case index % 10 >= 7 && index / 10 < 7:
return .topTrailing
case index % 10 < 2 && index / 10 >= 7:
return .bottomLeading
case index % 10 >= 2 && index / 10 >= 7:
return .bottomTrailing
default:
return .center
}
}
}
struct ScrollItem: Identifiable {
let id = UUID()
var name: String
}
我正在使用 swiftui 开发一个应用程序。缩放后,当我说用 ScrollViewReader 滚动到角落时,它会离开屏幕。我的代码在下面。尝试几次后失败。它不是每次都这样做。
import SwiftUI
struct ContentView: View {
@State var zoomIn = false
var body: some View {
GeometryReader { g in
ScrollViewReader { reader in
ScrollView([.horizontal,.vertical], showsIndicators: false) {
VStack(spacing: 20) {
ForEach(0 ..< 11, id:\.self) { row in
HStack(spacing: 20) {
ForEach(0 ..< 11, id:\.self) { column in
Text("Item \(row) \(column)")
.foregroundColor(.white)
.frame(width: zoomIn ? 70 : 35, height: zoomIn ? 70 : 35)
.background(Color.red)
.id("\(row)\(column)")
.onTapGesture {
withAnimation {
reader.scrollTo( ["00", "010","100","1010"].randomElement()!)
}
}
}
}
}
}
Button("Zoom") {
withAnimation {
zoomIn.toggle()
}
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我的主屏幕。
在 scrollTo
之后我认为您遇到的问题是 2 ForEach
似乎无法与 ScrollReader
配合使用。我采用了不同的方法并使用了可识别的结构和 LazyVGrid
。这让我可以使用一个 ForEach
并用 UUID
标识各个方块。然后我在 scrollTo()
中使用了相同的 UUID
。我 运行 遇到的唯一困难是 ScrollReader
不知道如何处理双向 ScrollView
,所以我创建了一个返回 UnitPoint
的函数并将其用作scrollTo()
中的锚点。这似乎已经成功了,而且工作起来非常可靠。
struct BiDirectionScrollTo: View {
let scrollItems: [ScrollItem] = Array(0..<100).map( { ScrollItem(name: [=10=].description) })
let columns = [
// Using 3 grid items forces there to be 3 columns
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80)),
GridItem(.fixed(80))
]
init() {
}
var body: some View {
ScrollViewReader { reader in
ScrollView([.horizontal,.vertical], showsIndicators: false) {
LazyVGrid(columns: columns, spacing: 20) {
ForEach(scrollItems, id: \.id) { item in
Text("Item \(item.name)")
.foregroundColor(.white)
.frame(width: 80, height: 80)
.background(Color.red)
.id(item.id)
.onTapGesture {
withAnimation {
if let index = [0, 9, 55, 90, 99].randomElement() {
print(index)
reader.scrollTo(scrollItems[index].id, anchor: setUnitPoint(index))
}
}
}
}
}
}
}
}
private func setUnitPoint(_ index:Int) -> UnitPoint {
switch true {
case index % 10 < 2 && index / 10 < 2:
return .topLeading
case index % 10 >= 7 && index / 10 < 7:
return .topTrailing
case index % 10 < 2 && index / 10 >= 7:
return .bottomLeading
case index % 10 >= 2 && index / 10 >= 7:
return .bottomTrailing
default:
return .center
}
}
}
struct ScrollItem: Identifiable {
let id = UUID()
var name: String
}