如何在SwiftUI中使用Checkbox创建文本?

时间:2019-10-17 05:58:40

标签: ios swift checkbox 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")
        }
    }

我需要在SwiftUI中保留checkedunchecked状态。

checkbox sample image

8 个答案:

答案 0 :(得分:2)

这是我创建的一个简单,可重复使用的选中标记组件,该组件遵循类似于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()
    }
}

您可以在其他视图中使用它,例如:

...
@State private var checked = true
...

HStack {
    CheckBoxView(checked: $checked)
    Spacer()
    Text("Element that requires checkmark!")
}
...

答案 1 :(得分:2)

这是我的看法。我实际上是在MacOS上执行此操作,但是过程应该相同。

首先,我不得不通过创建两个png图像来伪造该复选框:enter image description hereenter image description here,分别命名为checkbox-on.pngcheckbox-off.png。这些是我放入Assets.xcassets中的。

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

第二,该视图包含状态变量:

@State var checked = false

剩下的就是用一个动作,一个图像,一些文本和一些修饰符来实现一个按钮:

Button(action: {
    checked.toggle()
}) {
    Image(checked ? "checkbox-on" :  "checkbox-off")
        .renderingMode(.original)
        .resizable()
        .padding(0)
        .frame(width: 14.0, height: 14.0)
        .background(Color(NSColor.controlBackgroundColor))
    Text("Choose me … !").padding(0)
}
.buttonStyle(PlainButtonStyle())
.background(Color(red: 0, green: 0, blue: 0, opacity: 0.02))
.cornerRadius(0)
  • checked是您要切换的布尔变量
  • 图像取决于布尔值,使用条件运算符在两者之间进行选择
  • renderingMode()确保图像正确显示,并使用resizable()启用frame()
  • 其余的修饰符可用来调整外观。

很显然,如果要养成这种习惯,可以创建一个结构:

struct Checkbox: View {
    @Binding var toggle: Bool
    var text: String
    var body: some View {
        Button(action: {
            self.toggle.toggle()
        }) {
            Image(self.toggle ? "checkbox-on" :  "checkbox-off")
                .renderingMode(.original)
                .resizable()
                .padding(0)
                .frame(width: 14.0, height: 14.0)
                .background(Color(NSColor.controlBackgroundColor))
            Text(text).padding(0)
        }
        .buttonStyle(PlainButtonStyle())
        .background(Color(red: 0, green: 0, blue: 0, opacity: 0.02))
        .cornerRadius(0)
    }
}

然后使用:

Checkbox(toggle: self.$checked, text: "Choose me … !")

(请注意,您需要为此使用self.$checked)。

最后,如果您希望使用通用的替代外观,即复选框的实心正方形,可以将Image替换为:

Rectangle()
    .fill(self.autoSave ? Color(NSColor.controlAccentColor) : Color(NSColor.controlColor))
    .padding(4)
    .border(Color(NSColor.controlAccentColor), width: 2)
    .frame(width: 14, height: 14)

我从中学到了很多,希望这会有所帮助。

答案 2 :(得分:2)

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())

在 macOS 上,Apple 已经创建了一个 CheckboxToggleStyle(),您可以将其用于 macOS 10.15+。但它不适用于 iOS - 尚不可用。

答案 3 :(得分:1)

我们可以利用FROM ubuntu:18.10 RUN apt-get update -y && \ apt-get install -y python-pip python-dev # Set the working directory to /usr/src/app WORKDIR /usr/src/app # Copy the current directory contents into the container at /usr/src/app ADD . /usr/src/app RUN pip install -r requirements.txt ENTRYPOINT [ "python" ] CMD [ "app-1.py" ] from Apple的帮助,它是给定类型的持久值,视图可以通过该值读取并监视该值。

工作示例:

@State

现在,您可以添加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) } }

答案 4 :(得分:1)

您会想要这样的东西:

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()
    }
}

您的列表可能看起来像这样:

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)
            })
        }
    }
}

您的模型可能看起来像这样:

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
    }
}

最后是一个Todo类:

public class Todo: Codable, Identifiable {    
    public let id: Int
    public var title: String
    public var completed: Bool
}

实际上没有经过测试,并且并非所有代码都已实现,但这应该可以使您走上正确的轨道。

答案 5 :(得分:0)

您可以使用以下代码并更改颜色等。这是一个单独的组件,我使用回调方法来了解是否选中此复选框。

第1步:创建可自定义和可重复使用的复选框视图 步骤2:在主视图中使用组件 使用checkboxSelected()回调函数可以知道是否选中了哪个复选框。

import SwiftUI

//MARK:- Checkbox Field
struct CheckboxField: View {
    let id: String
    let label: String
    let size: CGFloat
    let color: Color
    let textSize: Int
    let callback: (String, Bool)->()

    init(
        id: String,
        label:String,
        size: CGFloat = 10,
        color: Color = Color.black,
        textSize: Int = 14,
        callback: @escaping (String, Bool)->()
        ) {
        self.id = id
        self.label = label
        self.size = size
        self.color = color
        self.textSize = textSize
        self.callback = callback
    }

    @State var isMarked:Bool = false

    var body: some View {
        Button(action:{
            self.isMarked.toggle()
            self.callback(self.id, self.isMarked)
        }) {
            HStack(alignment: .center, spacing: 10) {
                Image(systemName: self.isMarked ? "checkmark.square" : "square")
                    .renderingMode(.original)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: self.size, height: self.size)
                Text(label)
                    .font(Font.system(size: size))
                Spacer()
            }.foregroundColor(self.color)
        }
        .foregroundColor(Color.white)
    }
}

enum Gender: String {
    case male
    case female
}

struct ContentView: View {
    var body: some View {
        HStack{
            Text("Gender")
                .font(Font.headline)
            VStack {
                CheckboxField(
                    id: Gender.male.rawValue,
                    label: Gender.male.rawValue,
                    size: 14,
                    textSize: 14,
                    callback: checkboxSelected
                )
                CheckboxField(
                    id: Gender.female.rawValue,
                    label: Gender.female.rawValue,
                    size: 14,
                    textSize: 14,
                    callback: checkboxSelected
                )
            }
        }
        .padding()
    }

    func checkboxSelected(id: String, isMarked: Bool) {
        print("\(id) is marked: \(isMarked)")
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

答案 6 :(得分:0)

答案 7 :(得分:0)

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()
}

macOS:

macOS checkbox

iOS:

iOS checkbox