Erik
Erik

Reputation: 2530

Can't tap UICollectionView item

I'm building an app whereas I've got a UICollectionView with a custom layout. I have a problem whereas I cannot tap some rows. Here's an overview over what happens

1) App starts and presents a UICollectionView

2) 3 test items are displayed, using the visual debugger in Xcode, you can see that there is something not right with the hierarchy

enter image description here

The red row can't be tapped now, but the yellow and green rows can.

3) User taps the yellow item, and segues to another page

4) User pops the shown UIViewController and returns to the UICollectionView whereas the viewWillAppear method reloads the UICollectionView like so:

[self.collectionView reloadData];

5) Re-entering the visual debugger shows that the hierarchy seems shifted, and the yellow row is now untappable, but the red and green rows can be tapped.

What could be the reason for this? I'll post any relevant code, ask for what parts you'd like to see.

enter image description here

Update

The UIViewController displaying the UICollectionView

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
ShareViewCell *view = [collectionView dequeueReusableCellWithReuseIdentifier:@"share" forIndexPath:indexPath];
view.share = [self.sharesController shareAtIndex:indexPath.item];
return view;
}

Custom cell:

- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {

    self.leftBorderView = [UIView new];
    [self.contentView addSubview:self.leftBorderView];

    self.label = [UILabel new];
    self.label.font = [UIFont boldSystemFontOfSize:10];
    self.label.numberOfLines = 0;
    self.label.lineBreakMode = NSLineBreakByWordWrapping;
    [self.contentView addSubview:self.label];
}
return self;
}

- (void)layoutSubviews
{
[super layoutSubviews];

self.leftBorderView.frame = CGRectMake(0, 0, 1.5, self.bounds.size.height);
CGSize labelSize = [self.label sizeThatFits:CGSizeMake(self.bounds.size.width - 10.0f, MAXFLOAT)];

NSTimeInterval durationOfShare = [self.share.endSpan timeIntervalSinceDate:self.share.startSpan] / 3600;

CGFloat middleOfCell = self.bounds.size.height / 2;
CGFloat yPositionToUse = middleOfCell - (labelSize.height / 2);

if (durationOfShare < 0.25)
{
    [self.label setHidden:YES];// to small to be shown
} else if (durationOfShare > 0.5)
{
    yPositionToUse = 8; // show it at the top
}

self.label.frame = CGRectMake(8, yPositionToUse, labelSize.width, labelSize.height);
}

Update 2

Is the UICollectionReusableView blocking tap of the UICollectionViewCell?

enter image description here

Upvotes: 0

Views: 1628

Answers (1)

Vinzzz
Vinzzz

Reputation: 11724

Ok,

First, you should be more precise in your question : you're using some code found on some question on StackOverflow.

The code seems to be this Calendar UI made with UICollectionView. This is a sample code, quickly built for the sake of a StackOverflow answer (with a bounty). It's not finished, has no contributors, and you should try to read it and improve over it !

From your debugger's captures, it seems you have some view which overlays on top of your collectionView's cells. From reading this code, I see it uses some supplementary view to present 'hour' blocks. This supplementary view class is HourReusableView. And it's the view coming on top on your debugger's captures

CalendarViewLayout is responsible to compute these supplementary views frame, as it does for colored event blocks (see method - (void)prepareLayout)

I might bet that these supplementary views's Z-order isn't predictable - all views have a default zIndex of 0. One way to fix it ? After line 67 of this file, set a negative zIndex on the UICollectionViewLayoutAttributes of the hour block. This way, you make sure hour supplementary views are always behind your cells, and don't intercept the cell's touch

Upvotes: 2

Related Questions