Swiftui在切换/true或false上显示不同的图像/文本

发布于 2025-02-13 08:53:38 字数 7190 浏览 2 评论 0原文

我正在尝试创建一个按钮,该按钮根据任务的当前状态显示不同的图像/文本。

我发现以下内容不起作用:

Button {
    taskViewModel.completeTask(id: task.id)
} label: {
    if task.taskCompleted {
        Image(systemName: "square")
            .foregroundStyle(.black)
            .padding(10)
            .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
    } else {
        Image(systemName: "checkmark.square")
            .foregroundStyle(.black)
            .padding(10)
            .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
    }
}

但这确实有效:

if task.taskCompleted {
    Button {
        taskViewModel.completeTask(id: task.id)
    } label: {
        Image(systemName: "checkmark.square")
            .foregroundStyle(.black)
            .padding(10)
            .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
    }
} else {
    Button {
        taskViewModel.completeTask(id: task.id)
    } label: {
        Image(systemName: "square")
            .foregroundStyle(.black)
            .padding(10)
            .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
    }
}

无效的代码更加干净!当然,有一种比我在这里所做的更好的方法?

不起作用的完整代码是:

    func TasksView(completed: Bool)->some View {
        
        LazyVStack(spacing: 20) {
            if let tasks = taskViewModel.filteredTasks{
                if tasks.isEmpty{
                    Text("No Tasks Today")
                        .offset(y: 100)
                }else{
                    ForEach(tasks){ task in
                        if completed && task.taskCompleted || !task.taskCompleted {
                            HStack(alignment: .top, spacing: 20) {
                                VStack(spacing: 12) {
                                    Circle()
                                        .fill(taskViewModel.isCurrentHour(date: task.taskDate) ? .black : .clear)
                                        .frame(width: 13, height: 13)
                                        .background(
                                            Circle()
                                                .stroke(.black, lineWidth: 2)
                                                .padding(-4)
                                        )
                                        .scaleEffect(taskViewModel.isCurrentHour(date: task.taskDate) ? 1.2 : 0.8)
                                    
                                    Rectangle()
                                        .fill(.black)
                                        .frame(width: 3)
                                }
                                
                                VStack {
                                    HStack(alignment: .top, spacing: 10) {
                                        VStack(alignment: .leading, spacing: 12) {
                                            Text(task.taskTitle)
                                                .font(.title2.bold())
                                            Text(task.taskDescription)
                                                .font(.callout)
                                                .foregroundStyle(.secondary)
                                        }
                                        .headerLeading()
                                        
                                        Text(task.taskDate.formatted(date: .omitted, time: .shortened))
                                    }
                                    
                                    HStack(spacing: 8) {
                                        if taskViewModel.isCurrentHour(date: task.taskDate) {
                                        
                                            HStack(spacing: 5) {
                                                ForEach(1...3, id: \.self) { user in
                                                    Image(systemName: "person")
                                                        .resizable()
                                                        .aspectRatio(contentMode: .fill)
                                                        .frame(width: 25, height: 25)
                                                }
                                            }
                                            .headerLeading()
                                        }
                                        

                                            Button{
                                                taskViewModel.completeTask(id: task.id)
                                            } label: {
                                                Image(systemName: task.taskCompleted ? "checkmark.square" : "square")
                                                    .foregroundStyle(.black)
                                                    .padding(10)
                                                    .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
                                            }
                                        
                                        Button{
                                            taskViewModel.deleteTask(id: task.id)
                                        } label: {
                                            Image(systemName: "bin.xmark")
                                                .foregroundStyle(.black)
                                                .padding(10)
                                                .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))

                                        }
                                        
                                    }
                                    .padding(.top)
                                    .headerTrailing()
                                    
                                    
                                }
                                .padding(taskViewModel.isCurrentHour(date: task.taskDate) ? 15 : 0)
                                .padding(.bottom, taskViewModel.isCurrentHour(date: task.taskDate) ? 0 : 10)
                                .headerLeading()
                                .background(
                                    Color(.black)
                                        .cornerRadius(20)
                                        .opacity(taskViewModel.isCurrentHour(date: task.taskDate) ? 1 : 0)
                                )
                                .foregroundColor(taskViewModel.isCurrentHour(date: task.taskDate) ? .white : .black)
                            }.headerLeading()
                        }
                    }
                }
            }else{
                ProgressView()
                    .offset(y: 100)
            }
        }
        .padding()
        .padding(.top)
        .onChange(of: taskViewModel.currentDay) { newDate in
            taskViewModel.filterTodaysTasks()
        }
    }

