慢速滚动时,TableView滞后

时间:2018-05-24 13:58:56

标签: ios swift uitableview smooth-scrolling

我的UITableViewCell平滑滚动有问题。 当我慢慢滚动UITableView时,我得到30-40 FPS,我的细胞正在跳跃(首先在顶部,最后在底部)。

当我快速滚动时,我得到55-60 FPS,细胞没有跳跃,一切都很好。

FPS由Profile测量。

当我滚动CPU时,使用率约为15-25%

我正在使用UIStoryboard创建单元格,Realm DBUITableViewAutomaticDimension

这是我的UITableView代码:

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let stop = getStop(indexPath: indexPath)
    let cell = tableView.dequeueReusableCell(withIdentifier: "stop", for: indexPath) as! StopTableViewCell
    cell.configure(model: stop)
    return cell        
 }

这是单元格代码:

class StopTableViewCell: UITableViewCell {


@IBOutlet weak var status: UILabel!
@IBOutlet weak var number: UILabel!
@IBOutlet weak var date: UILabel!
@IBOutlet weak var name: UnderLinedLabel!
@IBOutlet weak var address: UnderLinedLabel!
@IBOutlet weak var phone: UnderLinedLabel!
@IBOutlet weak var milage: UILabel!


override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func prepareForReuse() {
    super.prepareForReuse()
    name.text = nil
    address.text = nil
    phone.text = nil
    milage.text = nil
    number.text =  nil
    date.text = nil
}

func calculateEstimateRoute(to lat: Double, lon: Double) -> String {
    let distance = LocationManager.Instance.actualLocation.distance(from: CLLocation(latitude: lat, longitude: lon))
    let isMetric = NSLocale.current.usesMetricSystem
    let measurment = Measurement(value: distance, unit: UnitLength.meters)
    var estimateRoute = !isMetric ? measurment.converted(to: UnitLength.miles) : measurment.converted(to: UnitLength.kilometers)
    estimateRoute.value = round(estimateRoute.value)
    return "~" + String(describing: estimateRoute)
}

func configure<T>(model: T) {
    if let stop = model as? Stop {
        name.text = stop.name
        address.text = stop.address1 + "\n" + stop.address2
        phone.text = stop.phone
        phone.isHidden = stop.phone.isEmpty
        milage.text = calculateEstimateRoute(to: stop.lat, lon: stop.lng)
        number.text =  "# " + stop.refno
        date.text = stop.departtime
        layer.shouldRasterize = true
        layer.rasterizationScale = UIScreen.main.scale
    }
}

}

这是单元格Via故事板: enter image description here

也许我必须创建3个单元格用于顶部orangeView,第二个用于中心内容,第三个用于底部按钮视图?

这是:

func getStop<S: Stop>(indexPath: IndexPath) -> S {
    switch segmentIndex {
    case 0:
        return stops.ASSIGNED[indexPath.row] as! S
    case 1:
        return stops.UNASSIGNED[indexPath.row] as! S
    default:
        return Stop() as! S
    }
}

在标题中我有UISegmentedControl

2 个答案:

答案 0 :(得分:1)

我正在看这个并想知道calculateEstimateRoute需要多长时间才能完成?这似乎是最可能的瓶颈。

我建议您使用Time Profiler运行Instruments,看看该功能专用的处理器功率。如果它很重要,您可以考虑将该函数推送到后台线程 - 可能使用操作队列,以便可以在prepareForReuse中取消调用。我已经对包含图像的单元格使用了类似的技术,因为加载图像可能非常耗时。

答案 1 :(得分:1)

问题是每次填充单元格时都在计算距离信息。

您需要记住,当您滚动设备上可见的单元格列表时,单元格会不断填充。这意味着当您向上和向下滚动时,您可以重复计算该值。

也许这是你的意图,因为用户可以旅行?我不知道你的用例,所以我可以提供以下内容作为一个想法。

更改您的数据源只是将此信息作为Stop对象的一部分提供。如果您需要根据用户位置更新距离信息,并且您想要处理它们可以运动的事实,您应该使用startMonitoringSignificantLocationChanges(),并且当位置正在更新时,您计算估计的路线。

您可以使用以下方法获取有关获取位置更新的信息:

订阅位置更新。 https://developer.apple.com/documentation/corelocation/cllocationmanager/1423531-startmonitoringsignificantlocati

您需要实施的方法来获取位置更新。 https://developer.apple.com/documentation/corelocation/cllocationmanagerdelegate/1423615-locationmanager