【问题标题】:@ViewBuilder throws error when init with other properties@ViewBuilder 在使用其他属性初始化时抛出错误
【发布时间】:2021-06-03 16:21:23
【问题描述】:

我有一个使用 SwiftUI 中的 @ViewBuilder 属性的自定义视图。

我还想在构造视图的闭包旁边要求初始化器中的一些其他属性。

import Foundation
import SwiftUI

public enum NavigationBarStyle {
    case title
    case dismiss
    case pop
    case popAndDismiss
}

public struct NavigationBar <TitleView: View>: View {
    
    //MARK: View Model
    
    @State var barStyle: NavigationBarStyle
    
    @Binding var showView: Bool
    
    @Binding var pushView: Bool
    
    var titleView: TitleView
    
    //MARK: Body
    public var body: some View {
        titleView
    }
    
    //MARK: Init
    public init(showView: Binding<Bool>?, pushView: Binding<Bool>?, style: NavigationBarStyle = NavigationBarStyle.dismiss, @ViewBuilder titleView: @escaping () -> TitleView) {
        //Compiler error in initializer
        self.titleView = titleView()
        self.barStyle = style
        self._showView = showView ?? .constant(true)
        self._pushView = pushView ?? .constant(true)
    }
    
}

struct NavigationBar_Previews: PreviewProvider {

    static var previews: some View {
        NavigationBar(showView: nil, pushView: nil) {
            Text("Title")
        }
    }
}

但是此代码会产生编译器错误。

Variable 'self.barStyle' used before being initialized

我有点困惑。当我从此代码中删除 @ViewBuilder 功能时,初始化程序起作用。

【问题讨论】:

    标签: ios xcode swiftui initialization


    【解决方案1】:

    barStyle 不是普通变量。你的barStyle@State var,所以你应该使用State(initialValue:

     public init(showView: Binding<Bool>?, pushView: Binding<Bool>?, style: NavigationBarStyle = NavigationBarStyle.dismiss, @ViewBuilder titleView: @escaping () -> TitleView) {
            //Compiler error in initializer
            self.titleView = titleView()
            self._barStyle = State(initialValue: style) //< == Here
            self._showView = showView ?? .constant(true)
            self._pushView = pushView ?? .constant(true)
        }
    

    【讨论】:

    • 这行得通,但我想了解如果我删除 @ViewBuilder 功能,我的初始化程序为什么会工作。
    • 如果我提供这样的值@State var barStyle: NavigationBarStyle = .dismiss,我的初始化程序也可以工作
    • 第二种情况,你已经在声明时初始化了var,所以编译器不会抛出错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-23
    • 2015-01-17
    • 2020-09-10
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多