![見出し画像](https://assets.st-note.com/production/uploads/images/91841264/rectangle_large_type_2_db9d7f7c578c5223f46c7ea54e816eb3.png?width=800)
SwiftUIでいこう! - カレンダー 3
実際のカレンダーの日付を作っていきます。今の月についての情報を変数に入れて使えるようにしていきます。参考にしている動画はこちら
let daysInMonth ・・・ その月の日数
let firstDayOfMonth ・・・ 年、月
let startingSpaces ・・・ 1日の曜日(1日以前のスペースを入れる)
let prevMonth ・・・ 前の月
let daysInPrevMonth ・・・ 前の月の日数
let daysInMonth = CalendarHelper().daysInMonth(dateHolder.date)
let firstDayOfMonth = CalendarHelper().firstOfMonth(dateHolder.date)
let startingSpaces = CalendarHelper().weekDay(firstDayOfMonth)
let prevMonth = CalendarHelper().minusMonth(dateHolder.date)
let daysInPrevMonth = CalendarHelper().daysInMonth(prevMonth)
CalendarHelperにメソッド追加。
func daysInMonth(_ date: Date) -> Int{
let range = calendar.range(of: .day, in: .month, for: date)!
return range.count
}
func dayOfMonth(_ date: Date) -> Int
let components = calendar.dateComponents([.day], from: date)
return components.day!
}
func firstOfMonth(_ date: Date) -> Date{
let components = calendar.dateComponents([.year, .month], from: date)
return calendar.date(from: components)!
}
func weekDay(_ date: Date) -> Int{
let components = calendar.dateComponents([.weekday], from: date)
return components.weekday! - 1
}
カレンダーを表示させる仕組みを作っていきます。
日付を取得すると数字を受け取ることになるので文字列に変更する構造体を作ります。
enumでMonthTypeを定義します。カレンダーの本体をCurrent、前後をPrevious、Nextとし使い分けができるようにしておきます。
struct MonthStruct
{
var monthType: MonthType
var dayInt : Int
func day() -> String
{
return String(dayInt)
}
}
enum MonthType
{
case Previous
case Current
case Next
}
カレンダーの実際の表記する方法としてデータをもとに数字を配置できるように"CalendarCell"を定義します。
import SwiftUI
struct CalendarCell: View
{
@EnvironmentObject var dateHolder: DateHolder
let count : Int
let startingSpaces : Int
let daysInMonth : Int
let daysInPrevMonth : Int
var body: some View
{
Text(monthStruct().day())
.foregroundColor(textColor(type: monthStruct().monthType))
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
func textColor(type: MonthType) -> Color
{
return type == MonthType.Current ? Color.white : Color.gray
}
func monthStruct() -> MonthStruct
{
let start = startingSpaces
let day = count - start
return MonthStruct(monthType: MonthType.Current, dayInt: day)
}
}
これで表示してみると
![](https://assets.st-note.com/img/1669585357471-PcdGcXor9g.png?width=800)
前の月と
if(count <= start){
let day = daysInPrevMonth + count - start
return MonthStruct(monthType: MonthType.Previous, dayInt: day)
}
後の月を入れ込むために追加します。
else if (count - start > daysInMonth) {
let day = count - start - daysInMonth
return MonthStruct(monthType: MonthType.Next, dayInt: day)
}
CalendarCellの全コードは
import SwiftUI
struct CalendarCell: View
{
@EnvironmentObject var dateHolder: DateHolder
let count : Int
let startingSpaces : Int
let daysInMonth : Int
let daysInPrevMonth : Int
var body: some View
{
Text(monthStruct().day())
.foregroundColor(textColor(type: monthStruct().monthType))
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
func textColor(type: MonthType) -> Color
{
return type == MonthType.Current ? Color.white : Color.gray
}
func monthStruct() -> MonthStruct
{
let start = startingSpaces == 0 ? startingSpaces + 7 : startingSpaces
if(count <= start)
{
let day = daysInPrevMonth + count - start
return MonthStruct(monthType: MonthType.Previous, dayInt: day)
}
else if (count - start > daysInMonth)
{
let day = count - start - daysInMonth
return MonthStruct(monthType: MonthType.Next, dayInt: day)
}
let day = count - start
return MonthStruct(monthType: MonthType.Current, dayInt: day)
}
}
これを利用して"ContentView"に入れ込みます。
var calendarGrid: some View{
VStack(spacing: 1){
let daysInMonth = CalendarHelper().daysInMonth(dateHolder.date)
let firstDayOfMonth = CalendarHelper().firstOfMonth(dateHolder.date)
let startingSpaces = CalendarHelper().weekDay(firstDayOfMonth)
let prevMonth = CalendarHelper().minusMonth(dateHolder.date)
let daysInPrevMonth = CalendarHelper().daysInMonth(prevMonth)
ForEach(0..<6){ row in
HStack(spacing: 1){
ForEach(1..<8){ column in
let count = column + (row * 7)
CalendarCell(count: count, startingSpaces:startingSpaces, daysInMonth: daysInMonth, daysInPrevMonth: daysInPrevMonth)
.environmentObject(dateHolder)
}
}
}
} .frame(maxHeight: .infinity)
これで、うまく表示できるようになりました。
![](https://assets.st-note.com/img/1669585711526-B0KddV61J6.png?width=800)
この記事が気に入ったらサポートをしてみませんか?