Listのカウント
Q&A
Swift初心者です
初めての開発なので見にくかったらすいません
Playgroundsを参考に在庫管理アプリを作ろうとしています。
実行したいこと
TaskViewにあるListの数をカウントし、ItemRowで表示させたい
どこを直したらいいのか曖昧なので下にコードほぼ全部載っけています、、、
Item
struct Item: Identifiable, Hashable, Codable {
var id = UUID()
var title = ""
static var delete = Item()
}
// 遷移先のBack文字を消す
struct NavigationBarBackButtonTextHidden: ViewModifier {
@Environment(\.presentationMode) var presentaion
func body(content: Content) -> some View {
content
.navigationBarBackButtonHidden(true)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: { presentaion.wrappedValue.dismiss() }) {
Image(systemName: "chevron.backward")
}
}
}
}
}
extension View {
func navigationBarBackButtonTextHidden() -> some View {
return self.modifier(NavigationBarBackButtonTextHidden())
}
}
ItemData
import SwiftUI
class ItemData: ObservableObject {
@Published var items: [Item] = [
Item(
title: "洗剤"
),
]
var itemTaskData = [Item: TaskData]()
func add(_ item: Item) {
items.append(item)
}
func remove(_ item: Item) {
items.removeAll { $0.id == item.id}
}
func getBindingToItem(_ item: Item) -> Binding<Item>? {
Binding<Item>(
get: {
guard let index = self.items.firstIndex(where: { $0.id == item.id }) else { return Item.delete }
return self.items[index]
},
set: { item in
guard let index = self.items.firstIndex(where: { $0.id == item.id }) else { return }
self.items[index] = item
}
)
}
ItemRow
struct ItemRow: View {
@ScaledMetric var imageWidth: CGFloat = 40
let item: Item
let taskData: TaskData
var body: some View {
HStack {
Label {
VStack(alignment: .leading, spacing: 5) {
Text(item.title)
}
} icon: {
Image(systemName: "pencil.circle")
.padding(.trailing, 15)
}
}//H
.badge(taskData.remainingTaskCount)
}
}
Task
import Foundation
struct Task: Identifiable, Hashable, Codable {
var id = UUID()
var text = ""
var count: Int = 0
var memo = ""
var isCompleted = false
var date = Date.now
}
TaskData
import SwiftUI
class TaskData: ObservableObject {
@Published var tasks: [Task] = [
Task(
text: "洗剤",
memo: "",
date: Date.roundedHoursFromNow(60 * 60 * 22)
),
]
var remainingTaskCount : Int {
tasks.filter { !$0.isCompleted && !$0.text.isEmpty }.count
}
func add(_ task: Task) {
tasks.append(task)
}
func sortedTasks(period: Period) -> Binding<[Task]> {
Binding<[Task]>(
get: {
self.tasks
.sorted { $0.date < $1.date }
},
set: { tasks in
for task in tasks {
if let index = self.tasks.firstIndex(where: { $0.id == task.id }) {
self.tasks[index] = task
}
}
}
)
}
}
enum Period: String, CaseIterable, Identifiable {
case nextSevenDays = "Next 7 Days"
var id: String { self.rawValue }
var name: String { self.rawValue }
}
extension Date {
static func roundedHoursFromNow(_ hours: Double) -> Date {
let exactDate = Date(timeIntervalSinceNow: hours)
guard let hourRange = Calendar.current.dateInterval(of: .hour, for: exactDate) else {
return exactDate
}
return hourRange.end
}
}
TaskRow
import SwiftUI
struct TaskRow: View {
@Binding var task: Task
var body: some View {
HStack {
Button {
task.isCompleted.toggle()
} label: {
Image(systemName: task.isCompleted ? "checkmark.circle.fill" : "circle")
}
.buttonStyle(.plain)
VStack {
TextField("Task Description", text: $task.text, axis: .vertical)
TextField("memo", text: $task.memo).font(.subheadline).foregroundColor(.gray)
}
.opacity(task.isCompleted ? 0.5 : 1.0)
Spacer()
VStack {
Text("消費期限").font(.subheadline)
DatePicker("", selection: $task.date, displayedComponents: [.date])
.environment(\.locale, Locale(identifier: "ja_JP"))
}.opacity(task.isCompleted ? 0.5 : 1.0)
}
}
}
TaskView
import SwiftUI
struct TaskView: View {
@ObservedObject var taskData: TaskData
@Binding var item: Item
@State private var newTask = Task()
var body: some View {
NavigationStack {
List {
ForEach(Period.allCases) { period in
Section(content: {
ForEach(taskData.sortedTasks(period: period)) { $task in
TaskRow(task: $task)
}//for
Button {
let newTask = Task(text: "", memo: "¥")
taskData.tasks.append(newTask)
} label: {
HStack {
Image(systemName: "plus")
Text("Add Task")
}
}//Button
}//section
)
.disabled(taskData.sortedTasks(period: period).isEmpty)
}
}//List
}//Navi
}//var
}//st
0