gpt4 book ai didi

SwiftUI:更新由其他 @State 变量组成的 @Binding 变量的最佳方式

转载 作者:行者123 更新时间:2023-12-04 03:07:09 25 4
gpt4 key购买 nike

我在 SwiftUI 中遇到了我的第一个复杂控件。这是一个日期频率选择器,用户可以在其中选择一周中的哪一天来进行每周重复的事件,或者选择每月的某一天来进行每月的重复事件。我有@State 变量来跟踪我的段 Controller 中的每周和每月,以及用户选择的星期几或月份。当这些值发生变化时,我想更新我的@Binding 频率。下面的代码正在运行,但我觉得更新 body 调用中的频率很脏。

enum Frequency {
case weekly(on: Int)
case monthly(on: Int)
}

struct FrequencyView : View {
@Binding var frequency: Frequency

@State var segment: Int
@State var weekDay: Int
@State var monthDay: Int
var displayFrequency: Frequency {
if segment == 0 {
return .weekly(on: weekDay)
} else {
return .monthly(on: monthDay)
}
}

var body: some View {
frequency = displayFrequency
return NavigationView {
VStack {
Text(displayFrequency.long).fontWeight(.bold)
SegmentedControl(selection: $segment) {
Text("Weekly").tag(0)
Text("Monthly").tag(1)
}.padding()

if segment == 0 {
Text("Day of the week").foregroundColor(Acorns.stone)
ExpensesWeeklyPickerView(day: $weekDay).padding()
} else {
Text("Day of the month").foregroundColor(Acorns.stone)
ExpensesMonthlyPickerView(day: $monthDay).padding()
}

Spacer()
}.navigationBarTitle(Text("Frequency"))
}
}
}

好奇是否有人找到了更好的方法来做到这一点?

最佳答案

首先,为 weekDay 添加访问器和 monthDayFrequency :

extension Frequency {
var weekDay: Int {
get {
if case .weekly(on: let day) = self { return day }
else { return 0 }
}
set { self = .weekly(on: newValue) }
}

var monthDay: Int {
get {
if case .monthly(on: let day) = self { return day }
else { return 0 }
}
set { self = .monthly(on: newValue) }
}
}

现在您可以使用这些访问器为您的 subview 创建绑定(bind):
if segment == 0 {
Text("Day of the week").foregroundColor(Acorns.stone)
ExpensesWeeklyPickerView(day: $frequency.weekDay).padding()
} else {
Text("Day of the month").foregroundColor(Acorns.stone)
ExpensesMonthlyPickerView(day: $frequency.monthDay).padding()
}

要更改单击段时的频率,您需要提供 SegmentedControl改变频率的绑定(bind)。我会介绍另一个(私有(private)) enum用于段:
fileprivate enum Segment: Int, Hashable {
case weekly
case monthly
}

然后将扩展名添加到 FrequencySegment 相互翻译:
extension Frequency {
fileprivate var segment: ContentView.Segment {
get {
switch self {
case .weekly(on: _): return .weekly
case .monthly(on: _): return .monthly
}
}
set {
switch newValue {
case .weekly: self = .weekly(on: 0)
case .monthly: self = .monthly(on: 0)
}
}
}
}

最后,摆脱你的 segment属性(property)和使用 frequency.segment反而:
        SegmentedControl(selection: $frequency.segment) {
Text("Weekly").tag(Segment.weekly)
Text("Monthly").tag(Segment.monthly)
}.padding()
if frequency.segment == .weekly {
...

关于SwiftUI:更新由其他 @State 变量组成的 @Binding 变量的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56973744/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com