SwiftUI编译指令触发以下语句的”无法推断上下文基础”错误。

huangapple go评论62阅读模式
英文:

SwiftUI compiler directives trigger "Cannot infer contextual base" error for following statements

问题

我有一个用于watchOS/iOS应用程序的SwiftUI视图,在其中使用#if os(xxxOS)编译器指令来选择特定于watchOS的视图或特定于iOS的视图,以为OSCommonView的body属性提供内容。watchOS和iOS的body视图都调用相同的一组视图修饰符,这些修饰符本身引用了在父OSCommonView中声明的函数。因此,我认为可以使用#if...#else...#endif编译器指令来切换OS特定的子视图视图,然后是修饰符,而不是在每个iso/watchOS子视图中复制这些修饰符。但是,无论哪个修饰符是第一个或最后一个,都会出现“无法推断出上下文基础...”错误。似乎#endif会导致编译器不“看到”第一个修饰符上面的可选视图?

我天真地认为编译器指令是“不可见的”,只是根据切换无缝呈现代码。我尝试创建一个ViewModifier来将它们分组,但未找到将OSCommonView的参数(包括一些绑定)和方法传递到ViewModifier结构的方法。目前,我只是在每个body_watchOS和body_iOS的定义中重复了一长串视图修饰符。

如果我将修饰符放在上面的编译开关内,它们可以正常工作,但这违背了不重复它们的初衷!

有什么建议吗?非常感谢。

英文:

I have a SwiftUI View for a watchOS / iOS app in which I use the #if os(xxxOS) compiler directive to select between a watchOS specific View or an iOS specific View to provide the content for the the OSCommonView body var. Both the watchOS and iOS body views call the same bunch of view modifiers, which themselves reference functions declared in the parent OSCommonView. So instead of replicating those modifiers in each of the iso/watchOS subviews I thought I could use the #if...#else...#endif compiler directives to switch-in the OS-specific subview view, followed by the modifiers. However, I get the error "Cannot infer contextual base for ..." for the first and last modifier, whatever modifier is the first or last. It seems that #endif makes a break such that the compiler does not "see" the optional view above the first modifier??

struct OSCommonView: View {
	var body: some View {
	#if os(watchOS)
		body_watchOS
	#else
		body_iOS
	#endif
		.onAppear() { handleOnAppear() } <= Cannot infer contextual base error...
		.onDisappear() { handleOnDisappear() }
		.onReceive(uiUpdateTimer) { handleReceive_uiUpdateTimer(newDate: $0) }
		/* --- several other modifiers --- */

    }
	var body_iOS: some View {
		/* view subviews etc */
	}
	var body_watchOS: some View {
		/* view subviews etc */
	}

	func handleOnAppear() { /* ... */}
	func handleOnDisappear() { /* ... */}
	func handleReceive_uiUpdateTimer(newDate: Date) { /* ... */}
}

I naively assumed the compiler directives were "invisible" and just presented the code seamlessly according to the switch. I have tried to create a ViewModifier to group them but failed to find a way to get the parameters (some with Bindings) and methods of the OSCommonView into a ViewModifier struct. At the moment I just duplicate the long list of view modifiers within each definition of body_watchOS and body_iOS.

If I put the modifiers inside the compiler switch above they work fine but that defeats the point of not duplicating them!

#if os(watchOS)
	body_watchOS
	    .onAppear() { handleOnAppear() }
	    .onDisappear() { handleOnDisappear() }
        ...
#else
	body_iOS
	    .onAppear() { handleOnAppear() }
	    .onDisappear() { handleOnDisappear() }
        ...
#endif

Any suggestions? Many thanks

答案1

得分: 1

You can wrap those kinds of directives in closures, while waiting for the missing feature that would negate the need for them:

  var body: some View {
    {
#if os(watchOS)
      body_watchOS
#else
      body_iOS
#endif
    } ()
      .onAppear(perform: handleOnAppear)

However, it's not obvious why you don't just do this:

  var body: some View {
    _body
      .onAppear(perform: handleOnAppear)
#if os(watchOS)
  private var _body: some View {
    
  }
#else
  private var _body: some View {
    
  }
#endif
英文:

You can wrap those kinds of directives in closures, while waiting for the missing feature that would negate the need for them:

  var body: some View {
    {
#if os(watchOS)
      body_watchOS
#else
      body_iOS
#endif
    } ()
      .onAppear(perform: handleOnAppear)

However, it's not obvious why you don't just do this:

  var body: some View {
    _body
      .onAppear(perform: handleOnAppear)
#if os(watchOS)
  private var _body: some View {
    
  }
#else
  private var _body: some View {
    
  }
#endif

huangapple
  • 本文由 发表于 2023年2月7日 02:13:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/75365103.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定