有人可以解释ScrollView测试代码的行为吗-为什么我不能滚动到左边缘和上边缘,为什么我可以滚动到右边缘和下边缘?以及如何解决这个问题。 (请注意,如果我们删除ISupply<T>
,则行为不会改变。)
public class Covariance
{
public class Animal { }
public class Rabbit : Animal { }
public interface ISupply<out T>
{
T Get();
}
public void NoCompileErrors()
{
ISupply<Animal> animals = null;
ISupply<Rabbit> rabbits = null;
animals = rabbits;
}
}
答案 0 :(得分:1)
我已经将@Asperi的答案改编为另一个问题(SwiftUI How to align a view that's larger than screen width),并且可行。
@State private var offset : CGPoint = .zero
var body: some View {
ScrollView.init([.vertical,.horizontal]) {
VStack {
Text("AAA")
.padding(8)
.frame(width: 1024, height: 1024)
.background(Color.orange)
.border(Color.red)
}
.background(rectReader())
.offset(x: self.offset.x, y: self.offset.y)
}
.border(Color.blue)
}
func rectReader() -> some View {
return GeometryReader { (geometry) -> AnyView in
let offset : CGPoint = CGPoint.init(
x: -geometry.frame(in: .global).minX,
y: -geometry.frame(in: .global).minY
)
if self.offset == .zero {
DispatchQueue.main.async {
self.offset = offset
}
}
return AnyView(Rectangle().fill(Color.clear))
}
}
答案 1 :(得分:1)
或者您可以尝试对每个方向使用一个ScrollView,请尝试
import SwiftUI
struct ContentView: View {
var body: some View {
ScrollView(.horizontal, showsIndicators: true) {
ScrollView(.vertical, showsIndicators: true) {
Color.yellow.frame(width: 1024, height: 1024)
.overlay(Text("A").font(.largeTitle), alignment: .topLeading)
.overlay(Text("B").font(.largeTitle), alignment: .topTrailing)
.overlay(Text("C").font(.largeTitle), alignment: .bottomTrailing)
.overlay(Text("D").font(.largeTitle), alignment: .bottomLeading)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
更新
要了解使用.offset修饰符会发生什么,请尝试想象一下此代码段的结果
import SwiftUI
struct ContentView: View {
var body: some View {
HStack {
Text("Hello").padding().background(Color.yellow).offset(x: 20, y: 40).border(Color.red)
Text("World").padding().background(Color.pink).offset(x: -10, y: -10).border(Color.yellow)
}.padding().border(Color.gray)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
答案 2 :(得分:0)
我遇到了这个问题和答案,因为我今天试图在任何方向上滚动(缩放)图像时都在寻找这个“内容视图错放问题”的解决方案,时间长达数小时。
这里提出的解决方案都不是“不错”的,也不适合我的情况。但是在为自己找到解决方案之后,我想在这里记录如何解决您的问题。
主要问题是内容视图的中心(带有VStack
元素的= {Text
)与ScrollView
的中心对齐。总是这样:内容大小小于还是大于ScrollView
大小。 (请记住:ScrollView
的大小对应于屏幕的大小,减去安全区域边缘的插图)。要将内容视图的最前边缘与滚动视图的最前边缘对齐,您必须使内容偏移当前在左侧重叠的量。
好东西:可以直接使用GeometryReader
和已知的内容大小来计算它。
var body: some View {
GeometryReader { proxy -> AnyView in
let insets = proxy.safeAreaInsets
let sw = proxy.size.width + insets.leading + insets.trailing
let sh = proxy.size.height + insets.top + insets.bottom
let contentSize : CGFloat = 1024
let dx: CGFloat = (contentSize > sw ? (contentSize - sw)/2 : 0.0)
let dy: CGFloat = (contentSize > sh ? (contentSize - sh)/2 : 0.0)
return AnyView(
ScrollView([.vertical,.horizontal]) {
VStack {
Text("AAA")
.padding(8)
.frame(width: 1024, height: 1024)
.background(Color.orange)
.border(Color.red)
}
.offset(x: dx, y: dy)
}
.border(Color.blue)
)
}
}