The execution environment

  • MacOS Mojave: 10.14.5
  • Version 11.0 Beta 6 (11M392q)

Project information

Making: github.com/young-cowbo…

App Effect Preview

Page structure design

There are four pages, HabitListView, AddButtonView, HabitDetailView, and AddItemView

Data structure design

The project involves three data structures: HabitItem(habit items), HabitIconArray(habit ICONS), and HabitColor(habit themes).

A HabitColor theme color that saves a custom theme

public let UserColorArray = [
  Color(red:75 / 255, green:166 / 255, blue: 239 / 255),
  Color(red:161 / 255, green:206 / 255, blue: 97 / 255),
  Color(red:248 / 255, green:214 / 255, blue: 80 / 255),
  Color(red:243 / 255, green:176 / 255, blue: 74 / 255),
  Color(red:238 / 255, green:140 / 255, blue: 111 / 255),
  Color(red:237 / 255, green:113 / 255, blue: 165 / 255),
  Color(red:207 / 255, green:102 / 255, blue: 247 / 255),
  Color(red:77 / 255, green:110 / 255, blue: 247 / 255),
  Color(red:236 / 255, green:107 / 255, blue: 102 / 255)]Copy the code

HabitIconArray Custom icon library

public let IconNameArray: [String] = [
    "alarm"."book"."pencil"."desktopcomputer"."gamecontroller"."sportscourt"."lightbulb"
]
Copy the code

HabitItem is used to store custom details. Here, the ObservableObject protocol is implemented to tell SwiftUI that the object needs to be monitored. The checkList property is wrapped in a Published Property Wrapper. Indicates that this property is to be listened on because it might need to be passed to the child View

class HabitItem: Identifiable.ObservableObject {
    var name: String = ""
    var iconName: String = "clock"
    var theme: Color = UserColor.color1.value
    var uuid: Int = 0

    @Published var checkList: [Bool] = [false.false.false.false.false.false.false]
    
    init() {}init(name: String, iconName: String, theme: Color) {
        self.name = name
        self.iconName = iconName
        self.theme = theme
        self.uuid = generatteID()
    }
}
Copy the code

The UI Settings

For details, refer to the repository code. Here is a process to create a “habit” item in MainView

MainView

. @State var sheetVisible: Bool = false
  @State var sheetType: String = "add". .AddButtonView() {
      self.sheetType = "add"
      self.sheetVisible = true}...Copy the code

The AddButtonView uses tail closure syntax to inline a closure for the event

The AddButtonView defines the onPressed property

struct AddButtonView: View {
    var onPressed: () -> Void
    
    var body: some View {
        Button(action: {
            self.onPressed()
        }) {
            HStack {
                Image(systemName: "plus.circle.fill")
                    .resizable()
                    .frame(width: 60, height: 60)
                    .foregroundColor(Color.blue)
            }
        }
    }
}
Copy the code

AddItemView adds an event when the button is clicked, passing the selected data to the onSumit property callback

struct AddItemView: View {@State var newItemTitle = ""
    @State var selectIconIndex: Int = 0
    @State var selectColorIndex: Int = 0
    
    var onSumit: (HabitItem) - >Void
    var onDissmis: () -> Void
    
    var body: some View {
         VStack{... .VStack {
                Button(action: {
                    if self.newItemTitle ! ="" {
                        let iconName = IconNameArray[self.selectIconIndex];
                        let theme = UserColorArray[self.selectColorIndex];

                        self.onSumit(HabitItem(name: self.newItemTitle, iconName: iconName, theme: theme))
                    }
                }) {
                    Text("New").frame(minWidth: 0, maxWidth: .infinity) } ... }... }... }}}Copy the code

New option to handle callback events using closures in MainView

AddItemView(onSumit: { item in
    self.habitItemList.insert(item, at: 0)
    self.sheetVisible = false
  }, onDissmis: { self.sheetVisible = false })
Copy the code

The rest is pretty much the same. You can pull the code down and run it locally to see what happens

thank you