2013-11-07 2 views
2

Ive пытался изменить репозиторий, https://github.com/PeteC/DSLCalendarView, чтобы пользователь мог выбрать дату начала и окончания, нажав и автоматически выбрав даты между ними. Я достиг этого, выполнив следующий код в демонстрационной версии:Пользовательская реализация DSLCalendarView для Excel, например, календарь

Проблема заключается в том, что она прерывает первоначальную реализацию перетаскивания по календарю, чтобы выбрать диапазон дат.

Любая помощь/руководство приветствуется, также если вы знаете о любой другой библиотеке, которая достигает того же самого, я буду очень благодарен. Функциональность, которую я ищу, это: Позвольте пользователю выбрать первую дату, последнюю дату и показать даты в середине как выбор.

в ViewController.m

- (DSLCalendarRange*)calendarView:(DSLCalendarView *)calendarView didDragToDay:(NSDateComponents *)day selectingRange:(DSLCalendarRange *)range { 

    if (!self.startDate) { 

     //  self.startDate = [self.dateFormatter dateFromString:[NSString stringWithFormat:@"%d/%d/%d",range.startDay.month, range.startDay.day,range.startDay.year]]; 
     //self.startDate = range.s 

     self.startDate = range.startDay; 

     self.hasSelectedStartDate = YES; 

     return [[DSLCalendarRange alloc] initWithStartDay:self.startDate endDay:self.startDate]; 



     NSLog(@"start date set to: %@",self.startDate); 
    } 
    else if (self.startDate && !self.endDate) 
    { 

     //self.endDate = [self.dateFormatter dateFromString:[NSString stringWithFormat:@"%d/%d/%d",range.startDay.month, range.startDay.day,range.startDay.year]]; 
     self.endDate = range.endDay; 

     NSLog(@"Start date is: %@",self.startDate); 
     NSLog(@"end date set to: %@",self.endDate); 

     return [[DSLCalendarRange alloc] initWithStartDay:self.startDate endDay:self.endDate]; 


    } else if (self.startDate && self.endDate) 
    { 
     return [[DSLCalendarRange alloc] initWithStartDay:self.startDate endDay:self.endDate]; 

     self.hasSelectedStartDate = NO; 
    } 
    NSLog(@"Select range programattically"); 

} 

В DSLCalendarView.m, я добавил следующий фрагмент кода touchedEnded дополнить выше реализации:

//added code: Aakash 
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
//added condition here besides the other code 
if ([self.delegate respondsToSelector:@selector(hasSelectedStartDate)]) { 
    self.flag = [self.delegate performSelector:@selector(hasSelectedStartDate)]; 
    NSLog(@"Value: %hhd",self.flag); 
} 

if (!self.draggedOffStartDay && [self.draggingStartDay isEqual:touchedView.day] && !self.flag) { 
self.selectedRange = [[DSLCalendarRange alloc] initWithStartDay:touchedView.day endDay:touchedView.day]; 
} 

Исходный код для обработки прикосновения :

