【问题标题】:My SwiftUI Code results in a big ol blank window我的 SwiftUI 代码导致一个大的 ol 空白窗口
【发布时间】:2021-09-08 18:25:21
【问题描述】:

所以我一直在开发一个应用程序来在 Mac 上重新创建 iOS 电池小部件,但我所有的努力都导致了一个空白屏幕。这是我的代码,不胜感激。

我尝试了各种不同的方法,包括LazyVGrid,但均无济于事。

非常感谢您的观看,希望您有愉快的一天!

ContentView.swift

struct ContentView: View {

@State var devices: [Device] = [
    Device(name: "Mark's Mac Book pro", type: .macbook, level: 1.00),
    Device(name: "MX Master 2S", type: .mouse, level: 0.75),
    Device(name: "MX Keys", type: .keyboard, level: 0.50),
    Device(name: "Mark's Airpods Max", type: .airpodsMax, level: 0.63)
]
@State var size: Double = 150.00

var body: some View {
    ScrollView {
        BatteryGrid(devices: $devices, size: $size)
    }
    .frame(minWidth: 300, minHeight: 175)
}
}

BatterGrid.swift

struct BatteryGrid: View {

@Binding var devices: [Device]
@Binding var size: Double
@State var count = 0
@ObservedObject var deviceArrays = PublishedDevices()
@State var devicesPerRow = 0
@State var rows = 0
@State var currentDevice = Device()

var body: some View {
    VStack {
        GeometryReader { geometry in
            ForEach(deviceArrays.devices, id: \.id) { deviceArray in
                HStack {
                    ForEach(deviceArray.row, id: \.id) { device in
                        Progresso(device: $currentDevice, size: $size)
                            .onAppear {
                                setCurrentDevice(to: device)
                            }
                    }
                }
            }
            .onAppear {
                devicesPerRow = Int(geometry.size.width.rounded(.up)) / Int(size.rounded(.down))
                rows = devices.count / devicesPerRow
            }
        }
    }
}

func setCurrentDevice(to device: Device) {
    currentDevice = device
}

}

struct DeviceRow: Identifiable {
var row: [Device] = []
var id = UUID()
}
class PublishedDevices: ObservableObject {
@Published var devices: [DeviceRow] = []
}

最后是 Progresso.swift

struct Progresso: View {
@Binding var device: Device
@Binding var size: Double
var body: some View {
    ZStack {
        Circle()
            .stroke(lineWidth: 8)
            .frame(maxWidth: .infinity)
            .frame(height: 100)
            .foregroundColor(.gray)
            .opacity(0.30)
        Circle()
            .trim(from: 0.0, to: device.level ?? 0)
            .stroke(style: StrokeStyle(lineWidth: 8, lineCap: .round, lineJoin: .round))
            .frame(maxWidth: .infinity)
            .frame(height: 100)
            .foregroundColor((device.level ?? 0) > 0.20 ? .green : .red)
            .rotationEffect(Angle(degrees: 270.0))
        VStack {
            device.icon()
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 40, height: 40)
            Text("\(Int(((device.level ?? 0) * 100).rounded(.up)))%")
                .font(.body.bold())
                .frame(width: 75)
                .lineLimit(1)
        }
    }
}
}

【问题讨论】:

  • PublishedDevices 在做什么?还有为什么你声明@Bindings却根本不使用双向绑定?
  • @vadian,我使用 PublishedDevices 类试图让我的代码在 ForEcah 循环中更新是徒劳的。我应该使用环境变量而不是绑定吗?谢谢! (P.S. 我对这一切都比较陌生哈哈)
  • 只有在要修改子视图中的值并通知父视图时才需要@Binding。如果不只是使用常规的let 常量。您的BatteryGrid 视图依赖于PublishedDevices 中的设备。如果课程没有发布任何内容,则屏幕保持空白。

标签: swift macos swiftui


【解决方案1】:

视图是空白的,因为您遍历了一个空数组 deviceArrays.devices,如此处所述

class PublishedDevices: ObservableObject {
@Published var devices: [DeviceRow] = []
}

此外,当您将PublishedDevices 声明为@ObservedObject 时,在您的BatteryGrid 结构中。它充当您视图的真相来源,因此您必须将其声明为@StateObject

@ObservedObject 用于将真相来源(视图模型)传递给另一个视图

更多关于状态对象的信息在这里https://developer.apple.com/documentation/swiftui/stateobject

【讨论】:

    猜你喜欢
    • 2022-11-08
    • 1970-01-01
    • 2014-05-06
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-30
    • 2012-09-15
    相关资源
    最近更新 更多