Is there a simple way for subclasses of UITableViewCell to show the 'Copy' UIMenuController popup like in the Address book app (see screenshot), after the selection is held for a while?
views:
458answers:
2
+3
A:
The normal method is to get the UIMenuController's shared instance, set the target rect and view and call -setMenuVisible:animated:
. Remeber to implement -canPerformAction:withSender:
in your responder.
The undocumented method is to implement these 3 methods in your data source (see http://iphonedevwiki.net/index.php/UITableViewDataSource).
-(void)tableView:(UITableView*)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath*)indexPath withSender:(id)sender;
-(BOOL)tableView:(UITableView*)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath*)indexPath withSender:(id)sender;
-(BOOL)tableView:(UITableView*)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath*)indexPath;
KennyTM
2010-03-21 18:39:45
Thanks! The undocumented method is exactly what I was looking for. The "official" method is rather clunky. Hopefully it becomes documented soon.It isn't ideal that it is undocumented, but in this case it's just implementing the protocol, not calling a method, so hopefully it's safe(er).
William Denniss
2010-03-22 03:56:21
+2
A:
Your UITableViewCell subclass may look like this
@interface MenuTableViewCell : UITableViewCell {
}
- (IBAction)copy:(id)sender;
- (void)showMenu;
@end
@implementation MenuTableViewCell
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(copy:)) {
return YES;
}
return NO;
}
- (IBAction)copy:(id)sender {
}
- (void)showMenu {
[[UIMenuController sharedMenuController] setMenuVisible:NO animated:YES];
[self becomeFirstResponder];
[[UIMenuController sharedMenuController] update];
[[UIMenuController sharedMenuController] setTargetRect:CGRectZero inView:self];
[[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
}
@end
And the UITableView delegate methods are like
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
MenuTableViewCell *cell = (MenuTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[MenuTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MenuTableViewCell *cell = (MenuTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
[cell showMenu];
}
zonble
2010-03-23 01:29:52
Thanks for the answer. This is a good way to do it "officially" I guess, but what I don't like is that it shows the Copy view when selected, where as the Address Book app shows the copy view when held for X seconds. This isn't an issue with your solution, but rather with the API. Thanks very much for your help.
William Denniss
2010-03-23 06:00:17