I recently added to my app the ability to long-press on a UILabel inside a table cell to make the "Copy" menu appear so the user can copy the text to the pasteboard. It works great both in the simulator and when I build directly to a device. However, when I build & archive (so I can push to TestFlight) the feature does not work.
I attempted the solution in this Stack Overflow question but it didn't work (and doesn't seem relevant since I'm building for iOS 5.0+). I have Optimization Level set to None [-O0]
in Build Settings.
Here's the relevant code (although I'm 90% sure the issue is not this code but some Xcode setting):
Adding the Gesture Recognizer:
UIGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handleLongPressForCopy:)];
[_postLabel addGestureRecognizer:longPress];
[self addSubview:_postLabel];
Handle Long Press
- (void)handleLongPressForCopy:(UILongPressGestureRecognizer *)recognizer {
switch (recognizer.state) {
case UIGestureRecognizerStateBegan:
NSAssert([self becomeFirstResponder], @"Sorry, UIMenuController will not work with %@ since it cannot become first responder", self);
UIMenuController *theMenu = [UIMenuController sharedMenuController];
CGRect displayRect = CGRectMake(_postLabel.frame.origin.x, _postLabel.frame.origin.y, 10, 0);
[theMenu setTargetRect:displayRect inView:self];
[theMenu setMenuVisible:YES animated:YES];
break;
default:
break;
}
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
return (action == @selector(copy:) );
}
As I said, it works great building to the device and in the simulator, just not after Build & Archive.
The NSAssert
method was not called in the release build, because the -DNS_BLOCK_ASSERTIONS
flag was enabled for release builds.
In the above code, I fixed the issue by moving [self becomeFirstResponder]
to its own line, assigning the return value to a BOOL, and then calling NSAssert on the BOOL.