Header in Swift 的 TableView 的自定义分页大小(一次滚动一个单元格)
Custom Paging Size for TableView with Header in Swift (Scroll One Cell At a Time)
我有一个包含多个部分的 UITableView,每个部分都有一个 header。 table 的大小使得一个 header 和一个单元格占据了 table 的整个框架。我想允许用户一次只滚动 table 一个单元格。当我设置 paging = enabled 时,滚动不会按预期工作,因为 table 一次滚动整个 table 帧,而不是一次滚动一个单元格。这会导致不希望的偏移量随着您滚动 table 而不断变大。
到目前为止,我的研究表明我需要覆盖 scrollViewWillBeginDragging。参见示例 UITableView with custom paging-like behaviour。但是我读到的关于这个话题的每个 post 肯定都在 Swift 之前,因为它都在 Objective C.
中
请建议 Swift 代码以完成带有 header 节的 table 视图的单个单元格分页。尽管可能需要禁用分页本身,但解决方案应尽可能接近真正的分页。
下面是我 table 尺码的代码。 table 的帧大小是 475。
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if (condition == true) {
return CGFloat(425)
}
else {
return CGFloat(375)
}
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if (condition == true) {
return CGFloat(47)
}
else {
return CGFloat(90)
}
}
更新: 这里的最佳答案 (Force UITableView to Scroll to Tops of Cells) 似乎也很相关。但是,同样,这一切都在 Objective C 中。如果这些链接中的任何一个答案被证明是正确的,将该答案简单翻译成 Swift 就足够了。
更新 2 我几乎明白了。但是边缘情况不起作用(即,在 table 的最顶部和最底部)。也就是说,我得到一个 paging-like 滚动动作,除非我尝试向下滚动到 table 中的最后一个单元格。没有捕捉到最后一个单元格。它只是正常滚动。我怀疑它与最后一个单元格的 frame.origin.y 有关。
请帮我找出这些边缘情况。代码如下:
viewDidLoad() {
self.tableView.decelerationRate = UIScrollViewDecelerationRateFast
}
var lastContentOffset:CGPoint!
var initialIndexPath:NSIndexPath?
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
lastContentOffset = CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y)
var visibleCellIndexes = tableView.indexPathsForVisibleRows() as! [NSIndexPath]
initialIndexPath = visibleCellIndexes[0]
}
var scrolledToPath:NSIndexPath?
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if (scrollView == self.tableView) {
var lastIndexPath:NSIndexPath!
var nextIndexPath:NSIndexPath!
if let p = scrolledToPath {
lastIndexPath = scrolledToPath
}
else if let u = initialIndexPath {
lastIndexPath = initialIndexPath
}
if (lastContentOffset.y <= scrollView.contentOffset.y) {
// scrolling down
if (lastIndexPath.row == numRows(lastIndexPath.section)-1) {
// last row in section
if (lastIndexPath.section == numSections(self.tableView)-1) {
// last section
nextIndexPath = lastIndexPath
}
else {
nextIndexPath = NSIndexPath(forRow: 0, inSection: lastIndexPath.section+1)
}
}
else {
nextIndexPath = NSIndexPath(forRow: lastIndexPath.row+1, inSection: lastIndexPath.section)
}
}
else if (lastContentOffset.y > scrollView.contentOffset.y) {
// scrolling up
if (lastIndexPath.row == 0) {
// first row in section
if (lastIndexPath.section == 0) {
// first section
nextIndexPath = lastIndexPath
}
else {
nextIndexPath = NSIndexPath(forRow: numRows(lastIndexPath.section-1)-1, inSection: lastIndexPath.section-1)
}
}
else {
nextIndexPath = NSIndexPath(forRow: lastIndexPath.row-1, inSection: lastIndexPath.section)
}
}
scrolledToPath = nextIndexPath
var headerHeight = CGFloat(47)
if (condition == true) {
headerHeight = CGFloat(90)
}
var rectOfNextIndexPath:CGRect = self.tableView.rectForRowAtIndexPath(nextIndexPath)
targetContentOffset.memory.y = rectOfNextIndexPath.origin.y - headerHeight
}
}
已修复。在我的 tableview 中调整大小弄乱了最终案例。在我确定单元格大小正确后,效果很好。下面是swift.
中tableview的page-like scrolling的解决方案
viewDidLoad() {
self.tableView.decelerationRate = UIScrollViewDecelerationRateFast
}
var lastContentOffset:CGPoint!
var initialIndexPath:NSIndexPath?
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
lastContentOffset = CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y)
var visibleCellIndexes = tableView.indexPathsForVisibleRows() as! [NSIndexPath]
initialIndexPath = visibleCellIndexes[0]
}
var scrolledToPath:NSIndexPath?
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
var lastIndexPath:NSIndexPath!
var nextIndexPath:NSIndexPath!
if let p = scrolledToPath {
lastIndexPath = scrolledToPath
}
else if let u = initialIndexPath {
lastIndexPath = initialIndexPath
}
if (lastContentOffset.y <= scrollView.contentOffset.y) {
// scrolling down
if (lastIndexPath.row == numRows(lastIndexPath.section)-1) {
// last row in section
if (lastIndexPath.section == numSections(self.tableView)-1) {
// last section
nextIndexPath = lastIndexPath
}
else {
nextIndexPath = NSIndexPath(forRow: 0, inSection: lastIndexPath.section+1)
}
}
else {
nextIndexPath = NSIndexPath(forRow: lastIndexPath.row+1, inSection: lastIndexPath.section)
}
}
else if (lastContentOffset.y > scrollView.contentOffset.y) {
// scrolling up
if (lastIndexPath.row == 0) {
// first row in section
if (lastIndexPath.section == 0) {
// first section
nextIndexPath = lastIndexPath
}
else {
nextIndexPath = NSIndexPath(forRow: numRows(lastIndexPath.section-1)-1, inSection: lastIndexPath.section-1)
}
}
else {
nextIndexPath = NSIndexPath(forRow: lastIndexPath.row-1, inSection: lastIndexPath.section)
}
}
scrolledToPath = nextIndexPath
var headerHeight = CGFloat(47)
if (condition == true) {
headerHeight = CGFloat(90)
}
var rectOfNextIndexPath:CGRect = self.tableView.rectForRowAtIndexPath(nextIndexPath)
targetContentOffset.memory.y = rectOfNextIndexPath.origin.y - headerHeight
}
我有一个包含多个部分的 UITableView,每个部分都有一个 header。 table 的大小使得一个 header 和一个单元格占据了 table 的整个框架。我想允许用户一次只滚动 table 一个单元格。当我设置 paging = enabled 时,滚动不会按预期工作,因为 table 一次滚动整个 table 帧,而不是一次滚动一个单元格。这会导致不希望的偏移量随着您滚动 table 而不断变大。
到目前为止,我的研究表明我需要覆盖 scrollViewWillBeginDragging。参见示例 UITableView with custom paging-like behaviour。但是我读到的关于这个话题的每个 post 肯定都在 Swift 之前,因为它都在 Objective C.
中请建议 Swift 代码以完成带有 header 节的 table 视图的单个单元格分页。尽管可能需要禁用分页本身,但解决方案应尽可能接近真正的分页。
下面是我 table 尺码的代码。 table 的帧大小是 475。
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if (condition == true) {
return CGFloat(425)
}
else {
return CGFloat(375)
}
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if (condition == true) {
return CGFloat(47)
}
else {
return CGFloat(90)
}
}
更新: 这里的最佳答案 (Force UITableView to Scroll to Tops of Cells) 似乎也很相关。但是,同样,这一切都在 Objective C 中。如果这些链接中的任何一个答案被证明是正确的,将该答案简单翻译成 Swift 就足够了。
更新 2 我几乎明白了。但是边缘情况不起作用(即,在 table 的最顶部和最底部)。也就是说,我得到一个 paging-like 滚动动作,除非我尝试向下滚动到 table 中的最后一个单元格。没有捕捉到最后一个单元格。它只是正常滚动。我怀疑它与最后一个单元格的 frame.origin.y 有关。
请帮我找出这些边缘情况。代码如下:
viewDidLoad() {
self.tableView.decelerationRate = UIScrollViewDecelerationRateFast
}
var lastContentOffset:CGPoint!
var initialIndexPath:NSIndexPath?
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
lastContentOffset = CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y)
var visibleCellIndexes = tableView.indexPathsForVisibleRows() as! [NSIndexPath]
initialIndexPath = visibleCellIndexes[0]
}
var scrolledToPath:NSIndexPath?
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if (scrollView == self.tableView) {
var lastIndexPath:NSIndexPath!
var nextIndexPath:NSIndexPath!
if let p = scrolledToPath {
lastIndexPath = scrolledToPath
}
else if let u = initialIndexPath {
lastIndexPath = initialIndexPath
}
if (lastContentOffset.y <= scrollView.contentOffset.y) {
// scrolling down
if (lastIndexPath.row == numRows(lastIndexPath.section)-1) {
// last row in section
if (lastIndexPath.section == numSections(self.tableView)-1) {
// last section
nextIndexPath = lastIndexPath
}
else {
nextIndexPath = NSIndexPath(forRow: 0, inSection: lastIndexPath.section+1)
}
}
else {
nextIndexPath = NSIndexPath(forRow: lastIndexPath.row+1, inSection: lastIndexPath.section)
}
}
else if (lastContentOffset.y > scrollView.contentOffset.y) {
// scrolling up
if (lastIndexPath.row == 0) {
// first row in section
if (lastIndexPath.section == 0) {
// first section
nextIndexPath = lastIndexPath
}
else {
nextIndexPath = NSIndexPath(forRow: numRows(lastIndexPath.section-1)-1, inSection: lastIndexPath.section-1)
}
}
else {
nextIndexPath = NSIndexPath(forRow: lastIndexPath.row-1, inSection: lastIndexPath.section)
}
}
scrolledToPath = nextIndexPath
var headerHeight = CGFloat(47)
if (condition == true) {
headerHeight = CGFloat(90)
}
var rectOfNextIndexPath:CGRect = self.tableView.rectForRowAtIndexPath(nextIndexPath)
targetContentOffset.memory.y = rectOfNextIndexPath.origin.y - headerHeight
}
}
已修复。在我的 tableview 中调整大小弄乱了最终案例。在我确定单元格大小正确后,效果很好。下面是swift.
中tableview的page-like scrolling的解决方案viewDidLoad() {
self.tableView.decelerationRate = UIScrollViewDecelerationRateFast
}
var lastContentOffset:CGPoint!
var initialIndexPath:NSIndexPath?
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
lastContentOffset = CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y)
var visibleCellIndexes = tableView.indexPathsForVisibleRows() as! [NSIndexPath]
initialIndexPath = visibleCellIndexes[0]
}
var scrolledToPath:NSIndexPath?
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
var lastIndexPath:NSIndexPath!
var nextIndexPath:NSIndexPath!
if let p = scrolledToPath {
lastIndexPath = scrolledToPath
}
else if let u = initialIndexPath {
lastIndexPath = initialIndexPath
}
if (lastContentOffset.y <= scrollView.contentOffset.y) {
// scrolling down
if (lastIndexPath.row == numRows(lastIndexPath.section)-1) {
// last row in section
if (lastIndexPath.section == numSections(self.tableView)-1) {
// last section
nextIndexPath = lastIndexPath
}
else {
nextIndexPath = NSIndexPath(forRow: 0, inSection: lastIndexPath.section+1)
}
}
else {
nextIndexPath = NSIndexPath(forRow: lastIndexPath.row+1, inSection: lastIndexPath.section)
}
}
else if (lastContentOffset.y > scrollView.contentOffset.y) {
// scrolling up
if (lastIndexPath.row == 0) {
// first row in section
if (lastIndexPath.section == 0) {
// first section
nextIndexPath = lastIndexPath
}
else {
nextIndexPath = NSIndexPath(forRow: numRows(lastIndexPath.section-1)-1, inSection: lastIndexPath.section-1)
}
}
else {
nextIndexPath = NSIndexPath(forRow: lastIndexPath.row-1, inSection: lastIndexPath.section)
}
}
scrolledToPath = nextIndexPath
var headerHeight = CGFloat(47)
if (condition == true) {
headerHeight = CGFloat(90)
}
var rectOfNextIndexPath:CGRect = self.tableView.rectForRowAtIndexPath(nextIndexPath)
targetContentOffset.memory.y = rectOfNextIndexPath.origin.y - headerHeight
}