Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/104.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 当滚动超过工作表中的限制时,防止在滚动视图顶部的图像上方填充_Ios_Swiftui - Fatal编程技术网

Ios 当滚动超过工作表中的限制时,防止在滚动视图顶部的图像上方填充

Ios 当滚动超过工作表中的限制时,防止在滚动视图顶部的图像上方填充,ios,swiftui,Ios,Swiftui,如果在ScrollView中呈现一张在下方显示文本的图纸,则向下滚动然后向上轻弹时,请注意,它将滚动超过限制,并且在图像上方显示空白,直到弹性滚动效果稳定为止。然后,您可以向下拉以关闭该工作表 我想防止在ScrollView中的图像上方添加空间。相反,我希望填充显示在图像和第一个文本之间。应用商店就是这样一个应用程序——当你点击今天的一篇报道时,请注意,当向上滚动超过限制时,顶部的图像始终固定在顶部,并且在其下方会出现弹性反弹效果 我怀疑GeometryReader可以用来获得全球坐标空间中的位

如果在ScrollView中呈现一张在下方显示文本的图纸,则向下滚动然后向上轻弹时,请注意,它将滚动超过限制,并且在图像上方显示空白,直到弹性滚动效果稳定为止。然后,您可以向下拉以关闭该工作表

我想防止在ScrollView中的图像上方添加空间。相反,我希望填充显示在图像和第一个文本之间。应用商店就是这样一个应用程序——当你点击今天的一篇报道时,请注意,当向上滚动超过限制时,顶部的图像始终固定在顶部,并且在其下方会出现弹性反弹效果

我怀疑GeometryReader可以用来获得全球坐标空间中的位置,但我不清楚如何利用它来获得所需的行为

