首页 > 解决方案 > iOS频繁约束常量更新导致帧率下降

问题描述

我正在创建一个用户界面类似于 Tinder 的应用程序。为了重新创建这个用户界面,我不得不使用UIPageViewController嵌入在容器视图中的UIButtons,并将 s 置于容器视图之上。重新创建这个 UI 很昂贵,并且会导致我的应用程序的帧速率下降。

在此处输入图像描述

请注意滑动到右侧页面时帧速率的下降。

每当用户在页面之间滚动时,叠加层会根据用户在页面之间滚动UIButton的程度来调整大小和颜色。这是通过继承UIPageViewControlleras aUIScrollViewDelegate并将UIPageViewController' UIScrollViewscontentOffset.x作为超级视图宽度的百分比传递给相应调整覆盖按钮的函数来完成的。

extension PageViewController: UIScrollViewDelegate {
    public func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let point = scrollView.contentOffset
        var percentComplete: CGFloat
        percentComplete = abs(point.x - view.frame.size.width)/view.frame.size.width
        if !(point.x > view.frame.width && currentPage == 2) && !(point.x < view.frame.width && currentPage == 0) {
            if point.x < view.frame.width  {
                containerVC.adjustButtons(for: percentComplete, direction: 1)
            } else {
                containerVC.adjustButtons(for: percentComplete, direction: 0)
            }
        }
    }
}

每次调用都会调用调整按钮大小和颜色的函数scrollViewDidScroll。这是通过参考滚动了多少UIPageViewController并相应地调整按钮约束、图像插图和图像来完成的。这个函数可能非常昂贵,因为每次调用它都会scrollViewDidScroll被调用,但我不确定如何解决这个问题。

最终结果是我所期望的行为,但是在开始滚动时,帧速率有时会显着下降UIPageViewController

func adjustButtons(for percentage: CGFloat, direction: Int) {
    buttonWrapperLeading.constant = (view.frame.width/2 - 38) * percentage
    buttonWrapperTrailing.constant = (view.frame.width/2 - 38) * percentage
    self.profileButton.imageEdgeInsets = UIEdgeInsets(top: 8 * (1-percentage), left: 8 * (1-percentage), bottom: 8 * (1-percentage), right: 8 * (1-percentage))
    self.meetButton.imageEdgeInsets = UIEdgeInsets(top: 8 * percentage, left: 8 * percentage, bottom: 8 * percentage, right: 8 * percentage)
    self.chatButton.imageEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
    let newProfileButtonImage = UIImage(named: "profileSilhouette")!.withRenderingMode(.alwaysTemplate).image(withTintColor: UIColor.interpolate(from: .darkGray, to: .secondaryColor, with: percentage))
    profileButton.setImage(newProfileButtonImage, for: .normal)
    let newMeetButtonImage = UIImage(named: "meet")!.withRenderingMode(.alwaysTemplate).image(withTintColor: UIColor.interpolate(from: .secondaryColor, to: .darkGray, with: percentage))
    meetButton.setImage(newMeetButtonImage, for: .normal)
}

我想知道如何做到这一点以最大程度地减少帧速率下降。我想约束常数的调整,以及每次调用函数时设置具有不同阴影和不同 imageInset 的按钮图像可能会导致问题,但我不确定。我不知道如何在不降低帧速率的情况下重新创建此 UI。

以下是 Tinder 的 UI 外观供参考: 在此处输入图像描述

标签: iosswiftcore-graphicscore-animationframe-rate

解决方案


我会使用分析(仪器)来获取有关导致丢帧的原因的更多详细信息。


推荐阅读