Swift 计算在可见屏幕上移动的项目的内容偏移量

Swift Calculate Content Offset of item moving across visible screen

我正在重新创建 iPhone App Switcher 页面,其中应用程序的选项卡视图大小基于它在可视屏幕上的位置(右侧较大,左侧较小)。我在滚动视图中有一系列视图。我想根据视图的位置/内容偏移设置每个视图(选项卡)的大小,因为它在可见屏幕 x 轴上水平滚动。

这是我在 scrollViewDidScroll 中的代码:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    tabViews.forEach { (tabView) in // tabViews: [UIView]
        let screenWidth = UIScreen.main.bounds.width

        // This should be a value between 0 and 1
        var screenOffsetX = tabView.convert(CGPoint(x: tabView.frame.minX, y: 0),to: view).x
        let maxValue: CGFloat = screenWidth / 8 // Max value is 1 + 1/8 scale size
        if screenOffsetX > maxValue { // Set max scale
            screenOffsetX = min(screenOffsetX, maxValue)
        }
        let minValue: CGFloat = 0
        if screenOffsetX < minValue { // Set min scale
            screenOffsetX = max(screenOffsetX, minValue)
        }

        let scaleAmount: CGFloat = 1 + (screenOffsetX / screenWidth)
        let scaleTransform = CGAffineTransform(scaleX: scaleAmount, y: scaleAmount)
        tabView.transform = scaleTransform
    }
}

我认为数学不对。我不认为 abcd.convert(point: ) 在可视屏幕上返回正确的内容偏移量。这是带有视图(选项卡)的滚动视图的图像:

每个视图都应在屏幕右侧略大,在左侧略小。

有什么想法吗?

tabView.convert 肯定不会 return 介于 0...1 之间的值 - 它只是将一个点转换为不同的视图坐标。

也应该是scrollView.convert,而不是tabView.convert

可以简化这些检查:

if screenOffsetX > maxValue { // Set max scale
   screenOffsetX = min(screenOffsetX, maxValue)
}

在您确认 maxValue 较小后,再进行 min 就没有意义了。你要么:

if screenOffsetX > maxValue { // Set max scale
   screenOffsetX = maxValue
}

screenOffsetX = min(screenOffsetX, maxValue)

我不确定你的代码中 maxValue 和 minValue 的用法是什么,但如果你想根据它们的位置缩放事物,我建议这样做:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
        tabViews.forEach { tabView in // tabViews: [UIView]
            let screenWidth = UIScreen.main.bounds.width
            var screenOffsetX = scrollView.convert(CGPoint(x: tabView.frame.minX, y: 0), to: view).x
            var screenOffsetPercentage = screenOffsetX / screenWidth
            let minValue: CGFloat = 0.5
            let maxValue: CGFloat = 1
            let scaleAmount = minValue + (maxValue - minValue) * screenOffsetPercentage
            let scaleTransform = CGAffineTransform(scaleX: scaleAmount, y: scaleAmount)
            tabView.transform = scaleTransform
        }
    }

您必须根据自己的想法调整它,但一开始它会从右侧的 1.0 比例缩放到左侧的 0.5 比例。

结果如下:https://media.giphy.com/media/m5KSgIInJmGjEHLZXb/giphy.gif