2012-10-11 6 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 

감사 handleLongPress:에서

답변

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

당신은 액션 시트 제스처 인식기를 할당합니다.

[actionSheet addGestureRecognizer:recognizer]; 

이유는 모르겠지만 제스처 인식기는 단일보기에서만 사용할 수 있습니다. 이 할당은 아마도 표 셀에서 제스처 인식기를 제거하므로 테이블 셀의 길게 눌러 제스처가 더 이상 작동하지 않습니다.