質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

1回答

4397閲覧

SwiftUIでカレンダーアプリを作る: 日曜始まりまたは月曜始まりのViwe生成のより簡潔な実装方法

qyoris

総合スコア13

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2020/06/05 00:29

最近、SwiftUIからiOS開発の勉強を始めたものです。
カレンダーアプリを作りたいと考えています。

知りたいこと

画像のカレンダーアプリのように、Navigation Barの下に曜日を表示させたいです。
この時、日曜始まりか月曜始まりかを選択できるようにしたいと考えています。
イメージ説明

機能としては実装できたのですが、煩雑なコードになってしまっていると思います。
extentionなどを使えばもっと簡潔にかけるのではないか?と思うのですが、そのやり方がわかりません。

試したこと

以下の構造体を自分なりに書いてみました。やりたかった動作は実現できています。
WeekdaySymbolsView(true) なら日曜始まりで 日_月_火_水_木_金_土 と表示されます。
WeekdaySymbolsView(false)なら月曜始まりで 月_火_水_木_金_土_日 と表示されます。
(※ アンダースコアはSpacerを表しています)

実際のコードは次の通りです。

// 日曜始まり または 月曜始まり のViewを生成するstruct struct WeekdaySymbolsView: View { let beginWithSunday: Bool // true: 日曜始まり, false: 月曜始まり let formatter: DateFormatter // 曜日を取得するために用いる let weekdaySymbols: [String] // 曜日のString型配列を格納 let indexFrom: Int // ForEachのfromの値を格納 let indexTo: Int // ForEachのtoの値を格納 // 日曜始まり(true) か 月曜始まり(false) を引数として渡し初期化を行う init(beginWithSunday: Bool) { self.beginWithSunday = beginWithSunday formatter = DateFormatter() formatter.locale = Locale(identifier: "ja_JP") weekdaySymbols = formatter.shortWeekdaySymbols // ["日", "月", "火", "水", "木", "金", "土"] // ForEachのfromとtoを決定する // 取得した配列 ["日", "月", "火", "水", "木", "金", "土"] から 0: 日曜日、1: 月曜日 ・・・ 6: 土曜日 と対応している // 日曜始まりの場合: ForEach(0 ..< 6) となり、fromは0、toは6 となる // 月曜始まりの場合: ForEach(1 ..< 7) となり、fromは1、toは7 となる indexFrom = beginWithSunday ? 0 : 1 indexTo = beginWithSunday ? weekdaySymbols.count - 1 : weekdaySymbols.count } // 土曜日と日曜日の値を定義するenum enum Weekday: Int { case saturday = 6 case sunday = 0 } var body: some View { // 7つの曜日を横並びに表示するView HStack { // ForEachで 週の始まりの曜日から最後の曜日を除いた曜日まで "曜日 スペーサ" をループで生成する // 日曜始まりの場合: "日曜日(0)〜金曜日(5) スペーサ" のループ // 月曜始まりの場合: "月曜日(1)〜土曜日(6) スペーサ" のループ ForEach(indexFrom ..< indexTo) { weekday in Text(self.weekdaySymbols[weekday]) Spacer() } // 日曜始まりの場合: 残りの "土曜日(6)" をenumを用いて表示 // 月曜始まりの場合: 残りの "日曜日(0)" をenumを用いて表示 Text(beginWithSunday ? weekdaySymbols[Weekday.saturday.rawValue] : weekdaySymbols[Weekday.sunday.rawValue]) } .font(.system(size: 10)) .frame(height: 0) .padding() } }

もっと簡潔な、Swift(UI)らしい書き方はありますでしょうか?
enumも初めて使ったので正しい用法なのか分かっていません。

別に関数を作った方がいいなど、何でも良いのでコードレビューをお願いしたいです。

アドバイスを頂けると嬉しいです。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

SwiftUIらしいやり方はそんなものだと思いますが、
月曜始まりの場合は、初期化時に取得した配列の先頭の「日」を配列の最後に移動して、
あとは配列の内容をそのまま表示する方がシンプルだと思います。

swift

1struct WeekdaySymbolsView: View { 2 var weekdaySymbols: [String] 3 4 init(beginWithSunday: Bool) { 5 let formatter = DateFormatter() 6 formatter.locale = Locale(identifier: "ja_JP") 7 weekdaySymbols = formatter.shortWeekdaySymbols // ["日", "月", "火", "水", "木", "金", "土"] 8 if !beginWithSunday { 9 weekdaySymbols.append(weekdaySymbols.remove(at: 0)) 10 } 11 12 } 13 14 var body: some View { 15 HStack { 16 Text(self.weekdaySymbols[0]) 17 ForEach(1 ..< weekdaySymbols.count) { weekday in 18 HStack { 19 Spacer() 20 Text(self.weekdaySymbols[weekday]) 21 } 22 } 23 } 24 .font(.system(size: 10)) 25 .frame(height: 0) 26 .padding() 27 } 28}

投稿2020/06/05 15:17

編集2020/06/05 15:22
TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

qyoris

2020/06/05 22:10

ありがとうございます。とても勉強になります!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問