【问题标题】:Undestranding @State SwiftUI解构@State SwiftUI
【发布时间】:2021-11-30 13:07:24
【问题描述】:

大家好,我在 swiftUI 中理解 @State 时遇到问题

我会更好地解释...正如您从滚动视图中的图像中看到的那样,我有两个视图,一个包含日历,另一个包含用户选择日期的摘要。

现在...我曾经用用户在日历上选择的日期更新 summaryView

 @State private var selectedDate: Date = Self.now
 private static var now = Date ()

同样在包含用户选择摘要的视图(日历上方的视图)中,还有一个用函数创建的随机黄色字符串

// MARK: - Generate Random String
private extension Reservations {
    
     func generateRandomString(length: Int) -> String {
        let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
            var s = ""
            for _ in 0 ..< length {
                s.append(letters.randomElement()!)
            }
            return s
     }
}

每次用户在日历上选择一天时都会发生变化。

我的问题是当用户选择一个日历日时,应用程序只需在摘要视图中更改日期,而不必再次重复“randomString”函数

这个问题是由于使用@State 我理解正确吗?我应该使用什么而不是 @State 来更改不在同一个视图中的单个值?


struct Reservations: View {
    
    @Environment(\.calendar) private var calendar
    
    @State private var selectedDate: Date = Self.now
    private static var now = Date()
    
    var body: some View {
        
        Summary()
        ReservationsCalendar()
    }
}

// MARK: - Generate Random String
private extension Reservations {
    
     func generateRandomString(length: Int) -> String {
        let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
            var s = ""
            for _ in 0 ..< length {
                s.append(letters.randomElement()!)
            }
            return s
     }
    
    @ViewBuilder func Summary() -> some View {
        
        HStack(spacing: 10) {
            
            HStack {
       Text(selectedDate.dayFormatted(style: .twoDigits))
                .font(.title.bold())

                Text("ID").foregroundColor(.white)
                Text(generateRandomString(length: 7).uppercased())
                    .foregroundColor(.yellow)
                    .padding(.horizontal, 10)
                    .frame(height: 25)
                    .background(
                       Capsule()
                        .fill(.black.opacity(0.2))
                    )
            }
        }
    }


    @ViewBuilder private func ReservationsCalendar() -> some View {
        
      ReservationsCal(currentDate: $selectedDate)
        
    }
}

【问题讨论】:

  • 我不清楚generateRandomString 何时或如何被调用。你能加入minimal reproducible example吗?
  • @jnpdx 我更新了我的问题`..我输入了我的部分代码只是为了让你更好地理解

标签: ios swift xcode swiftui view


【解决方案1】:

现在,您在视图层次结构中调用generateRandomString,保证每次重新渲染视图时都会生成一个新的随机字符串。

相反,您可以将其声明为 @State 变量,该变量将在重新渲染中持续存在(并声明 generateRandomString 以便在初始化阶段使用它):

struct Reservations: View {
    
    @State private var selectedDate: Date = Self.now
    @State private var randomString = Self.generateRandomString(length: 7)

    private static var now = Date()
    
    var body: some View {
        Text(randomString.uppercased())
    }
}

private extension Reservations {
    
    static func generateRandomString(length: Int) -> String {
       let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
           var s = ""
           for _ in 0 ..< length {
               s.append(letters.randomElement()!)
           }
           return s
    }
}

【讨论】:

  • @State private var randomString 返回此错误不能在属性初始化程序中使用实例成员“generateRandomString”;属性初始化程序在“self”可用之前运行
  • 由于结构 Reservations 中有 2 个不同的视图,使用 @State 进行日历选择是否正确,还是应该使用其他属性包装器?
  • 我已更新答案以解决第一条评论。你的第二个问题:不一定。首先,我会更新你的代码以使用标准的 Swift 约定——函数应该有小写的名字——类型应该有大写。由于我看不到ReservationsCal 的代码或所选日期的操作,因此不清楚这里的正确或最佳路径是什么。 @State 看起来不错,但也许您希望它在某个时候出现在视图模型中。
  • 是的,现在它似乎工作了..所以我需要通过使用@状态来更新同一结构中多个视图的值你建议我用这种方式解决吗?跨度>
  • @kAiN 抱歉,我没有完全关注,但是是的,您可以传递 @State 值,也可以在 ObservableObject 中使用 @Published
猜你喜欢
  • 2019-11-10
  • 1970-01-01
  • 1970-01-01
  • 2019-02-02
  • 2021-01-04
  • 2021-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多