2014-10-07 16 views
18

Trên ios8 tôi đang sử dụng bộ điều khiển xem bảng dữ liệu lõi và sau khi xóa các hàng, phần chân trang của phần của tôi đột nhiên đi xuống dưới cùng của UITableView. Khi tôi cuộn chế độ xem bảng, chế độ xem chân trang sẽ quay lại vị trí của nó. Làm thế nào có thể khắc phục điều này và tại sao điều này lại xảy ra?Vị trí xem chân trang của phần UITableView sau endUpdate

Đây là mã chỉ trong trường hợp.

- (void)controller:(NSFetchedResultsController *)controller 
    didChangeObject:(id)anObject 
     atIndexPath:(NSIndexPath *)indexPath 
    forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath *)newIndexPath 
{  
    if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext) 
    { 
     switch(type) 
     { 
      case NSFetchedResultsChangeInsert: 
       [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
       break; 

      case NSFetchedResultsChangeDelete: 
       [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; 
       break; 

      case NSFetchedResultsChangeUpdate: 
       [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
       break; 

      case NSFetchedResultsChangeMove: 
       [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
       [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
       break; 
     } 
    } 
} 

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{ 
    if (self.beganUpdates) 
    { 
     [self.tableView endUpdates]; 
    } 
} 
+0

kiểm tra bài đăng này http://stackoverflow.com/questions/5740518/uitableview-footer-stop-from- nổi trên nội dung –

+0

Tôi đã gửi [Radar] (https://openradar.appspot.com/radar?id=6187705981468672) về vấn đề này. Tôi đề nghị tất cả các bạn làm tốt nếu bạn muốn điều này cố định. Dupes rất thuyết phục. – gurooj

Trả lời

3

Tôi vừa gặp phải vấn đề tương tự. Khi tôi sử dụng insertRowsAtIndexPaths .. footer đi đến phía dưới. Cũng nhận thấy rằng nếu bạn gọi reloadData trên bàn xem nó sẽ khắc phục vấn đề vì vậy tôi đã làm điều này:

[CATransaction begin]; 
[CATransaction setCompletionBlock: ^{ 
    // Code to be executed upon completion 
    [tableView reloadData]; 
}]; 

[tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationLeft]; 
[CATransaction commit]; 

Tất cả nó làm là tải lại bàn khi các hình ảnh động chèn kết thúc ... Nó không phải là một giải pháp thực tế, giống như tránh vấn đề nhưng nó ẩn vấn đề cho đến khi ai đó giải thích tại sao nó lại xảy ra và cách khắc phục nó ...

+0

yea, bạn cũng có thể làm điều này để tránh điều này (tốt hơn sau đó tải lại dữ liệu, nhưng nó cũng khá cheesy quá): [self.tableView setContentOffset: CGPointMake (self.tableView.contentOffset.x, self.tableView.contentOffset.y- 1)]; – t0a0

11

Đây là thay đổi hoạt ảnh trên iOS 8. Bạn phải thay đổi kiểu xem bảng thành 'được nhóm' để giữ chân trang của phần chuyển sang phần khởi động của uitableview

+1

Cảm ơn, giải pháp này đã làm việc cho tôi. Bạn có liên kết nơi tài liệu này được ghi chép không? –

+0

Giải pháp này nghe có vẻ giống hack hơn là cách giải quyết vấn đề phù hợp. – RaffAl

1

Tôi đã gặp phải vấn đề tương tự và dành rất nhiều công sức để cố gắng giải quyết nó. Và bây giờ, cuối cùng!

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 

     NATask *task = sections[indexPath.section][indexPath.row]; 
     [sections[indexPath.section] removeObjectAtIndex:indexPath.row]; 
     [appDelegate.managedObjectContext deleteObject:task]; 

     [CATransaction begin]; 
     [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 

     UIView *footerView = [tableView footerViewForSection:indexPath.section]; 
     CABasicAnimation *animation = [[footerView.layer animationForKey:@"position"] mutableCopy]; 
     CGPoint fromValue = [(NSValue *)animation.fromValue CGPointValue]; 
     animation.toValue = [NSValue valueWithCGPoint:CGPointMake(0, fromValue.y - 44)]; 
     [footerView.layer removeAnimationForKey:@"position"]; 
     [footerView.layer addAnimation:animation forKey:@"position"]; 
     dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, .4 * NSEC_PER_SEC); 
     dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
      [tableView reloadData]; 
     }); 

     [CATransaction commit]; 
    } 
} 

Tất nhiên, đây không phải là giải pháp lý tưởng nhất, nhưng nó hoạt động! Tôi gần như hai tuần vật lộn với vấn đề này, tôi hy vọng, ít nhất, là hữu ích cho một ai đó.

0

Tôi đã gặp sự cố tương tự. Không ai trong số các câu trả lời cho đến nay đã cho tôi chính xác những gì tôi đang tìm kiếm. Đặt chế độ xem bảng thành 'được nhóm' không phải là hành vi tôi muốn và các giải pháp khác vẫn dẫn đến chân trang ở cuối chế độ xem bảng cho đến khi reloadData được gọi, chúng đột ngột chụp lại vị trí chính xác.

Dưới đây là giải pháp của tôi giúp bạn dễ dàng chuyển đến vị trí cần thiết.

NSIndexPath* iPath = [NSIndexPath indexPathForRow:_lineItemArray.count-1 inSection:0]; 

// Calculate the Y position of the bottom of the footer within the table view frame. 
CGFloat footerBaseY = (_footer.y + _footer.height) - _sTableView.contentOffset.y; 
// Calculate the Y position of the bottom taking into account the bottom content inset. 
CGFloat tableViewContentBottomY = _sTableView.height - _sTableView.contentInset.bottom; 

if (footerBaseY < tableViewContentBottomY) { 
    [_sTableView insertRowsAtIndexPaths:@[iPath] withRowAnimation:UITableViewRowAnimationBottom]; 
    [UIView animateWithDuration:0.3 
        animations:^{ 
         CGFloat y = _lineItemArray.count * [_sTableView rectForRowAtIndexPath:iPath].size.height; 
         CGFloat newBaseY = (y + _footer.height) - _sTableView.contentOffset.y; 

         if (newBaseY < tableViewContentBottomY) { 
          _footer.y = y; 
         } else { 
          // The footer is within a cell's height away from the bottom. Subtract the diff from the new y. 
          _footer.y = y - (newBaseY - tableViewContentBottomY); 
         } 
        } completion:^(BOOL finished) { 
         // This ensures that the bottom row animates up if the footer was within a cell's height away from the bottom. 
         [_sTableView scrollToRowAtIndexPath:iPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 
        }]; 
} else { 
    // The footer was already at the bottom of the vew so I'm animating the added row up. 
    [_sTableView insertRowsAtIndexPaths:@[iPath] withRowAnimation:UITableViewRowAnimationBottom]; 
    [_sTableView scrollToRowAtIndexPath:iPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 
} 
0

Tôi vẫn cần chế độ xem đầu trang và chân trang của phần được dính. Vì vậy mà thay vì thay đổi phong cách tableview để nhóm lại, tôi chỉ đơn giản là đã làm một reloadSection sau khi xóa các hàng ...

Các vấn đề liên quan