Movatterモバイル変換


[0]ホーム

URL:


LoginSignup
83

Go to list of users who liked

83

Share on X(Twitter)

Share on Facebook

Add to Hatena Bookmark

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【iOS】【swift】カレンダーを作ってみる

Posted at

ss.jpg

↑のようにスワイプで切り替えれるようなカレンダーを。
ひとまず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)}}

(縦幅は適当です。。

ソースはこちらに
https://github.com/kitanoow/SwiftCalendarDemo/

83

Go to list of users who liked

83
2

Go to list of comments

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
83

Go to list of users who liked

83

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?


[8]ページ先頭

©2009-2025 Movatter.jp