Cien días Swift (Día 27) -Proyecto 4: Parte 2

百日 学 Swift (Día 27) - Proyecto 4, segunda parte (Proyecto 4: Parte 2)

Un edificio de diseño básico 1. (crear un diseño básico)

(1) Agregar propiedades de control de entrada

@State private var wakeUp = Date()          // 计划起床时间
@State private var sleepAmount = 8.0        // 期待睡眠时长
@State private var coffeeAmount = 1         // 每日饮用咖啡数量

(2) Construir esqueleto de interfaz de usuario

Use el siguiente código para reemplazar la vista de texto predeterminada de Hello World.

NavigationView {
    VStack {
        // 计划起床时间
        Text("打算几点起床呢?")
        	.font(.headline)
        DatePicker("Please enter a time", selection: $wakeUp, displayedComponents: .hourAndMinute)
        	.labelsHidden()
        // 预期睡眠时长
        Text("想睡多久呢?")
        	.font(.headline)
        Stepper(value: $sleepAmount, in: 4...12, step: 0.25) {
            Text("\(sleepAmount, specifier: "%g") 小时")
        }
        .padding(.horizontal)
        // 每日饮用咖啡杯数
        Text("每天喝几杯咖啡☕️?")
        	.font(.headline)
        Stepper(value: $coffeeAmount, in: 1...20) {
            Text("\(coffeeAmount) 杯")
        }
        .padding(.horizontal)
    }
}

(3) Crear botón y método de llamada

  • Agregar métodos en ContentView
func calculateBedtime() {
}
  • Agregar decoración de botones a VStack
.navigationBarItems(trailing:
    Button(action: calculateBedtime) {
        Text("预计就寝时间")
    }
)

De esta manera, la interfaz está básicamente construida, pero el método de llamada de botón temporalmente no funciona porque no hay código.

2. Conexión de SwiftUI a Core ML (Conecte SwiftUI a Core ML)

(1) Importar modelo Core ML en el proyecto

El modelo se ha creado a través de Crear ML y se ha enviado al archivo BetterRest.mlmodel a través de Salida. Busque este archivo, arrástrelo a la carpeta del proyecto en Xcode y cámbiele el nombre a SleepCalculator.mlmodel. De esta manera, Xcode creará automáticamente una clase llamada SleepCalculator.

(2) atributos de información de visualización complementarios

@State private var alertTitle = ""          // 对话框标题
@State private var alertMessage = ""        // 对话框内容
@State private var showingAlert = false     // 对话框显示状态

(3) Método de llamada del botón Finalizar

// 按钮调用方法
func calculateBedtime() {
    let model = SleepCalculator()
    let components = Calendar.current.dateComponents([.hour, .minute], from: wakeUp)    // 读取起床时间的时和分
    let hour = (components.hour ?? 0) * 60 * 60     // 将小时换算成秒
    let minute = (components.minute ?? 0) * 60      // 将分钟换算成秒
    do {
        let prediction = try model.prediction(wake: Double(hour + minute), estimatedSleep: sleepAmount, coffee: Double(coffeeAmount))   // 使用模型预测
        let sleepTime = wakeUp - prediction.actualSleep     // 得出就寝时间
        let formatter = DateFormatter()                     // 使用 DateFormatter 转换显示格式
        formatter.timeStyle = .short
        alertTitle = "合理就寝时间是:"
        alertMessage = formatter.string(from: sleepTime)
    } catch {
        // 出错处理
        alertTitle = "出错啦!~"
        alertMessage = "很遗憾,程序发生了错误。"
    }
    showingAlert = true		// 无论是否出错,总是显示对话框
}

(4) Agregue un modificador de alerta a VStack, de modo que cuando finalice el método CalculateBedtime, ya que displayAlert siempre se establece en verdadero, mostrará información al usuario.

.alert(isPresented: $showingAlert) {
    Alert(title: Text(alertTitle), message: Text(alertMessage), dismissButton: .default(Text("好")))
}

Debe decirse que el diseño general del programa ha llegado a su fin, y a continuación se realizan algunos ajustes menores.

La limpieza de la interfaz de usuario en la parte 3. (interfaz de acabado)

(1) Reduzca el rango de selección del tiempo de activación

La gran mayoría de los usuarios básicamente no tienen requisitos de turno de noche, por lo que establecer la hora de despertarse de manera predeterminada entre las 6 y las 8 de la mañana hará que sea más conveniente para más usuarios. Puede agregar un atributo predeterminado para la hora de despertarse:

var defaultWakeTime: Date {
    var components = DateComponents()
    components.hour = 7
    components.minute = 0
    return Calendar.current.date(from: components) ?? Date()
}

Esta es una propiedad calculada. Utiliza DateComponents para crear una fecha. El valor predeterminado es 7 am, que puede satisfacer las necesidades de la mayoría de las personas que necesitan establecer la hora del despertador entre las 6 am y las 8 am. Luego usamos esta propiedad como el valor predeterminado de wakeUp.

@State private var wakeUp = defaultWakeTime

El resultado será una falla de compilación, el error es: Cannot use instance member 'defaultWakeTime' within property initializer;Esto se debe a que Swift no permite que una propiedad use directamente otra propiedad, porque no se sabe qué propiedad se creó primero. La solución es establecer defaultWakeTime como una variable estática, es decir, agregar la palabra clave estática frente a var.

static var defaultWakeTime: Date {

(2) Ajuste de interfaz

En primer lugar, puede reemplazar todo el VStack con Form, para que toda la vista se convierta en un formulario, y el diseño sea más regular de lo que es ahora.

Luego hay dos formas de ajustar para cada elemento de entrada:

  • Use el paquete de Sección, elimine la vista de Texto y defina el texto directamente en el Título de la Sección (lo escribí por separado en SectionView.swift)
  • Use el paquete VStack para establecer la alineación y el espaciado
Tio
Publicado 77 artículos originales · Me gusta 16 · Visitantes más de 40,000

Supongo que te gusta

Origin blog.csdn.net/hh680821/article/details/105305224
Recomendado
Clasificación