我想滚动到我的UITableView中靠近我的一个单元格的位置。
我这个代码执行此操作:
myTableView.scrollToRow(at: index,at: .top, animated: true)
并在动画完成后我做:
myTableView.setContentOffset(CGPoint(x: 0, y: myTableView.contentOffset.y + myCloseToCellOffset), animated: true)
然而问题是动画被分成两个动画,因此不能顺利运行。反正有没有把它变成一个动画?或者任何其他方式来获得我想要的结果?
在我看来,只有当两个动画的方向相同时,两个动画之间的这种令人不快的停顿才是令人不快的。当它不同时(首先,然后向下)它看起来很好。所以我提出以下建议(也许有一个更简单的解决方案,但这就是我的想法):
myTableView.scrollToRow(at: index,at: .top, animated: true)
自己实现的偏移量。myCloseToCellOffset
的方向相同,只需将myCloseToCellOffset
添加到其中并直接调用myTableView.setContentOffset(CGPoint(x: 0, y: myTableView.contentOffset.y + (initalOffset + myCloseToCellOffset), animated: true)
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)
}
}