如何在 SwiftUI 中使用复选框创建文本?

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 中保留checkedunchecked声明。

复选框示例图像

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)

苹果系统:

macOS 复选框

iOS:

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)


byJ*_*van 8

我们可以借助@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()


fuz*_*uzz 6

你会想要这样的东西:

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)

这些都没有经过实际测试,也不是所有的代码都已经实现,但这应该会让你走上正轨。


Man*_*ngo 6

这里\xe2\x80\x99是我的看法。我\xe2\x80\x99m实际上是在MacOS上这样做的,但过程应该是相同的。

\n

首先,我必须通过创建两个 png 图像来伪造复选框:在此输入图像描述在此输入图像描述,分别称它们为checkbox-on.pngcheckbox-off.png。这些我放进去了Assets.xcassets

\n

我相信对于 iOS,这些图像已经可用。

\n

其次,视图包含一个状态变量:

\n
@State var checked = false\n
Run Code Online (Sandbox Code Playgroud)\n

剩下的就是实现一个带有操作、图像、一些文本和一些修饰符的按钮:

\n
Button(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)\n
    \n
  • checked是您要切换的布尔变量
  • \n
  • 图像取决于布尔值,使用条件运算符在两者之间进行选择
  • \n
  • renderingMode()确保图像正确显示并resizable()用于启用frame().
  • \n
  • 其余的修改器用于调整外观。
  • \n
\n

显然,如果你想养成这个习惯,你可以创建一个结构体:

\n
struct 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

然后使用:

\n
Checkbox(toggle: self.$checked, text: "Choose me \xe2\x80\xa6 !")\n\n
Run Code Online (Sandbox Code Playgroud)\n

(请注意,您需要self.$checked在这个上使用)。

\n

最后,如果您更喜欢使用常见的替代外观,即复选框的填充方块,您可以替换Image为:

\n
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