我正在使用UIMenuItem
在UICollectionView
单元长按中执行自定义操作。
这与iOS 6完美配合,但现在我将我的应用程序转换为iOS 7和Xcode 5,但它无法正常工作。自定义项目未显示。
UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"Unfavorite"
action:@selector(unFavorite:)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObject:menuItem]];
[UIMenuController sharedMenuController].menuVisible = YES;
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender;
{
//do not show default itens like copy, paste....
[self becomeFirstResponder];
return NO;
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
// The selector(s) should match your UIMenuItem selector
if (action == @selector(unFavorite:)) {
return YES;
}
return NO;
}
- (void)collectionView:(UICollectionView *)collectionView
performAction:(SEL)action
forItemAtIndexPath:(NSIndexPath *)indexPath
withSender:(id)sender {
}
- (BOOL)collectionView:(UICollectionView *)collectionView
shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath {
myIndexPath = indexPath;
return YES;
}
答案 0 :(得分:8)
我不知道iOS 6,但在iOS 7中它非常简单。您只需要三个标准集合视图委托菜单处理方法,以及单元子类中的操作方法。没有必要与第一响应者或类似的东西一起玩。所以,例如(在这个例子中,Copy是一个标准项目,但是我已经添加到菜单中):
// collection view delegate:
- (BOOL)collectionView:(UICollectionView *)collectionView
shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath {
UIMenuItem* mi = [[UIMenuItem alloc] initWithTitle:@"Capital"
action:NSSelectorFromString(@"capital:")];
[[UIMenuController sharedMenuController] setMenuItems:@[mi]];
return YES;
}
- (BOOL)collectionView:(UICollectionView *)collectionView
canPerformAction:(SEL)action
forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
return (action == NSSelectorFromString(@"copy:") ||
action == NSSelectorFromString(@"capital:"));
}
- (void)collectionView:(UICollectionView *)collectionView
performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath
withSender:(id)sender {
// in real life, would do something here
NSString* state = (self.sectionData)[indexPath.section][indexPath.row];
if (action == NSSelectorFromString(@"copy:"))
NSLog(@"copying %@", state);
else if (action == NSSelectorFromString(@"capital:"))
NSLog(@"fetching the capital of %@", state);
}
// cell subclass:
-(void)capital:(id)sender {
// find my collection view
UIView* v = self;
do {
v = v.superview;
} while (![v isKindOfClass:[UICollectionView class]]);
UICollectionView* cv = (UICollectionView*) v;
// ask it what index path we are
NSIndexPath* ip = [cv indexPathForCell:self];
// talk to its delegate
if (cv.delegate &&
[cv.delegate respondsToSelector:
@selector(collectionView:performAction:forItemAtIndexPath:withSender:)])
[cv.delegate collectionView:cv performAction:_cmd
forItemAtIndexPath:ip withSender:sender];
}
答案 1 :(得分:1)
我使用类似StackOverflow问题中的图像和示例更新了我的iOS 7.0解决方案。
我使用ARC和委托的弱引用。似乎适用于iOS 6.0和iOS 7.0
答案 2 :(得分:1)
我在UICollectionView上添加了一个searchBar,其中UIMenuController的结果是MIA。经过两天的试用和错误我认为终于找到了一种方法让它发挥作用。
问题(在iOS7上运行):
我认为使其工作的诀窍是从searchBar中明确删除第一响应者状态:
- (void)longPressGestureDetected:(UILongPressGestureRecognizer *)gesture {
if(gesture.state == UIGestureRecognizerStateBegan) {
CGPoint touchPoint = [gesture locationInView:gesture.view];
NSInteger index = [self.collectionView indexPathForItemAtPoint:touchPoint].item;
if(index >= 0 && index < self.documents.count) {
// dismiss searchBar
[self.searchBar resignFirstResponder];
[self becomeFirstResponder];
// select the right document
//[self.documentManager selectDocumentWithIndex:index];
// show menu
UIMenuController *menu = [UIMenuController sharedMenuController];
menu.menuItems = [self defaultMenuItems];
[menu setTargetRect:CGRectMake(touchPoint.x, touchPoint.y, 0, 0) inView:gesture.view];
[gesture.view becomeFirstResponder];
[menu update];
[menu setMenuVisible:YES animated:YES];
}
}
当然,控制器中也有这些响应者状态方法:
- (BOOL)canBecomeFirstResponder { return YES; }
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
if(action == @selector(renameDocument:)) {
return YES;
} else {
return NO;
}
}
- (NSArray*)defaultMenuItems {
// add menu items
UIMenuItem *renameItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Rename", @"Rename Menu Item") action:@selector(renameDocument:)];
return @[renameItem];
}
答案 3 :(得分:0)
在NibCell.h中
@protocol CellToVCDelegate <NSObject>
@optional
- (void)deleteActivity:(id)sender ;
- (void)shareActivity:(id)sender;
@end
@interface NibCell : UICollectionViewCell{
id <CellToVCDelegate> delegate;
}
@property (nonatomic, retain) id <CellToVCDelegate> delegate;
在NibCell.m
#pragma mark - Custom Action(s)
- (void)deleteActivity:(id)sender {
NSLog(@"delete action! %@", sender);
[self.delegate deleteActivity:sender];
}
- (void)shareActivity:(id)sender {
NSLog(@"shareActivity action! %@", sender);
[self.delegate shareActivity:sender];
}
在集合VC.h中
@interface VC : UIViewController <
CellToVCDelegate>
VC.m中的:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NibCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cvCellIdentifier
forIndexPath:indexPath];
cell.delegate = self;
return cell;
}