#pragma mark - Touches 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    DSLCalendarDayView *touchedView = [self dayViewForTouches:touches]; 
    if (touchedView == nil) { 
     self.draggingStartDay = nil; 
     return; 
    } 

    self.draggingStartDay = touchedView.day; 
    self.draggingFixedDay = touchedView.day; 
    self.draggedOffStartDay = NO; 

    DSLCalendarRange *newRange = self.selectedRange; 
    if (self.selectedRange == nil) { 
     newRange = [[DSLCalendarRange alloc] initWithStartDay:touchedView.day endDay:touchedView.day]; 
    } 
    else if (![self.selectedRange.startDay isEqual:touchedView.day] && ![self.selectedRange.endDay isEqual:touchedView.day]) { 
     newRange = [[DSLCalendarRange alloc] initWithStartDay:touchedView.day endDay:touchedView.day]; 
    } 
    else if ([self.selectedRange.startDay isEqual:touchedView.day]) { 
     self.draggingFixedDay = self.selectedRange.endDay; 
    } 
    else { 
     self.draggingFixedDay = self.selectedRange.startDay; 
    } 

    if ([self.delegate respondsToSelector:@selector(calendarView:didDragToDay:selectingRange:)]) { 
    newRange = [self.delegate calendarView:self didDragToDay:touchedView.day selectingRange:newRange]; 
    } 
    self.selectedRange = newRange; 

    [self positionCalloutViewForDayView:touchedView]; } 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    if (self.draggingStartDay == nil) { 
     return; 
    } 

    DSLCalendarDayView *touchedView = [self dayViewForTouches:touches]; 
    if (touchedView == nil) { 
     self.draggingStartDay = nil; 
     return; 
    } 

    DSLCalendarRange *newRange; 
    if ([touchedView.day.date compare:self.draggingFixedDay.date] == NSOrderedAscending) { 
     newRange = [[DSLCalendarRange alloc] initWithStartDay:touchedView.day endDay:self.draggingFixedDay]; 
    } 
    else { 
     newRange = [[DSLCalendarRange alloc] initWithStartDay:self.draggingFixedDay endDay:touchedView.day]; 
    } 

    if ([self.delegate respondsToSelector:@selector(calendarView:didDragToDay:selectingRange:)]) { 
     newRange = [self.delegate calendarView:self didDragToDay:touchedView.day selectingRange:newRange]; 
    } 
    self.selectedRange = newRange; 

    if (!self.draggedOffStartDay) { 
     if (![self.draggingStartDay isEqual:touchedView.day]) { 
      self.draggedOffStartDay = YES; 
     } 
    } 

    [self positionCalloutViewForDayView:touchedView]; } 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    if (self.draggingStartDay == nil) { 
     return; 
    } 

    DSLCalendarDayView *touchedView = [self dayViewForTouches:touches]; 
    if (touchedView == nil) { 
     self.draggingStartDay = nil; 
     return; 
    } 


    if (!self.draggedOffStartDay && [self.draggingStartDay isEqual:touchedView.day]) { 
    self.selectedRange = [[DSLCalendarRange alloc] initWithStartDay:touchedView.day endDay:touchedView.day]; 
    } 

    self.draggingStartDay = nil; 

    // Check if the user has dragged to a day in an adjacent month 
    if (touchedView.day.year != _visibleMonth.year || touchedView.day.month != _visibleMonth.month) { 
     // Ask the delegate if it's OK to animate to the adjacent month 
     BOOL animateToAdjacentMonth = YES; 
     if ([self.delegate respondsToSelector:@selector(calendarView:shouldAnimateDragToMonth:)]) { 
      animateToAdjacentMonth = [self.delegate calendarView:self shouldAnimateDragToMonth:[touchedView.dayAsDate dslCalendarView_monthWithCalendar:_visibleMonth.calendar]]; 
     } 

     if (animateToAdjacentMonth) { 
      if ([touchedView.dayAsDate compare:_visibleMonth.date] == NSOrderedAscending) { 
       [self didTapMonthBack:nil]; 
      } 
      else { 
       [self didTapMonthForward:nil]; 
      } 
     } 
    } 

    if ([self.delegate respondsToSelector:@selector(calendarView:didSelectRange:)]) { 
     [self.delegate calendarView:self didSelectRange:self.selectedRange]; 
    } 
    } 
+0

я нужен способ, чтобы добавить событие и событие дисплея в эту библиотеку, любое предложение –

+0

@ManicMonkOnMac есть вы реализовали это ..? Можете ли вы поделиться кодом [email protected] –

+0

Да, я его реализовал, я попытаюсь опубликовать соответствующий код, или я могу отправить вам всю измененную структуру на ваш идентификатор почты. Это было не так давно:/ – ManicMonkOnMac

ответ

1

Вы можете добиться этого из демонстрации Xample это сам,

просто ищет - (void)calendarView:(DSLCalendarView *)calendarView didSelectRange:(DSLCalendarRange *)range делегата в ViewController.m

заменить его с этим,