当我尝试运行此问题时,以下错误是由Xcode抛出的:

编译器无法在合理的时间内键入该表达式;尝试将表达式分解为不同的子表达

I'm trying to create a button that displays a different images/text depending on the current state of a task.

I've found the following doesn't work:

Button {
    taskViewModel.completeTask(id: task.id)
} label: {
    if task.taskCompleted {
        Image(systemName: "square")
            .foregroundStyle(.black)
            .padding(10)
            .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
    } else {
        Image(systemName: "checkmark.square")
            .foregroundStyle(.black)
            .padding(10)
            .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
    }
}

But this does work:

if task.taskCompleted {
    Button {
        taskViewModel.completeTask(id: task.id)
    } label: {
        Image(systemName: "checkmark.square")
            .foregroundStyle(.black)
            .padding(10)
            .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
    }
} else {
    Button {
        taskViewModel.completeTask(id: task.id)
    } label: {
        Image(systemName: "square")
            .foregroundStyle(.black)
            .padding(10)
            .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
    }
}

The code that doesn't work is far cleaner!. Surely there is a better way to do this than what I've done here?

The full code that isn't working is:

    func TasksView(completed: Bool)->some View {
        
        LazyVStack(spacing: 20) {
            if let tasks = taskViewModel.filteredTasks{
                if tasks.isEmpty{
                    Text("No Tasks Today")
                        .offset(y: 100)
                }else{
                    ForEach(tasks){ task in
                        if completed && task.taskCompleted || !task.taskCompleted {
                            HStack(alignment: .top, spacing: 20) {
                                VStack(spacing: 12) {
                                    Circle()
                                        .fill(taskViewModel.isCurrentHour(date: task.taskDate) ? .black : .clear)
                                        .frame(width: 13, height: 13)
                                        .background(
                                            Circle()
                                                .stroke(.black, lineWidth: 2)
                                                .padding(-4)
                                        )
                                        .scaleEffect(taskViewModel.isCurrentHour(date: task.taskDate) ? 1.2 : 0.8)
                                    
                                    Rectangle()
                                        .fill(.black)
                                        .frame(width: 3)
                                }
                                
                                VStack {
                                    HStack(alignment: .top, spacing: 10) {
                                        VStack(alignment: .leading, spacing: 12) {
                                            Text(task.taskTitle)
                                                .font(.title2.bold())
                                            Text(task.taskDescription)
                                                .font(.callout)
                                                .foregroundStyle(.secondary)
                                        }
                                        .headerLeading()
                                        
                                        Text(task.taskDate.formatted(date: .omitted, time: .shortened))
                                    }
                                    
                                    HStack(spacing: 8) {
                                        if taskViewModel.isCurrentHour(date: task.taskDate) {
                                        
                                            HStack(spacing: 5) {
                                                ForEach(1...3, id: \.self) { user in
                                                    Image(systemName: "person")
                                                        .resizable()
                                                        .aspectRatio(contentMode: .fill)
                                                        .frame(width: 25, height: 25)
                                                }
                                            }
                                            .headerLeading()
                                        }
                                        

                                            Button{
                                                taskViewModel.completeTask(id: task.id)
                                            } label: {
                                                Image(systemName: task.taskCompleted ? "checkmark.square" : "square")
                                                    .foregroundStyle(.black)
                                                    .padding(10)
                                                    .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
                                            }
                                        
                                        Button{
                                            taskViewModel.deleteTask(id: task.id)
                                        } label: {
                                            Image(systemName: "bin.xmark")
                                                .foregroundStyle(.black)
                                                .padding(10)
                                                .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))

                                        }
                                        
                                    }
                                    .padding(.top)
                                    .headerTrailing()
                                    
                                    
                                }
                                .padding(taskViewModel.isCurrentHour(date: task.taskDate) ? 15 : 0)
                                .padding(.bottom, taskViewModel.isCurrentHour(date: task.taskDate) ? 0 : 10)
                                .headerLeading()
                                .background(
                                    Color(.black)
                                        .cornerRadius(20)
                                        .opacity(taskViewModel.isCurrentHour(date: task.taskDate) ? 1 : 0)
                                )
                                .foregroundColor(taskViewModel.isCurrentHour(date: task.taskDate) ? .white : .black)
                            }.headerLeading()
                        }
                    }
                }
            }else{
                ProgressView()
                    .offset(y: 100)
            }
        }
        .padding()
        .padding(.top)
        .onChange(of: taskViewModel.currentDay) { newDate in
            taskViewModel.filterTodaysTasks()
        }
    }

