swift - 如何在 UIScrollView 移动时正确转换 UIView 的比例

标签 swift uiview uiscrollview

为了获得与 Snapchat 的 HUD 移动类似的效果,我创建了一个基于 UIScollView 的 contentOffset 的 HUD 元素的移动。 编辑:Link to the Github project .

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    self.view.layoutIfNeeded()

    let factor = scrollView.contentOffset.y / self.view.frame.height

    self.transformElements(self.playButton,
                           0.45 + 0.55 * factor, // 0.45 = desired scale + 0.55 = 1.0 == original scale
                           Roots.screenSize.height - 280, // 280 == original Y
                           Roots.screenSize.height - 84, // 84 == minimum desired Y
                           factor)
}

func transformElements(_ element: UIView?,
                       _ scale: CGFloat,
                       _ originY: CGFloat,
                       _ desiredY: CGFloat,
                       _ factor: CGFloat) {
    if let e = element {
        e.transform = CGAffineTransform(scaleX: scale, y: scale) // this line lagging

        let resultY = desiredY + (originY - desiredY) * factor
        var frame = e.frame
        frame.origin.y = resultY
        e.frame = frame
    }
}

使用此代码实现的滚动以及过渡似乎“滞后”/不流畅。 (实体 iPhone 6S+ 和 7+)。

删除以下行:e.transform = CGAffineTransform(scaleX: scale, y: scale) 消除了这个问题。 UIView 对象的滚动和 Y 移动 再次平滑。

变换对象比例的最佳方法是什么?

enter image description here

没有布局约束。

func setupPlayButton() {
        let rect = CGRect(x: Roots.screenSize.width / 2 - 60,
                          y: Roots.screenSize.height - 280,
                          width: 120,
                          height: 120)
        self.playButton = UIButton(frame: rect)
        self.playButton.setImage(UIImage(named: "playBtn")?.withRenderingMode(.alwaysTemplate), for: .normal)
        self.playButton.tintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
        self.view.addSubview(playButton)
}

最佳答案

发生这种情况是因为您同时应用了:transformframe。如果您只应用 transform,它会更平滑。如下更新您的 transformElements 函数:

    func transformElements(_ element: UIView?,
                       _ scale: CGFloat,
                       _ originY: CGFloat,
                       _ desiredY: CGFloat,
                       _ factor: CGFloat) {
    if let e = element {
        e.transform = CGAffineTransform(scaleX: scale, y: scale).translatedBy(x: 0, y: desiredY * (1 - factor))

    }
}

关于swift - 如何在 UIScrollView 移动时正确转换 UIView 的比例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43469323/

相关文章:

ios - 如何在 spriteKit swift 中降低 Sprite 的速度?

ios - 尝试更新 firebase 但节点值被删除

ios - 如何强制UIView(mapView)占满整个屏幕

ios - CGPDFPage 绘图导致内存问题(Swift 3)

ios - UIScrollView 没有缩放

iOS swift : Constraints did not update on screen

json - Swift 中的 Realm DB 和对象映射器 (Json)

swift - 如何处理基于单元格的 NSOutlineView 中的复选框单击

ios - 最小化窗口动画,但对于 iOS?

ios - viewDidload 和 viewDidAppear 没有被调用?