- (void)calendarView:(DSLCalendarView *)calendarView didSelectRange:(DSLCalendarRange *)range 
{ 
    if (range != nil) 
    { 
    if(startD == nil) { 
     if(endD == nil) { 
      [self start:nil]; 
     }else{ 
      [self end:nil]; 
     } 
    }else{ 
     if(endD == nil) { 
      [self end:nil]; 
     } 
    } 

    [self draw:nil]; 
} 

Теперь посмотрим на - (IBAction)draw:(id)sender в том же классе,

заменить его с этим ,

- (IBAction)draw:(id)sender { 
    if(startD && endD) { 
     [_calendarView setSelectedRange:[[DSLCalendarRange alloc] initWithStartDay:startD.startDay endDay:endD.endDay]]; 
     startD = nil; 
     endD = nil; 
    } 

    else if(startD) 
    [_calendarView setSelectedRange:[[DSLCalendarRange alloc] initWithStartDay:startD.startDay endDay:startD.endDay]]; 
    else if(endD) 
     [_calendarView setSelectedRange:[[DSLCalendarRange alloc] initWithStartDay:endD.startDay endDay:endD.endDay]]; 
} 
0

CXDurationPicker is t он самый близкий компонент, который я могу найти в календаре Excel. https://github.com/concurlabs/CXDurationPicker

Чтобы имитировать поведение сборщика календаря Excel, я также внес некоторые изменения.

  1. определить собственный делегат

    #pragma mark - CXDurationPickerViewDelegate 
    - (void)durationPicker:(CXDurationPickerView *)durationPicker 
         endDateChanged:(CXDurationPickerDate)pickerDate { 
    
        NSDate *firstDate = [CXDurationPickerUtils dateFromPickerDate:durationPicker.startDate]; 
        NSDate *secondDate = [CXDurationPickerUtils dateFromPickerDate:durationPicker.endDate]; 
    
        [self updateStartDate:firstDate EndDate:secondDate AtIndex:selectedId]; 
        [self dismissDatePicker:nil]; 
    } 
    
    - (void)durationPicker:(CXDurationPickerView *)durationPicker 
        singleDateChanged:(CXDurationPickerDate)pickerDate { 
        NSLog(@"singleDateChanged"); 
    } 
    
    - (void)durationPicker:(CXDurationPickerView *)durationPicker 
         startDateChanged:(CXDurationPickerDate)pickerDate { 
    
        durationPicker.endDate = durationPicker.startDate; 
        durationPicker.mode = CXDurationPickerModeEndDate; 
    } 
    
    #pragma mark - CXDurationPickerViewDelegate Optionals 
    
    - (void)durationPicker:(CXDurationPickerView *)durationPicker 
    invalidEndDateSelected:(CXDurationPickerDate)date { 
    
        NSLog(@"Invalid end date selected."); 
    
        durationPicker.startDate = durationPicker.endDate = date; 
        durationPicker.mode = CXDurationPickerModeEndDate; 
    } 
    
    - (void)durationPicker:(CXDurationPickerView *)durationPicker invalidStartDateSelected:(CXDurationPickerDate)date { 
        NSLog(@"Invalid start date selected."); 
        durationPicker.startDate = durationPicker.endDate = date; 
        durationPicker.mode = CXDurationPickerModeEndDate; 
    } 
    
    - (void)durationPicker:(CXDurationPickerView *)durationPicker 
        didSelectDateInPast:(CXDurationPickerDate)date 
           forMode:(CXDurationPickerMode)mode { 
    
        NSLog(@"Date was selected in the past. Ignoring."); 
    } 
    
  2. Обновить код в CXDurationPickerDayView.m, чтобы исправить проблемы с отображением, когда день начала и конца день в тот же день.

    --- a/Popsoc/CXDurationPicker/CXDurationPickerView.m 
    +++ b/Popsoc/CXDurationPicker/CXDurationPickerView.m 
    @@ -482,8 +482,12 @@ 
        day.type = CXDurationPickerDayTypeStart; 
    
        day = (CXDurationPickerDayView *) [self.days lastObject]; 
    
        day.type = CXDurationPickerDayTypeEnd; 
    + 
    + if (self.days.count == 1) { 
    +  day.type = CXDurationPickerDayTypeSingle; 
    + } 
    
0

я изменил библиотеку DSLCalendarView и он работает как шарм в обоих направлениях, 1. Выберите продолжительность перетаскивания 2. Expedia-как постукивание.

В файле DSLCalendarView.m найдите - (void) touchesEnded: (NSSet *) касается событияEvent: (UIEvent *); метод.В этом методе, вы найдете ниже, если заявление

if (!self.draggedOffStartDay && [self.draggingStartDay isEqual:touchedView.day]) { 
    // comment out this original code 
    // self.selectedRange = [[DSLCalendarRange alloc] initWithStartDay:touchedView.day endDay:touchedView.day]; 

    // add below code block 
    if (!self.startDate) { 
     self.startDate = self.draggingStartDay; 
     self.selectedRange = [[DSLCalendarRange alloc] initWithStartDay:self.draggingStartDay 
                   endDay:touchedView.day]; 
    } 
    else if (self.startDate && !self.endDate) { 
     self.endDate = touchedView.day; 
     self.selectedRange = [[DSLCalendarRange alloc] initWithStartDay:self.startDate 
                   endDay:touchedView.day]; 
    } 
    else if (self.startDate && self.endDate) { 
     self.startDate = self.draggingStartDay; 
     self.endDate = nil; 
     self.selectedRange = [[DSLCalendarRange alloc] initWithStartDay:self.draggingStartDay 
                   endDay:touchedView.day]; 
    } 
} 

Не забудьте объявить два глобальных ВАР @property (неатомический, сильный) NSDateComponents * STARTDATE; @property (неатомный, сильный) NSDateComponents * endDate; в том же файле.

Вы можете проверить результат, выполнив ниже метод делегата в своем VC.

#pragma mark - DSLCalendarViewDelegate methods 

- (void)calendarView:(DSLCalendarView *)calendarView didSelectRange:(DSLCalendarRange *)range { 
    if (range) { 
     NSLog(@"selected %ld/%ld/%ld - %ld/%ld/%ld", range.startDay.year, range.startDay.month, range.startDay.day, range.endDay.year, range.endDay.month, range.endDay.day); 
    } 
}