struct details视图:视图{
var图像:UIImage?
var body:一些观点{
滚动视图{
图像(uiImage:Image??uiImage())
.可调整大小()
.aspectRatio((图像?.size.width±1)/(图像?.size.height±1),内容模式:。填充)
.背景(颜色(.secondarySystemFill))

ForEach(0..这可以使用GeometryReader:

  • 图像
    包装在
    GeometryReader
    中,这样就可以获得全局坐标空间中的位置
  • 确保将
    .scaledToFill()
    添加到
    GeometryReader
    中,否则它不会占用
    滚动视图中的任何空间。或者,您可以通过为
    GeometryReader
    提供默认帧来解决此问题
  • 使用全局坐标空间中图像的
    minY
    设置“向上拖动”时的
    offset
    。这样可以模拟图像处于固定位置
  • 这项技术有一个问题。当向下拖动工作表时,图像会粘在它的位置上,这看起来很奇怪。我还不知道如何解决这个问题,但这个答案可能会对您有所帮助

    请参见下面的示例

    struct DetailsView: View {
        func getOffsetY(basedOn geo: GeometryProxy) -> CGFloat {
            // Find Y position
            let minY = geo.frame(in: .global).minY
            
            let emptySpaceAboveSheet: CGFloat = 40
            
            // Don't offset view when scrolling down
            if minY <= emptySpaceAboveSheet {
                return 0
            }
            
            // Offset the view when it goes above to simulate it standing still
            return -minY + emptySpaceAboveSheet
        }
        
        var body: some View {
            ScrollView {
                GeometryReader { imageGeo in
                    Image(systemName: "option")
                        .resizable()
                        .scaledToFill()
                        .background(Color(.secondarySystemFill))
                        .offset(x: 0, y: self.getOffsetY(basedOn: imageGeo))
                }
                // Need this to make sure the geometryreader has a size
                .scaledToFill()
                
                
                ForEach(0..<50) { index in
                    Text("\(index)")
                }
            }
        }
    }
    
    struct details视图:视图{
    func getOffsetY(基于geo:GeometryProxy)->CGFloat{
    //找到Y位置
    设minY=geo.frame(in:.global).minY
    让空白空间位于图纸上方:CGFloat=40
    //向下滚动时不偏移视图
    
    如果minYOk,下面是您案例的可能解决方案。使用Xcode 12b5/iOS 14进行测试

    这个想法是有一个内部的容器,在里面滚动,但是在滚动视图坐标空间中读取它的坐标,补偿相对于容器的图像位置偏移,容器继续滚动,这样就产生了效果,所有其他的东西,比如图像下面,仍然有弹跳

    struct DemoView:View{
    var图像:UIImage?
    @国家私有风险值偏移量=CGFloat.zero
    var body:一些观点{
    滚动视图{
    VStack{//内部容器
    图像(uiImage:Image??uiImage())
    .可调整大小()
    .aspectRatio((图像?.size.width±1)/(图像?.size.height±1),内容模式:。填充)
    .背景(颜色(.secondarySystemFill))
    .offset(y:offset<0?offset:0)//压缩偏移
    ForEach(0..Value){
    value+=nextValue()
    }
    }
    
    这几乎可以正常工作!就像您提到的那样,在工作表关闭时,图像保持不变,并且图像纵横比丢失。您不想按照中所述禁用反弹吗?虽然这样可以解决不希望出现的行为,但希望仍然支持弹性滚动行为,而不是在顶部突然停止滚动
    struct DetailsView: View {
        var image: UIImage?
        
        var body: some View {
            ScrollView {
                Image(uiImage: image ?? UIImage())
                    .resizable()
                    .aspectRatio((image?.size.width ?? 1) / (image?.size.height ?? 1), contentMode: .fill)
                    .background(Color(.secondarySystemFill))
                
                ForEach(0..<50) { index in
                    Text("\(index)")
                }
            }
        }
    }
    
    struct DetailsView: View {
        func getOffsetY(basedOn geo: GeometryProxy) -> CGFloat {
            // Find Y position
            let minY = geo.frame(in: .global).minY
            
            let emptySpaceAboveSheet: CGFloat = 40
            
            // Don't offset view when scrolling down
            if minY <= emptySpaceAboveSheet {
                return 0
            }
            
            // Offset the view when it goes above to simulate it standing still
            return -minY + emptySpaceAboveSheet
        }
        
        var body: some View {
            ScrollView {
                GeometryReader { imageGeo in
                    Image(systemName: "option")
                        .resizable()
                        .scaledToFill()
                        .background(Color(.secondarySystemFill))
                        .offset(x: 0, y: self.getOffsetY(basedOn: imageGeo))
                }
                // Need this to make sure the geometryreader has a size
                .scaledToFill()
                
                
                ForEach(0..<50) { index in
                    Text("\(index)")
                }
            }
        }
    }
    
    struct DemoView: View {
        var image: UIImage?
    
        @State private var offset = CGFloat.zero
    
        var body: some View {
            ScrollView {
                VStack { // internal container
                    Image(uiImage: image ?? UIImage())
                        .resizable()
                        .aspectRatio((image?.size.width ?? 1) / (image?.size.height ?? 1), contentMode: .fill)
                        .background(Color(.secondarySystemFill))
                        .offset(y: offset < 0 ? offset : 0)      // compansate offset
    
                    ForEach(0..<50) { index in
                        Text("\(index)")
                    }
                }
                .background(GeometryReader {
                    // read current position of container inside scroll view
                    Color.clear.preference(key: ViewOffsetKey.self,
                        value: -$0.frame(in: .named("scroll")).origin.y)
                })
                .onPreferenceChange(ViewOffsetKey.self) {
                    self.offset = $0   // needed offset to shift back image
                }
            }
            .coordinateSpace(name: "scroll")
        }
    }
    
    struct ViewOffsetKey: PreferenceKey {
        typealias Value = CGFloat
        static var defaultValue = CGFloat.zero
        static func reduce(value: inout Value, nextValue: () -> Value) {
            value += nextValue()
        }
    }