//
import SwiftUI
enum MyColorType: Int, CaseIterable {
case base // #FFFFFF
case orange // #F8C165
case red // #D24141
case blue // #4187FA
case pink // #F064B9
case green // #50AA41
case purple // #965AD2
var color: Color {
switch self {
case .base: return .white
case .orange: return Color.rgbo(red: 248, green: 193, blue: 101, opacity: 1)
case .red: return Color.rgbo(red: 210, green: 65, blue: 65, opacity: 1)
case .blue: return Color.rgbo(red: 65, green: 135, blue: 250, opacity: 1)
case .pink: return Color.rgbo(red: 240, green: 100, blue: 185, opacity: 1)
case .green: return Color.rgbo(red: 80, green: 170, blue: 65, opacity: 1)
case .purple: return Color.rgbo(red: 150, green: 90, blue: 210, opacity: 1)
}
}
var title: String {
switch self {
case .base: return "デフォルト"
case .orange: return "オレンジ"
case .red: return "レッド"
case .blue: return "ブルー"
case .pink: return "ピンク"
case .green: return "グリーン"
case .purple: return "パープル"
}
}
}
extension Color {
static func rgbo(red: Int, green: Int, blue: Int, opacity: CGFloat = 1) -> Color {
return Color(red: CGFloat(red) / 255, green: CGFloat(green) / 255, blue: CGFloat(blue) / 255, opacity: opacity)
}
}
//
import SwiftUI
class MyColor: ObservableObject {
let themeColorTypeKey = "themeColorType"
@Published var color: Color = MyColorType.base.color
init() {
self.color = themeColor
}
var themeColor: Color {
let savedTypeInt = UserDefaults.standard.integer(forKey: themeColorTypeKey)
return MyColorType(rawValue: savedTypeInt)?.color ?? MyColorType.base.color
}
func changeAndSaveThemeColor(type: MyColorType) {
color = type.color
UserDefaults.standard.setValue(type.rawValue, forKey: themeColorTypeKey)
}
}
//
import SwiftUI
import RealmSwift
struct HomeView: View {
@ObservedResults(MemoDataModel.self) var memoDataList
@State var isShowColorSetting = false
@EnvironmentObject var myColor: MyColor
var body: some View {
NavigationStack {
VStack {
memoList
// Spacerを下に入れることで、メモ一覧を上に詰めるように表示させる
Spacer()
}
.toolbarBackground(myColor.color, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
// NavigationBarに設置するボタンなどを定義
.toolbar {
// 左上:テーマカラー設定
ToolbarItem(placement: .navigationBarLeading) {
colorSettingButton
}
// 右上:新規メモ作成
ToolbarItem(placement: .navigationBarTrailing) {
memoCreateLinkButton
}
}
}
}
/// メモ一覧.
var memoList: some View {
List {
ForEach(memoDataList, id: \.self) { memo in
// NavigationLinkは画面遷移を行うViewです
// タップでdestinationに記載したViewへNavigation遷移
NavigationLink(
// 画面遷移する際にタップしたセルのMemoDataを渡す
destination:
MemoDetailView(memoData: memo)
) {
memoCell(memo)
}
}
.onDelete(perform: delete)
}
.listStyle(.plain)
}
/// カラー設定ボタン.
var colorSettingButton: some View {
Button(
action: {
isShowColorSetting = true
}, label: {
Image(.colorSettingIcon)
}
)
.confirmationDialog("テーマカラーを選択してください", isPresented: $isShowColorSetting) {
ForEach(MyColorType.allCases, id: \.self) { type in
Button(
action: {
myColor.changeAndSaveThemeColor(type: type)
}, label: {
Text(type.title)
}
)
}
Button("キャンセル", role: .cancel) {}
}
}
/// メモ作成ボタン.
var memoCreateLinkButton: some View {
// NavigationLinkはTextだけでなく画像やViewでも設定できる
NavigationLink(
// onAppearで生成した新しいMemoDataを渡す
destination:
MemoDetailView(memoData: MemoDataModel())
) {
Image(systemName: "plus")
}
}
}
// MARK: View Components
extension HomeView {
/// メモ一覧に表示するセル.
func memoCell(_ memo: MemoDataModel) -> some View {
VStack(alignment: .leading) {
// メモのテキスト
Text(memo.text)
.font(.body)
// メモの作成・編集日時
Text(formatDate.string(from: memo.recordDate))
.font(.footnote)
}
}
}
extension HomeView {
// 表示形式を変更した日付
var formatDate: DateFormatter {
let formatter = DateFormatter()
// Apple が推奨する固定フォーマット用ロケール
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(identifier: "UTC")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
return formatter
}
}
// MARK: Methods
extension HomeView {
/// リストからメモを削除する処理(Realm オブジェクトを削除).
func delete(at offsets: IndexSet) {
// map + firstで削除対象のオブジェクトを取得
if let objectToDelete = offsets
// インデックスを使って、対応するメモデータを取り出す
.map({ memoDataList[$0] })
// 今回は最初の1件だけを削除対象にする
.first {
// removeでリストからメモデータを削除
self.$memoDataList.remove(objectToDelete)
}
}
}
#Preview {
@Previewable @StateObject var myColor = MyColor()
HomeView()
.environmentObject(myColor)
}