2012-10-11 84 views
0

我有下面的代码,它产生一个UICollectionView。当您在UICollectionViewCell上长按时,会出现UIActionSheet。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 

感谢

回答

5

我前段时间试过类似的东西,发现几乎整个方法都是错误的。

开始:你设置你的细胞的方式不好。因为单元格是可重用的,但现在每次收集视图要求特定单元格时添加子视图。您应该子类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来确定要删除/编辑的项目。

+0

真是个好回复。这解决了我的问题,以及我遇到的其他问题。非常感谢您的帮助。 – Typhoon101

1

handleLongPress:您指定的手势识别的动作片。

[actionSheet addGestureRecognizer:recognizer]; 

我不知道你为什么这么做,但手势识别器只能用于单个视图。此分配可能会从表格视图单元格中移除手势识别器,以便表格单元格上的长按手势不再起作用。