0

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

ありがとう

4

2 に答える 2

5

私は実際に少し前に似たようなことを試してみましたが、ほぼ全体のアプローチが間違っていることがわかりました。

まず、セルの設定方法が良くありません。セルは再利用可能ですが、コレクション ビューが特定のセルを要求するたびにサブビューを追加するようになりました。メソッドでサブビューをサブクラス化UICollectionViewCellし、追加する必要がありinitWithCoder:ます。

次に、テキスト フィールドのサブクラスにプロパティを作成します。次にcollectionView:cellForItemAtIndexPath:、テキストを labelstextプロパティに設定するだけです。

それでは、ジェスチャ認識機能を修正しましょう。それぞれにジェスチャ認識エンジンを設定するのではなく、UICollectionViewCellグローバルなものを 1 つだけ設定する必要があります。に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て削除/編集するアイテムを特定します。

于 2012-10-11T14:44:07.517 に答える
1

ジェスチャレコグナイザーをアクションシートにhandleLongPress:割り当てます。

[actionSheet addGestureRecognizer:recognizer];

なぜそうするのかわかりませんが、ジェスチャレコグナイザーは単一のビューでのみ使用できます。この割り当てにより、ジェスチャレコグナイザがテーブルビューセルから削除される可能性があるため、テーブルセルでの長押しジェスチャは機能しなくなります。

于 2012-10-11T12:42:29.643 に答える