カスタムカレンダーコントロール

6328 ワード

前言#


カレンダーコントロールは旅行、教育、車の予約、学習などのアプリでよく使われていますが、システムのNSCalendarコントロールは私たちのプロジェクトのニーズを満たすことができないことが多いので、「サードパーティのカレンダーコントロールが私たちのニーズを満たすことができるかどうか」と思って、やっとサードパーティを見つけましたが、次に頭が痛くなりました.サードパーティには以下の問題があるかもしれません.1、サードパーティのカレンダーコントロールがこんなに多いのに、どれを使うべきですか?2、サードパーティのコントロールは一般的に多くの機能を統合していますが、私はその中の小さな機能を使っているだけで、彼のような多くのファイルを統合しますか?3、サードパーティのコントロールがバージョンの更新に遭遇した場合、私たちはまた更新しなければなりません.もし何かバグがあれば、もっと損をしません.などの欠点がありますか.
そこで、自分のプロジェクトで使用するカレンダーコントロールについて、自分に合ったプロジェクトをカスタマイズすることをお勧めします.では、どのようにカスタマイズしますか?
詳細コードはdemoを直接ダウンロードして表示してください:プロジェクトに直接ドラッグして使用できます-カスタムカレンダー-LZBCalendar

カレンダーコントロールをカスタマイズする方法#####


一、全体構造分析###


一般的なカレンダーコントロールには、3つのセクションがあります.1.年月の選択(下図頭部)2.曜日(真ん中の頭)3.日付(下の日付)
常用カレンダー構造png

二、カレンダーを分析するにはどうすればいいですか。


1、頭部は簡単で、ボタンをクリックして月を切り替え、年月を取得すればよい(一般的には現在の年と現在の月を取得する)
 - (NSDateComponents *)getDateComponentsFromDate:(NSDate *)date
 {
    NSDateComponents *component = [[NSCalendar currentCalendar] components:
                             (NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:date];
    return component;
  }

2、曜日のスタイルは固定されており、これは自分で配列を設定することができ、日付を保存するスタイルは中国語@[@"日",@"一",@"二",@"三",@"四",@"五",@"六",English
3、日付コントロールはUICOLLectionViewを採用するが、いくつかの問題を解決しなければならない:A、何個のUICOLLectionView Cellを採用するか、異なる個数のUICOLLectionView CellがUICOLLectnViewの高さを決定するか?解決:1ヶ月に何日かかるかを知っていれば、最低何個のUIcollectionViewCellが必要かを知っています.
  date 
- (NSInteger)totalDaysThisMonth:(NSDate *)date
 {
   NSRange range = [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];
   return range.length;
}

今月の1日目が何曜日なのかを知ることで、前に何個空いているべきかを知ることができます.
   1 , cell
 - (NSInteger)firstDayInFirstWeekThisMonth:(NSDate *)date
{
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar setFirstWeekday:1];
NSDateComponents *comp = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:date];
comp.day = 1;
NSDate *firstDayOfMonthDate = [calendar dateFromComponents:comp];
NSUInteger firstWeekday = [calendar ordinalityOfUnit:NSCalendarUnitWeekday inUnit:NSCalendarUnitWeekOfMonth forDate:firstDayOfMonthDate];
return firstWeekday-1;
}

前のいくつのcellを求めて、限界法で知っていて、cellは全部でどれだけあることができます
#define limitation_Low  28
#define limitation_Medium  35
#define limitation_High  42

B、cellの高さを決め、UIcollectionViewの高さを算出し、高さをコールバックして使う
//collectinView 
  NSInteger marginDays = [self firstDayInFirstWeekThisMonth:self.style.today];
NSInteger itemCount = marginDays + [self totalDaysThisMonth:self.style.today];
CGFloat collectionViewHeight = 0;
if(itemCount <= limitation_Low)
    collectionViewHeight = limitation_Low/self.style.weekDateDays.count *self.itemHeight;
