@ViewBuilder 在使用其他属性初始化时抛出错误

Posted

技术标签:

【中文标题】@ViewBuilder 在使用其他属性初始化时抛出错误【英文标题】:@ViewBuilder throws error when init with other properties 【发布时间】: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 功能时,初始化程序起作用。

【问题讨论】:

【参考方案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,所以编译器不会抛出错误。

以上是关于@ViewBuilder 在使用其他属性初始化时抛出错误的主要内容,如果未能解决你的问题,请参考以下文章

Hadoop API 在尝试初始化集群以使用 DistCp 时抛出错误

AudioUnitInitialize 在初始化 AudioComponentInstance 时抛出错误

AVAudioPlayer 在使用 M4A 文件初始化时抛出。 (OSStatus 错误 2003334207。)

如何使 UIViewRepresentable @ViewBuilder 与动态内容一起使用?

在安全模式下使用 Xalan 执行 XSLT 以创建 XHTML 在创建属性时抛出 TransformerConfigurationException

传递带有@JsonIgnore 标记的属性时抛出错误