简体   繁体   中英

Row selection doesn't work on first tap after scroll in a non-bouncing UITableView

Basically the problem I'm seeing seems like an Apple bug. The problem is after scrolling the table, the first tap on any row only highlights it. A second tap is needed to actually select or deselect it. I noticed that this problem happens most of the time. Very few times it will work as expected, but I haven't noticed any pattern as to when it works.

This issue only happens if theTableView.bounces = NO; otherwise, it works perfectly.

I verified this by implementing the appropriate delegate methods.

First tap on any row after scrolling, I get these call backs

-(BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
-(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
-(void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath

Subsequent taps on the same or a different row after scrolling, I get these call backs

-(BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
-(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
-(void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath

//then

-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
//or
-(NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath

I have seen other similar questions, but all of them are using a table inside another scroll view, which isn't the case here.

Has anyone found a fix or a workaround for this? I tried on iOS 7.0 ... 8.2 and the problem is present on all of them.

Thanks!

After a lot more testing, I found that the problem happens when the table's contentOffset.y reaches maximum value or 0. So I created my own "bouncing effect" but on a much smaller scale by implementing scrollViewWillEndDragging:withVelocity:targetContentOffset: in the table view's delegate as follows:

-(void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
    targetContentOffset->y = MAX(targetContentOffset->y -1, 1);
}

With that in place, the problem disappeared. It's a workaround but works like a charm!

Swift 4 syntax of this comment :

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    targetContentOffset.pointee.y = max(targetContentOffset.pointee.y - 1, 1)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM