Question

In my app i have a viewcontroller with a calendar in it (CKCalendar). Only one month is shown at the same time and with scrolling one can switch months. On certain days in the calendar are events which a highlighted by a circle.

Months are switched with the code

- (void) nextMonth:(UISwipeGestureRecognizer *)swipe {
[self.calView moveCalendarToNextMonth];
[self drawItemsForCurrentMonth];
}

The method drawItemsForCurrentMonth calls the next piece of code for every items that needs highlighting.

AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];

NSArray* res = [self calculateDayCirclePosition:date];

CGFloat x = [[res objectAtIndex:0] floatValue] + (DEFAULT_CELL_WIDTH-DEFAULT_CIRCLE_WIDTH-CELL_BORDER_WIDTH)/2;
CGFloat y = [[res objectAtIndex:1] floatValue] + (DEFAULT_CELL_HEIGHT-DEFAULT_CIRCLE_WIDTH)/2;

AgendaCircleView* circleView = [[AgendaCircleView alloc] initWithFrame:CGRectMake(x,y,self.circleWidth,self.circleWidth)];

circleView.date = date;
AgendaViewController* avc;

if([appDelegate.viewController.frontViewController isKindOfClass:[UINavigationController class]]) {
    UINavigationController* navVC = (UINavigationController*)appDelegate.viewController.frontViewController;
    avc = (AgendaViewController*)[navVC visibleViewController];
}

UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:avc action:@selector(didSelectDate:)];

tapGesture.enabled = YES;
tapGesture.delegate = avc;
tapGesture.numberOfTapsRequired = 1;
tapGesture.numberOfTouchesRequired = 1;

[circleView addGestureRecognizer:tapGesture];
circleView.userInteractionEnabled = YES;

circleView.alpha = 0.5;
circleView.layer.cornerRadius = (self.circleWidth/2);

if(fill) {
    circleView.backgroundColor = [appDelegate.dataController.rijschoolItem getColor1];
}
else {
    circleView.layer.borderWidth = 1.0f;
    circleView.backgroundColor = [UIColor clearColor];
    circleView.layer.borderColor = [UIColor whiteColor].CGColor;
}

[circleView setNeedsDisplay];

[self.calendarContainer addSubview:circleView];

[self.calendarContainer bringSubviewToFront:circleView];

[self.calendarContainer setUserInteractionEnabled:YES];

This code works fine when the viewcontroller is initialized. Clicking on the circle fires the didSelectDate method. However when i change months the tapgesturerecognizer does not work anymore. When months are changed i use the exact same code that is used when initializing the viewcontroller. The strange thing is that when i open an other detailed viewcontroller and throw it on the view stack and go back, it is working again.

I've tried to use

gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer but this does not solve the problem.

Furthermore i've tried to use setNeedsLayout but this is not working either.

Any ideas?

Was it helpful?

Solution

Ok, I found the problem. So for others who might encounter the same type of problem. You have to make sure that the view is not animating while adding the gesturerecognizers.

I had this block of code

[UIView animateWithDuration:0.4 animations:^{
   calendar.alpha = 1.0;
}];

[self drawItemsForCurrentMonth];

changed into

[UIView animateWithDuration:0.4 animations:^{
    calendar.alpha = 1.0;
} completion:^(BOOL finished) {
    if(finished) {
        [self drawItemsForCurrentMonth];
    }
}];

Having the method drawItemsForCurrentMonth after the animation block does not necessarily guarantee that the block is has actually finished. Luckily there is a completion block which covers that aspect.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top