byJ*_*van 5 checkbox ios swift swiftui
我需要带有文本字段的复选框(?如在待办事项列表中)。目前我已经创建了如下按钮对象:
Button(action: {
// do when checked / unchecked
//...
}) {
HStack(alignment: .top, spacing: 10) {
Rectangle()
.fill(Color.white)
.frame(width:20, height:20, alignment: .center)
.cornerRadius(5)
Text("Todo item 1")
}
}
Run Code Online (Sandbox Code Playgroud)
我需要在 SwiftUI 中保留checked
和unchecked
声明。
Nat*_*ird 28
对于 iOS 设备来说,最好的方法是创建一个 CheckboxStyle 结构体并遵守 ToggleStyle 协议。这样您就可以使用 Apple 提供的内置 Toggle 组件。
// CheckboxStyle.swift
import SwiftUI
struct CheckboxStyle: ToggleStyle {
func makeBody(configuration: Self.Configuration) -> some View {
return HStack {
Image(systemName: configuration.isOn ? "checkmark.square" : "square")
.resizable()
.frame(width: 24, height: 24)
.foregroundColor(configuration.isOn ? .blue : .gray)
.font(.system(size: 20, weight: .regular, design: .default))
configuration.label
}
.onTapGesture { configuration.isOn.toggle() }
}
}
// Example usage in a SwiftUI view
Toggle(isOn: $checked) {
Text("The label")
}
.toggleStyle(CheckboxStyle())
Run Code Online (Sandbox Code Playgroud)
在 macOS 上,Apple 已经创建了CheckboxToggleStyle()
可用于 macOS 10.15+ 的版本。但它还不适用于 iOS。
Rya*_*yan 14
Toggle
似乎适用于 macOS 和 iOS,使用各自的本机控件。
https://developer.apple.com/documentation/swiftui/toggle
在打开和关闭状态之间切换的控件。
@State var isOn: Bool = true
var body: some View {
Toggle("My Checkbox Title", isOn: $isOn)
.padding()
}
Run Code Online (Sandbox Code Playgroud)
苹果系统:
iOS:
小智 12
这是我创建的一个简单的、可重复使用的复选标记组件,它遵循类似于 iOS 上其他复选标记的配色方案(例如,在消息应用程序中选择消息):
import SwiftUI
struct CheckBoxView: View {
@Binding var checked: Bool
var body: some View {
Image(systemName: checked ? "checkmark.square.fill" : "square")
.foregroundColor(checked ? Color(UIColor.systemBlue) : Color.secondary)
.onTapGesture {
self.checked.toggle()
}
}
}
struct CheckBoxView_Previews: PreviewProvider {
struct CheckBoxViewHolder: View {
@State var checked = false
var body: some View {
CheckBoxView(checked: $checked)
}
}
static var previews: some View {
CheckBoxViewHolder()
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在其他视图中使用它,如下所示:
...
@State private var checked = true
...
HStack {
CheckBoxView(checked: $checked)
Spacer()
Text("Element that requires checkmark!")
}
...
Run Code Online (Sandbox Code Playgroud)
我们可以借助@State
Apple的帮助,它会持久保存给定类型的值,视图通过该值读取和监视该值。
工作示例:
struct CheckboxFieldView: View {
@State var checkState: Bool = false
var body: some View {
Button(action:
{
//1. Save state
self.checkState = !self.checkState
print("State : \(self.checkState)")
}) {
HStack(alignment: .top, spacing: 10) {
//2. Will update according to state
Rectangle()
.fill(self.checkState ? Color.green : Color.red)
.frame(width:20, height:20, alignment: .center)
.cornerRadius(5)
Text("Todo item ")
}
}
.foregroundColor(Color.white)
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以添加CheckboxFieldView()
你会想要这样的东西:
struct TodoCell: View {
var todoCellViewModel: TodoCellViewModel
var updateTodo: ((_ id: Int) -> Void)
var body: some View {
HStack {
Image(systemName: (self.todoCellViewModel.isCompleted() ? "checkmark.square" : "square")).tapAction {
self.updateTodo(self.todoCellViewModel.getId())
}
Text(self.todoCellViewModel.getTitle())
}
.padding()
}
}
Run Code Online (Sandbox Code Playgroud)
您的列表可能如下所示:
struct TodoList: View {
var todos: Todos
var updateTodo: ((_ id: Int) -> Void)
var body: some View {
List(self.todos) { todo in
TodoCell(todoCellViewModel: TodoCellViewModel(todo: todo), updateTodo: { (id) in
self.updateTodo(id)
})
}
}
}
Run Code Online (Sandbox Code Playgroud)
您的模型可能如下所示:
public class TodoCellViewModel {
private var todo: Todo
public init(todo: Todo) {
self.todo = todo
}
public func isCompleted() -> Bool {
return self.todo.completed
}
public func getTitle() -> String {
return self.todo.title
}
public func getId() -> Int {
return self.todo.id
}
}
Run Code Online (Sandbox Code Playgroud)
最后是一个Todo
类:
public class Todo: Codable, Identifiable {
public let id: Int
public var title: String
public var completed: Bool
}
Run Code Online (Sandbox Code Playgroud)
这些都没有经过实际测试,也不是所有的代码都已经实现,但这应该会让你走上正轨。
这里\xe2\x80\x99是我的看法。我\xe2\x80\x99m实际上是在MacOS上这样做的,但过程应该是相同的。
\n首先,我必须通过创建两个 png 图像来伪造复选框:和
,分别称它们为
checkbox-on.png
和checkbox-off.png
。这些我放进去了Assets.xcassets
。
我相信对于 iOS,这些图像已经可用。
\n其次,视图包含一个状态变量:
\n@State var checked = false\n
Run Code Online (Sandbox Code Playgroud)\n剩下的就是实现一个带有操作、图像、一些文本和一些修饰符的按钮:
\nButton(action: {\n checked.toggle()\n}) {\n Image(checked ? "checkbox-on" : "checkbox-off")\n .renderingMode(.original)\n .resizable()\n .padding(0)\n .frame(width: 14.0, height: 14.0)\n .background(Color(NSColor.controlBackgroundColor))\n Text("Choose me \xe2\x80\xa6 !").padding(0)\n}\n.buttonStyle(PlainButtonStyle())\n.background(Color(red: 0, green: 0, blue: 0, opacity: 0.02))\n.cornerRadius(0)\n
Run Code Online (Sandbox Code Playgroud)\nchecked
是您要切换的布尔变量renderingMode()
确保图像正确显示并resizable()
用于启用frame()
.显然,如果你想养成这个习惯,你可以创建一个结构体:
\nstruct Checkbox: View {\n @Binding var toggle: Bool\n var text: String\n var body: some View {\n Button(action: {\n self.toggle.toggle()\n }) {\n Image(self.toggle ? "checkbox-on" : "checkbox-off")\n .renderingMode(.original)\n .resizable()\n .padding(0)\n .frame(width: 14.0, height: 14.0)\n .background(Color(NSColor.controlBackgroundColor))\n Text(text).padding(0)\n }\n .buttonStyle(PlainButtonStyle())\n .background(Color(red: 0, green: 0, blue: 0, opacity: 0.02))\n .cornerRadius(0)\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n然后使用:
\nCheckbox(toggle: self.$checked, text: "Choose me \xe2\x80\xa6 !")\n\n
Run Code Online (Sandbox Code Playgroud)\n(请注意,您需要self.$checked
在这个上使用)。
最后,如果您更喜欢使用常见的替代外观,即复选框的填充方块,您可以替换Image
为:
Rectangle()\n .fill(self.autoSave ? Color(NSColor.controlAccentColor) : Color(NSColor.controlColor))\n .padding(4)\n .border(Color(NSColor.controlAccentColor), width: 2)\n .frame(width: 14, height: 14)\n
Run Code Online (Sandbox Code Playgroud)\n我通过这样做学到了很多东西,希望这会有所帮助。
\n