How to get notified of UITableViewCell move start and end?
Your UITableViewDelegate will receive the following notifications in response to reordering actions:
- (void)tableView:(UITableView *)tableView willBeginReorderingRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didEndReorderingRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didCancelReorderingRowAtIndexPath:(NSIndexPath *)indexPath;
How to detect the end of loading of UITableView
Improve to @RichX answer:lastRow
can be both [tableView numberOfRowsInSection: 0] - 1
or ((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row
.
So the code will be:
-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if([indexPath row] == ((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row){
//end of loading
//for example [activityIndicator stopAnimating];
}
}
UPDATE:
Well, @htafoya's comment is right. If you want this code to detect end of loading all data from source, it wouldn't, but that's not the original question. This code is for detecting when all cells that are meant to be visible are displayed. willDisplayCell:
used here for smoother UI (single cell usually displays fast after willDisplay:
call). You could also try it with tableView:didEndDisplayingCell:
.
Detect drag event of UITableViewCell
While Bala's comment went into the right direction, I initially had some problems with the right implementation. Now I found out how it can be done. In short: You have to create a custom subclass of UITableViewCell
. Override layoutSubviews
to attach a UILongPressGestureRecognizer
to UITableViewCellReorderControl
. Define a protocol and use a delegate to inform whoever you want to about the dragging state.
CustomTableViewCell.h:
#import <UIKit/UIKit.h>
@protocol CustomTableViewCellDelegate;
@interface CustomTableViewCell : UITableViewCell {
}
@property (nonatomic, assign) id <CustomTableViewCellDelegate> delegate;
@end
@protocol CustomTableViewCellDelegate
- (void)CustomTableViewCell:(CustomTableViewCell *)cell isDragging:(BOOL)value;
@end
CustomTableViewCell.m:
#import "CustomTableViewCell.h"
@implementation CustomTableViewCell
@synthesize delegate = _delegate;
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
[_delegate CustomTableViewCell:self isDragging:YES]; // Dragging started
} else if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
[_delegate CustomTableViewCell:self isDragging:NO]; // Dragging ended
}
}
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *view in self.subviews) {
if ([NSStringFromClass ([view class]) rangeOfString:@"ReorderControl"].location != NSNotFound) { // UITableViewCellReorderControl
if (view.gestureRecognizers.count == 0) {
UILongPressGestureRecognizer *gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
gesture.cancelsTouchesInView = NO;
gesture.minimumPressDuration = 0.150;
[view addGestureRecognizer:gesture];
}
}
}
}
@end
Be aware that while this code doesn't use any private APIs it still might stop working if Apple changes its internal implementation (i.e. by changing the classname of UITableViewCellReorderControl
).
How do I notify the UITableViewController of events from a UITableViewCell subclass?
Using a delegate is a good pattern to use for this. Your custom cell class should define a protocol and a delegate property. The view controller should set itself as the cell's delegate and the view controller should implement the cell's protocol method(s). Make sure one of the parameters of the protocol methods is the cell.
The view controller can ask the table view for the index path of the cell if that is needed. There is no need for the cell to know its index path. Since rows and sections can be added/deleted, it is bad form for a cell to be told what its index path since it could change at any time.
iOS - Detect UITableViewCell being moved out of the visible view?
On versions of iOS older than 6.0, the table view doesn't send the tableView:didEndDisplayingCell:forRowAtIndexPath:
message.
If you are using a subclass of UITableViewCell
, you can get the same effect on older versions of iOS by overriding didMoveToWindow
:
- (void)didMoveToWindow {
if (self.window == nil) {
// I have been removed from the table view.
}
}
You may need to give your cell a (weak or unsafe_unretained) reference back to your table view delegate so you can send the delegate a message.
However, you can't rely only on didMoveToWindow
for all versions of iOS. Before iOS 6, a table view always removed a table view cell as a subview before reusing it, so the cell would always receive didMoveToWindow
before being reused. However, starting in iOS 6, a table view can reuse a cell without removing it as a subview. The table view will simply change the cell's frame to move it to its new location. This means that starting in iOS 6, a cell does not always receive didMoveToWindow
before being reused.
So you should implement both didMoveToWindow
in your cell subclass, and tableView:didEndDisplayingCell:forRowAtIndexPath:
in your delegate, and make sure it works if both are called, or if just one is called.
Related Topics
Locking a Uisearchbar to the Top of a Uitableview Like Game Center
Uiview Touch Event in Controller
Swift Protocol Get Only Settable
iOS - Integrating Credit Card Payments
How to Create Static Library and Can Add Just .A File on Any Project in iOS
Why Is My iOS App Not Showing Up in Other Apps' "Open In" Dialog
iOS - 'Myproject-Swift.H' File Not Found When Running Unit Tests for Swift
Cookie Sharing Between Multiple Wkwebviews
Find Current Country from iPhone Device
Disable Magnification Gesture in Wkwebview
Uifont - How to Get System Thin Font
iOS - Ensure Execution on Main Thread
How to Retrieve Facebook Response Using Facebook iOS Sdk
The Document Main.Storyboard Requires Xcode 8.0 or Later
iOS - Swift - Function That Returns Asynchronously Retrieved Value
Uniquely Identifying an iOS User