UIActionSheet 只显示一次
Posted
技术标签:
【中文标题】UIActionSheet 只显示一次【英文标题】:UIActionSheet only showing once 【发布时间】:2012-10-11 10:43:57 【问题描述】:我有以下生成 UICollectionView 的代码。当您长按 UICollectionViewCell 时,会出现 UIActionSheet。
这有效,但只有一次。如果您关闭 UIActionSheet 并再次长按同一单元格,则不会发生任何事情。
任何想法我做错了什么?
#import "ProjectsListViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface ProjectsListViewController ()
@end
@implementation ProjectsListViewController
@synthesize appDelegate;
- (void)viewDidLoad
[super viewDidLoad];
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
// CREATE THE COLLECTION VIEW
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[self setCollectionView:[[UICollectionView alloc] initWithFrame:CGRectMake(20, 54, [[self view] bounds].size.width - 40, [[self view] bounds].size.height) collectionViewLayout:flowLayout]];
[[self collectionView] setDataSource:self];
[[self collectionView] setDelegate:self];
[self.view addSubview:self.collectionView];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
[[self collectionView] setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section
return [[[appDelegate userSettingsDictionary] objectForKey:@"Projects"] count];
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView
return 1;
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
// CREATE A BACKGROUND VIEW FOR THE FOLDER IMAGE
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"folder.png"]];
UIView *background = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 122, 89)];
[background setBackgroundColor:[UIColor colorWithPatternImage:image]];
[cell addSubview:background];
// SET THE CELL TEXT
UILabel *cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 95, 130, 100)];
[cellLabel setText:[[[[[appDelegate userSettingsDictionary] objectForKey:@"Projects"] objectAtIndex:[indexPath row]] objectForKey:@"Project Name"] uppercaseString]];
// LISTEN FOR A LONG PRESS ON EACH FOLDER
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
[cell addGestureRecognizer:longPress];
[cell addSubview:cellLabel];
return cell;
// PRESENT AN ACTION SHEET WHEN A FOLDER HAS RECEIVED A LONG PRESS EVENT
- (void)handleLongPress:(UILongPressGestureRecognizer *)recognizer
if ( [recognizer state] == UIGestureRecognizerStateBegan )
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Select an action" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Delete" otherButtonTitles:@"Edit", nil];
[actionSheet addGestureRecognizer:recognizer];
// SET THE SELECTED FOLDER'S ROW NUMBER AS THE ACTIONSHEET TAG. JUST A WAY OF LETTING THE DELETE METHOD KNOW WHICH FOLDER TO DELETE
[actionSheet showInView:self.view];
// GET THE SIZE OF THE FOLDER IMAGE AND SET EACH COLLECTION VIEW ITEM SIZE TO FIT
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"folder.png"]];
return CGSizeMake(image.size.width, image.size.height + 50);
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
return UIEdgeInsetsMake(10, 10, 90, 10);
@end
谢谢
【问题讨论】:
【参考方案1】:实际上我不久前尝试过类似的方法,但发现几乎整个方法都是错误的。
首先:您设置单元格的方式并不好。因为单元格是可重用的,但现在每次集合视图请求特定单元格时都添加子视图。您应该继承 UICollectionViewCell
并在 initWithCoder:
方法中添加子视图。
然后只需在子类上为文本字段创建一个属性。然后在collectionView:cellForItemAtIndexPath:
中将文本设置为标签text
属性。
现在让我们修复手势识别器。您不应该为每个UICollectionViewCell
设置一个手势识别器,而应该只为一个全局识别器。在viewDidLoad:
你应该添加:
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
[self.collectionView addGestureRecognizer:longPress];
那么你应该把handleLongPress:
改成这样:
- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture
if (gesture.state == UIGestureRecognizerStateBegan)
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:[gesture locationInView:self.collectionView]];
if (indexPath != nil)
self.currentIndexPath = indexPath;
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Select an action" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Delete" otherButtonTitles:@"Edit", nil];
UICollectionViewCell *itemCell = [self.collectionView cellForItemAtIndexPath:indexPath];
[action showFromRect:CGRectMake(0, 0, itemCell.frame.size.width, itemCell.frame.size.height) inView:itemCell animated:YES];
请注意,我没有添加将识别器添加到操作表的行,我不明白您为什么要这样做。您还应该添加一个名为 currentIndexPath
的属性。
此时应正确设置所有内容。当您从操作表中获得响应时,只需使用 self.currentIndexPath
来确定要删除/编辑的项目。
【讨论】:
多么棒的回复。这解决了我的问题,以及我遇到的其他几个问题。非常感谢您的帮助。【参考方案2】:在handleLongPress:
中,您将手势识别器分配给操作表。
[actionSheet addGestureRecognizer:recognizer];
我不知道你为什么这样做,但手势识别器只能用于单个视图。此分配可能会从表格视图单元格中删除手势识别器,因此表格单元格上的长按手势不再起作用。
【讨论】:
以上是关于UIActionSheet 只显示一次的主要内容,如果未能解决你的问题,请参考以下文章
如何知道视图层次结构中是不是显示 UIActionSheet?
在 UIAlertView 上显示 UIActionSheet