Go to list of users who liked
Share on X(Twitter)
Share on Facebook
More than 5 years have passed since last update.
↑のようにスワイプで切り替えれるようなカレンダーを。
ひとまずswiftの試しが主目的ですが、swiftらしくない部分もあるかもしれません。
試し試しで実装した所があるのでベストな実装とは思えないので、
もう少し暖めようかと思ったのですが、ひとまずちょっと公開してみることにしました。
Xcode 6.1.1にて実装しました。
1.構成
・各日を表示するView(DayViewとします。)
・各月を表示するView(MonthViewとします。)
・月を切り替えるためのView(CalenderViewとします。)
この3つのViewを扱うようにします。
2.DayViewについて
曜日に合わせて表示を切り替えるなど想定されるため、
year/month/day/week
の四つの情報を取得するようにしています。
classDayView:UIView{requiredinit(coderaDecoder:NSCoder){fatalError("init(coder:) has not been implemented")}init(frame:CGRect,year:Int,month:Int,day:Int,weekday:Int){super.init(frame:frame)vardayWidth:Int=Int((UIScreen.mainScreen().bounds.size.width)/7.0)vardayHeight:CGFloat=30vardayLabel:UILabel=UILabel(frame:CGRectMake(0,0,CGFloat(dayWidth),dayHeight))dayLabel.textAlignment=NSTextAlignment.CenterdayLabel.text=String(format:"%02d",day)ifweekday==1{//日曜日は赤dayLabel.textColor=UIColor.redColor()}elseifweekday==7{//土曜日は青dayLabel.textColor=UIColor.blueColor()}self.addSubview(dayLabel)}}3.MonthViewについて
その月の最終日の取得や曜日、第何週目かの取得を行い、
DayViewを表示させています。
ざっくりですが、各DayViewの横幅は、frameのwidthを7で割った商を扱っています。
classMonthView:UIView{requiredinit(coderaDecoder:NSCoder){fatalError("init(coder:) has not been implemented")}init(frame:CGRect,year:Int,month:Int){super.init(frame:frame)self.setUpDays(year,month:month)}funcsetUpDays(year:Int,month:Int){varsubViews:[UIView]=self.subviewsas[UIView]forviewinsubViews{ifview.isKindOfClass(DayView){view.removeFromSuperview()}}varday:Int?=self.getLastDay(year,month:month);vardayWidth:Int=Int(frame.size.width/7.0)vardayHeight:Int=dayWidth+5ifday!=nil{//初日の曜日を取得varweekday:Int=self.getWeekDay(year,month:month,day:1)forvari:Int=0;i<day!;i++{varweek:Int=self.getWeek(year,month:month,day:i+1)varx:Int=((weekday-1)*(dayWidth));vary:Int=(week-1)*dayHeightvarframe:CGRect=CGRectMake(CGFloat(x),CGFloat(y),CGFloat(dayWidth),CGFloat(dayHeight));vardayView:DayView=DayView(frame:frame,year:year,month:month,day:i+1,weekday:weekday)self.addSubview(dayView)weekday++ifweekday>7{weekday=1}}}}//その月の最終日の取得funcgetLastDay(varyear:Int,varmonth:Int)->Int?{vardateFormatter:NSDateFormatter=NSDateFormatter();dateFormatter.dateFormat="yyyy/MM/dd";ifmonth==12{month=0year++}vartargetDate:NSDate?=dateFormatter.dateFromString(String(format:"%04d/%02d/01",year,month+1));iftargetDate!=nil{//月初から一日前を計算し、月末の日付を取得varorgDate=NSDate(timeInterval:(24*60*60)*(-1),sinceDate:targetDate!)varstr:String=dateFormatter.stringFromDate(orgDate)//lastPathComponentを利用するのは目的として違う気も。。returnstr.lastPathComponent.toInt();}returnnil;}//曜日の取得funcgetWeek(year:Int,month:Int,day:Int)->Int{vardateFormatter:NSDateFormatter=NSDateFormatter();dateFormatter.dateFormat="yyyy/MM/dd";vardate:NSDate?=dateFormatter.dateFromString(String(format:"%04d/%02d/%02d",year,month,day));ifdate!=nil{varcalendar:NSCalendar=NSCalendar.currentCalendar()vardateComp:NSDateComponents=calendar.components(NSCalendarUnit.WeekOfMonthCalendarUnit,fromDate:date!)returndateComp.weekOfMonth;}return0;}//第何週の取得funcgetWeekDay(year:Int,month:Int,day:Int)->Int{vardateFormatter:NSDateFormatter=NSDateFormatter();dateFormatter.dateFormat="yyyy/MM/dd";vardate:NSDate?=dateFormatter.dateFromString(String(format:"%04d/%02d/%02d",year,month,day));ifdate!=nil{varcalendar:NSCalendar=NSCalendar.currentCalendar()vardateComp:NSDateComponents=calendar.components(NSCalendarUnit.WeekdayCalendarUnit,fromDate:date!)returndateComp.weekday;}return0;}}4.CalenderViewについて
こちらでは、ScrollViewを配置し、その上に3つのMonthViewを配置するのみとしています。
この3つの表示をスクロールに合わせて表示を切り替えるような形で想定しています。
こちら参考させていただきました。
http://cocoadays.blogspot.jp/2010/09/1.html
classCalenderView:UIView,UIScrollViewDelegate{varcurrentYear:Int=0varcurrentMonth:Int=0varcurrentDay:Int=0varscrollView:UIScrollView!varprevMonthView:MonthView!varcurrentMonthView:MonthView!varnextMonthView:MonthView!requiredinit(coderaDecoder:NSCoder){fatalError("init(coder:) has not been implemented")}overrideinit(frame:CGRect){super.init(frame:frame)vardateFormatter:NSDateFormatter=NSDateFormatter();dateFormatter.dateFormat="yyyy/MM/dd";vardateString:String=dateFormatter.stringFromDate(NSDate());vardates:[String]=dateString.componentsSeparatedByString("/")currentYear=dates[0].toInt()!currentMonth=dates[1].toInt()!scrollView=UIScrollView(frame:self.bounds)scrollView.backgroundColor=UIColor.clearColor()scrollView.contentSize=CGSizeMake(frame.size.width*3.0,frame.size.height);scrollView.contentOffset=CGPointMake(frame.size.width,0.0);scrollView.delegate=self;scrollView.pagingEnabled=true;scrollView.showsHorizontalScrollIndicator=false;scrollView.showsVerticalScrollIndicator=false;scrollView.scrollsToTop=false;self.addSubview(scrollView)currentMonthView=MonthView(frame:CGRectMake(frame.size.width,0,frame.size.width,frame.size.height),year:currentYear,month:currentMonth)//翌月varret=self.getNextYearAndMonth()nextMonthView=MonthView(frame:CGRectMake(frame.size.width*2.0,0,frame.size.width,frame.size.height),year:ret.year,month:ret.month)//前月ret=self.getPrevYearAndMonth()prevMonthView=MonthView(frame:CGRectMake(0.0,0,frame.size.width,frame.size.height),year:ret.year,month:ret.month)scrollView.addSubview(currentMonthView);scrollView.addSubview(nextMonthView);scrollView.addSubview(prevMonthView);}funcscrollViewDidScroll(scrollView:UIScrollView){varpos:CGFloat=scrollView.contentOffset.x/scrollView.bounds.size.widthvardeff:CGFloat=pos-1.0iffabs(deff)>=1.0{if(deff>0){self.showNextView()}else{self.showPrevView()}}}funcshowNextView(){currentMonth++;if(currentMonth>12){currentMonth=1;currentYear++;}vartmpView:MonthView=currentMonthViewcurrentMonthView=nextMonthViewnextMonthView=prevMonthViewprevMonthView=tmpViewvarret=self.getNextYearAndMonth()nextMonthView.setUpDays(ret.year,month:ret.month)self.resetContentOffSet()}funcshowPrevView(){currentMonth--if(currentMonth==0){currentMonth=12currentYear--}vartmpView:MonthView=currentMonthViewcurrentMonthView=prevMonthViewprevMonthView=nextMonthViewnextMonthView=tmpViewvarret=self.getPrevYearAndMonth()prevMonthView.setUpDays(ret.year,month:ret.month)//position調整self.resetContentOffSet()}funcresetContentOffSet(){//position調整prevMonthView.frame=CGRectMake(0,0,frame.size.width,frame.size.height)currentMonthView.frame=CGRectMake(frame.size.width,0,frame.size.width,frame.size.height)nextMonthView.frame=CGRectMake(frame.size.width*2.0,0,frame.size.width,frame.size.height)varscrollViewDelegate:UIScrollViewDelegate=scrollView.delegate!scrollView.delegate=nil//delegateを呼びたくないのでscrollView.contentOffset=CGPointMake(frame.size.width,0.0);scrollView.delegate=scrollViewDelegate}funcgetNextYearAndMonth()->(year:Int,month:Int){varnext_year:Int=currentYearvarnext_month:Int=currentMonth+1ifnext_month>12{next_month=1next_year++}return(next_year,next_month)}funcgetPrevYearAndMonth()->(year:Int,month:Int){varprev_year:Int=currentYearvarprev_month:Int=currentMonth-1ifprev_month==0{prev_month=12prev_year--}return(prev_year,prev_month)}}5 CalenderViewの利用
ViewControllerにて利用する場合は以下のような形を想定しています。
classViewController:UIViewController{overridefuncviewDidLoad(){super.viewDidLoad()// Do any additional setup after loading the view, typically from a nib.varcalenderView:CalenderView=CalenderView(frame:CGRectMake(0,20,UIScreen.mainScreen().bounds.size.width,500));self.view.addSubview(calenderView)}}(縦幅は適当です。。
Register as a new user and use Qiita more conveniently
- You get articles that match your needs
- You can efficiently read back useful information
- You can use dark theme