else if(itemCount > limitation_Low && itemCount <=limitation_Medium)
    collectionViewHeight = limitation_Medium/self.style.weekDateDays.count *self.itemHeight;
else
    collectionViewHeight = limitation_High/self.style.weekDateDays.count *self.itemHeight;
self.collectionView.frame = CGRectMake(0, 0, self.bounds.size.width, collectionViewHeight);
self.contentView.frame = CGRectMake(0, CGRectGetMaxY(self.headerView.frame), self.bounds.size.width, collectionViewHeight);

三、カレンダー全体の設計と使用


1、カレンダーのスタイル設定が多いので、カレンダーの基本スタイルを設定するには、LZBCalendarAppearStyleなど、別のクラスを使用することをお勧めします.
2、カスタムUIcollectionViewCell、タイトルの詳細label(自分のプロジェクトの必要に応じて)を含めるべき
3、datasourceデータソース方式でカレンダーの表示スタイルを設定し、nilを返すとデフォルトパラメータを表示する
@property (nonatomic, weak)  id dataSource;
- (NSString *)calendar:(LZBCalendar *)calendar titleForDate:(NSDate *)date;
- (NSString *)calendar:(LZBCalendar *)calendar subtitleForDate:(NSDate *)date;

4、delegate方式によるコールバック応答イベント
- (BOOL)calendar:(LZBCalendar *)calendar shouldSelectDate:(NSDate *)date;
- (void)calendar:(LZBCalendar *)calendar didSelectDate:(NSDate *)date;

LZBCalendarの使い方##


1、コントロールの作成
 - (LZBCalendar *)calendar
{
   if(_calendar == nil)
{
  _calendar = [[LZBCalendar alloc]initWithStyle:self.style];
  _calendar.dataSource = self;
  _calendar.delegate = self;
}
return _calendar;
}
 - (LZBCalendarAppearStyle *)style
{
  if(_style == nil)
 {
  _style = [[LZBCalendarAppearStyle alloc]init];  // 
  _style.isNeedCustomHeihgt = YES;   // cell 
 }
  return _style;
}

2、データソースを呼び出す方法を実現し、カレンダーの高さを更新しなければならない
 - (void)calendar:(LZBCalendar *)calendar layoutCallBackHeight:(CGFloat)height
{
   self.calendar.frame = CGRectMake(0, 100, [UIScreen mainScreen].bounds.size.width, height);
}

3、データソースのスタイル変更-(NSString*)calendar:(LZBCalendar*)calendaartitleForDate:(NSDate*)dateを取得するか{////現在の月比較if([[ NSDate date]getDateWithMonth]==[date getDateWithMonth]){NSInteger result=[[NSDate date]getDateWithDay]-[date getDateWithDay];switch(result){case 0:return@今日";break;case 1:case;case 1:case;case 1:case;case 1:case;case 1:case;case 1:case;case 1:careturn@「昨日」;break;case-1:return@「明日」;break;
        default:
            return nil;
            break;
    }
}
else
    return nil;
}
- (NSString *)calendar:(LZBCalendar *)calendar subtitleForDate:(NSDate *)date
{
NSInteger result = [date getDateWithDay];
switch (result) {
    case 1:
        return @"10";
        break;
    case 2:
        return @"20";
        break;
    case 3:
        return @" ";
        break;
    default:
        return nil;
        break;
   }
 }

4、代理応答イベント
- (void)calendar:(LZBCalendar *)calendar didSelectDate:(NSDate *)date
{
NSLog(@" :%s------ :line-%d ",__func__, __LINE__);  
 }

結果:
カレンダーを選択します.png
注意:プロジェクトに直接ドラッグ&ドロップ詳細コードを使用するにはdemoを直接ダウンロードしてください:カスタムカレンダー-LZBCalendar

最後のメッセージ


文章が役に立つと思ったら、starを忘れないでね!starはプログラム猿への最大の励ましです!