Ana*_*att 8 ios ios5 ios6 uicollectionview uicollectionviewcell
我在每个单元格中都有一个带UIImageView的UICollectionView,现在我想添加Copy Callout,就像在Photos.app中一样:

我在UICollectionViewDelegate中看到了这个方法:
- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
Run Code Online (Sandbox Code Playgroud)
经过几分钟的研究后,我找到了UIMenuController类,据我所知,我必须使用它来获取菜单,但无论如何,我认为必须有更简单的方法然后创建UIGestureRecognizer,创建,定位等我的UIMenu.
我是在正确的轨道上吗?你怎么能实现这个功能?
Pau*_*olt 18
是的,你走在正确的轨道上.您还可以使用此技术实现除剪切,复制和粘贴之外的自定义操作.
// ViewController.h
@interface ViewController : UICollectionViewController
// ViewController.m
-(void)viewDidLoad
{
[super viewDidLoad];
self.collectionView.delegate = self;
UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"Custom Action"
action:@selector(customAction:)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObject:menuItem]];
}
#pragma mark - UICollectionViewDelegate methods
- (BOOL)collectionView:(UICollectionView *)collectionView
canPerformAction:(SEL)action
forItemAtIndexPath:(NSIndexPath *)indexPath
withSender:(id)sender {
return YES; // YES for the Cut, copy, paste actions
}
- (BOOL)collectionView:(UICollectionView *)collectionView
shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)collectionView:(UICollectionView *)collectionView
performAction:(SEL)action
forItemAtIndexPath:(NSIndexPath *)indexPath
withSender:(id)sender {
NSLog(@"performAction");
}
#pragma mark - UIMenuController required methods
- (BOOL)canBecomeFirstResponder {
// NOTE: The menu item will on iOS 6.0 without YES (May be optional on iOS 7.0)
return YES;
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
NSLog(@"canPerformAction");
// The selector(s) should match your UIMenuItem selector
if (action == @selector(customAction:)) {
return YES;
}
return NO;
}
#pragma mark - Custom Action(s)
- (void)customAction:(id)sender {
NSLog(@"custom action! %@", sender);
}
Run Code Online (Sandbox Code Playgroud)
注意:iOS 7.0会更改行为
在您的UICollectionViewCell子类中,您需要添加自定义操作方法,否则不会显示任何内容.
// Cell.m
#import "Cell.h"
@implementation Cell
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// custom logic
}
return self;
}
- (void)customAction:(id)sender {
NSLog(@"Hello");
if([self.delegate respondsToSelector:@selector(customAction:forCell:)]) {
[self.delegate customAction:sender forCell:self];
}
}
@end
Run Code Online (Sandbox Code Playgroud)您需要创建一个委托协议并在每个单元格上设置它以回调到维护UICollectionView的UIController.这是因为单元格对模型没有任何意义,因为它只涉及显示内容.
// Cell.h
#import <UIKit/UIKit.h>
@class Cell; // Forward declare Custom Cell for the property
@protocol MyMenuDelegate <NSObject>
@optional
- (void)customAction:(id)sender forCell:(Cell *)cell;
@end
@interface Cell : UICollectionViewCell
@property (strong, nonatomic) UILabel* label;
@property (weak, nonatomic) id<MyMenuDelegate> delegate;
@end
Run Code Online (Sandbox Code Playgroud)在您的ViewController或UICollectionViewController的子类中,您需要符合协议并实现新方法.
// ViewController.m
@interface ViewController () <MyMenuDelegate>
@end
// @implementation ViewController ...
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
Cell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"MY_CELL" forIndexPath:indexPath];
cell.delegate = self;
return cell;
}
// ...
// Delegate method for iOS 7.0 to get action from UICollectionViewCell
- (void)customAction:(id)sender forCell:(Cell *)cell {
NSLog(@"custom action! %@", sender);
}
Run Code Online (Sandbox Code Playgroud)

可选:在UIView子类中,如果在此处实现canPerformAction方法,则可以覆盖默认的Cut,Copy,Paste,而不是在UIViewController中.否则,该行为将在您的自定义方法之前显示默认方法.
// Cell.m
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
NSLog(@"canPerformAction");
// The selector(s) should match your UIMenuItem selector
NSLog(@"Sender: %@", sender);
if (action == @selector(customAction:)) {
return YES;
}
return NO;
}
Run Code Online (Sandbox Code Playgroud)

Ana*_*att 10
这是完整的解决方案:
- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
if ([NSStringFromSelector(action) isEqualToString:@"copy:"])
return YES;
else
return NO;
}
- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
if ([NSStringFromSelector(action) isEqualToString:@"copy:"]) {
UIPasteboard *pasteBoard = [UIPasteboard pasteboardWithName:UIPasteboardNameGeneral create:NO];
pasteBoard.persistent = YES;
NSData *capturedImageData = UIImagePNGRepresentation([_capturedPhotos objectAtIndex:indexPath.row]);
[pasteBoard setData:capturedImageData forPasteboardType:(NSString *)kUTTypePNG];
}
}
Run Code Online (Sandbox Code Playgroud)
在我的情况下,我只允许在我的CollectionView中使用复制功能,如果按下复制,我将复制单元格内的图像到PasteBoard.
也许有点晚了但我可能会找到一个更好的解决方案,仍然搜索这个:
在你的UICollectionViewController的viewDidLoad中添加你的项目:
UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"Title" action:@selector(action:)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObject:menuItem]];
Run Code Online (Sandbox Code Playgroud)
添加以下委托方法:
//This method is called instead of canPerformAction for each action (copy, cut and paste too)
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
if (action == @selector(action:)) {
return YES;
}
return NO;
}
//Yes for showing menu in general
- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
Run Code Online (Sandbox Code Playgroud)
如果你还没有UICollectionViewCell的子类.添加为项目指定的方法:
- (void)action:(UIMenuController*)menuController {
}
Run Code Online (Sandbox Code Playgroud)
这样您就不需要任何becomeFirstResponder或其他方法.如果您将单元格本身作为参数调用一般方法,则可以在一个位置执行所有操作,并且可以轻松处理不同的单元格.
编辑:不知何故,uicollectionview需要存在此方法(此方法不会调用您的自定义操作,我认为uicollectionview只检查存在)
- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7928 次 |
| 最近记录: |