在UITableView中的索引路径上平滑滚动到靠近单元格的特定位置

问题描述 投票:0回答:1

我想滚动到我的UITableView中靠近我的一个单元格的位置。

我这个代码执行此操作:

myTableView.scrollToRow(at: index,at: .top, animated: true)

并在动画完成后我做:

myTableView.setContentOffset(CGPoint(x: 0, y: myTableView.contentOffset.y + myCloseToCellOffset), animated: true)

然而问题是动画被分成两个动画,因此不能顺利运行。反正有没有把它变成一个动画?或者任何其他方式来获得我想要的结果?

ios swift uitableview
1个回答
1
投票

在我看来,只有当两个动画的方向相同时,两个动画之间的这种令人不快的停顿才是令人不快的。当它不同时(首先,然后向下)它看起来很好。所以我提出以下建议(也许有一个更简单的解决方案,但这就是我的想法):

  1. 计算myTableView.scrollToRow(at: index,at: .top, animated: true)自己实现的偏移量。
  2. 如果此偏移变化与添加myCloseToCellOffset的方向相同,只需将myCloseToCellOffset添加到其中并直接调用myTableView.setContentOffset(CGPoint(x: 0, y: myTableView.contentOffset.y + (initalOffset + myCloseToCellOffset), animated: true)
  3. 如果此偏移变化的方向与myCloseToCellOffset实现的偏移变化不同,则进行两次调用。首先是myTableView.setContentOffset(CGPoint(x: 0, y: myTableView.contentOffset.y + initalOffset, animated: true)然后是`myTableView.setContentOffset(CGPoint(x:0,y:myTableView.contentOffset.y + myCloseToCellOffset,animated:true)

我不知道myCloseToCellOffset是什么,所以我认为它可能是正面的,也可能是负面的或零。

这是一些示例实现,我希望我没有错误,我希望我足够冗长:

enum TableViewChangeDirections {
case upUp
case downDown
case upDown
case downUp
case unimportant
}

extension Double {
/// Rounds the double to decimal places value
    func rounded(toPlaces places:Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}

然后在包含表视图的View Controller中

let numberOfCells = 20
let cellToMakeVisibleIndex = 5
let heightOfCell : CGFloat = 44
let myCloseToCellOffset : CGFloat = 100

var firstDesiredYOffset: CGFloat!
var secondDesiredYOffset: CGFloat!

这将找到scrollToRow的偏移量

func tableViewOffset(forCellToGoTo cellToGoTo: CGFloat) -> CGFloat {
    let desiredOffset = heightOfCell * cellToGoTo
    var maxContentOffset = CGFloat(numberOfCells)*heightOfCell - tableView.frame.size.height
    maxContentOffset = (maxContentOffset >= 0) ? maxContentOffset : 0
    return (desiredOffset > maxContentOffset) ? maxContentOffset : desiredOffset
}

如果方向相反,这将执行第二次偏移更改:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if (tableView.isUserInteractionEnabled == false && self.secondDesiredYOffset != nil && self.firstDesiredYOffset != nil && Double(tableView.contentOffset.y).rounded(toPlaces: 2) == Double(self.firstDesiredYOffset).rounded(toPlaces: 2)) {
        self.tableView.setContentOffset(CGPoint(x: 0, y: self.secondDesiredYOffset), animated: true)
        self.secondDesiredYOffset = nil
        self.tableView.isUserInteractionEnabled = true
    }
}

这将返回两个偏移变化的方向:

    var changeDirections : TableViewChangeDirections {
    if self.firstDesiredYOffset > self.tableView.contentOffset.y && myCloseToCellOffset >= 0 {
        return .upUp
    } else if self.firstDesiredYOffset > self.tableView.contentOffset.y && myCloseToCellOffset < 0 {
        return .upDown
    } else if self.firstDesiredYOffset < self.tableView.contentOffset.y && myCloseToCellOffset <= 0 {
        return .downDown
    } else if self.firstDesiredYOffset < self.tableView.contentOffset.y && myCloseToCellOffset > 0 {
        return .downUp
    } else {
        return .unimportant
    }
}

最后,您进行一般偏移的位置会发生变化。我把它放在按钮动作中,但你把它放在你需要的地方:

 @IBAction func didPressButton(_ sender: Any) {

    self.firstDesiredYOffset = self.tableViewOffset(forCellToGoTo: CGFloat(cellToMakeVisibleIndex))
    self.tableView.setContentOffset(CGPoint(x: 0, y: self.firstDesiredYOffset), animated: true)

    switch (self.changeDirections) {
    case .upUp, .downDown:
        self.firstDesiredYOffset = self.firstDesiredYOffset + myCloseToCellOffset
        self.tableView.setContentOffset(CGPoint(x: 0, y: self.firstDesiredYOffset), animated: true)
    case .upDown, .downUp:
        self.tableView.isUserInteractionEnabled = false
        self.secondDesiredYOffset = self.firstDesiredYOffset + myCloseToCellOffset
        self.tableView.setContentOffset(CGPoint(x: 0, y: self.firstDesiredYOffset), animated: true)
    case .unimportant:
        self.tableView.setContentOffset(CGPoint(x: 0, y: self.tableView.contentOffset.y + myCloseToCellOffset), animated: true)
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.