I will admit that there is already a question exactly along these lines here on S.O., but it lacks implementation details, a working answer, and I would like to be more specific, so I think a new question is in order. Obviously, let me know if I'm wrong and we can try to restart the thread over there.
Basically, I want to copy the text in a UILabel to the pasteboard when a user holds down on the label. Not hard to do, honestly. However, I think the best way to provide visual feedback is to prompt the user with the Copy menu option from UIMenuController
.
According to the Event Handling section of the iPhone Application Programming Guide, specifically the section on Copy, Cut, and Paste Operations, it should be possible to provide copy, cut, and/or paste operations from a custom view.
So, I've sub-classed UILabel with the following implementation as described by the guide, but the UIMenuController won't show up. There's no indication in the guide that there's anything else required to do this, and the NSLog statement does print out to the console, indicating that the selector is being performed when I hold down on the label:
//
// CopyLabel.m
// HoldEm
//
// Created by Billy Gray on 1/20/10.
// Copyright 2010 Zetetic LLC. All rights reserved.
//
#import "CopyLabel.h"
@implementation CopyLabel
- (void)showCopyMenu {
NSLog(@"I'm tryin' Ringo, I'm tryin' reeeeal hard.");
// bring up editing menu.
UIMenuController *theMenu = [UIMenuController sharedMenuController];
// do i even need to show a selection? There's really no point for my implementation...
// doing it any way to see if it helps the "not showing up" problem...
CGRect selectionRect = [self frame];
[theMenu setTargetRect:selectionRect inView:self];
[theMenu setMenuVisible:YES animated:YES]; // <-- doesn't show up...
}
// obviously, important to provide this, but whether it's here or not doesn't seem
// to change the fact that the UIMenuController view is not showing up
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
BOOL answer = NO;
if (action == @selector(copy:))
answer = YES;
return answer;
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self performSelector:@selector(showCopyMenu) withObject:nil afterDelay:0.8f];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showCopyMenu) object:nil];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showCopyMenu) object:nil];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showCopyMenu) object:nil];
}
@end
So, what else does one have to do to make this happen?
For those following along and trying to do this, too, you'll also need to set 'User Interaction Enabled' for the label
Edit:
For clarity, let me add that this should be similar to the little [Copy] menu item that appears over an image in certain iphone views when you hold down on it. -B