When I try to run this the following error is thrown by Xcode:

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

好倦 2025-02-20 08:53:39

根据完成的任务状态,有一种更好,更干净的方法。

Button {
    taskViewModel.completeTask(id: task.id)
} label: {
    Image(systemName: task.taskCompleted ? "checkmark.square" : "square") // Change image based on state of the task completed
        .foregroundStyle(.black)
        .padding(10)
        .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
}

There is a better and a cleaner way to do it, based on the state of the task completed.

Button {
    taskViewModel.completeTask(id: task.id)
} label: {
    Image(systemName: task.taskCompleted ? "checkmark.square" : "square") // Change image based on state of the task completed
        .foregroundStyle(.black)
        .padding(10)
        .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
}
檐上三寸雪 2025-02-20 08:53:38

代替更多细节,通常在对象的属性结果下调整视图的最佳方法是进行最小的调整。在这种情况下,您可以将更改限制为图像的systemName

Button {
    taskViewModel.completeTask(id: task.id)
} label: {
    Image(systemName: task.taskCompleted ? "checkmark.square" : "square")
        .foregroundStyle(.black)
        .padding(10)
        .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
}

更有可能发生的是task 不会向SwiftUI渲染系统的更改表示,,因此,在完成后运行后,没有迹象表明需要对视图进行重新评估。

In lieu of more details, generally the best way to adjust your view in the result of an object's property is to make the smallest adjustment necessary. In this case, you can limit the change to the systemName of the image:

Button {
    taskViewModel.completeTask(id: task.id)
} label: {
    Image(systemName: task.taskCompleted ? "checkmark.square" : "square")
        .foregroundStyle(.black)
        .padding(10)
        .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
}

What is more likely happening is that task isn't signalling its change to the SwiftUI rendering system, so after completeTask has run there's no indication that the view needs to be re-evaluated.

失退 2025-02-20 08:53:38

对于SwiftUi,第一个示例中的按钮的身份没有改变。您可以通过添加显式.id(…)来解决此问题。例如:

Button {
    taskViewModel.completeTask(id: task.id)
} label: {
    if task.taskCompleted {
        Image(systemName: "square")
            .foregroundStyle(.black)
            .padding(10)
            .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
    } else {
        Image(systemName: "checkmark.square")
            .foregroundStyle(.black)
            .padding(10)
            .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
    }
}.id("\(task.id)-\(task.completed)")

一旦任务的完成更改,SwiftUI正在重新评估UI,它将检测到该按钮具有不同的ID,然后将使用您的新映像重新呈现。

To SwiftUI, the identity of the button hasn't changed in the first example. You could fix this by adding an explicit .id(…). For example:

Button {
    taskViewModel.completeTask(id: task.id)
} label: {
    if task.taskCompleted {
        Image(systemName: "square")
            .foregroundStyle(.black)
            .padding(10)
            .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
    } else {
        Image(systemName: "checkmark.square")
            .foregroundStyle(.black)
            .padding(10)
            .background(Color(.white), in: RoundedRectangle(cornerRadius: 10))
    }
}.id("\(task.id)-\(task.completed)")

As soon as the task's completed changes, and SwiftUI is re-evaluating the UI, it will detect that the button has a different ID and will then re-render it with your new image.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文