简体   繁体   English

包括 SwiftUI 个基于平台的视图修改器

[英]Including SwiftUI view modifiers based on platform

I'm working on a cross-platform app using SwiftUI. I have a view that consists of an HStack with various items lined up in it.我正在使用 SwiftUI 开发跨平台应用程序。我有一个视图,其中包含一个HStack ,其中排列着各种项目。 In essence, this:从本质上讲,这:

struct ContentView: View {
    var body: some View {
        HStack {
            // Some stuff on the left side of this HStack
            Spacer()
            // more stuff on the right side
        }
    }
}

The Spacer takes up as much space as it can, which pushes the views before it to the left side and views after it to the right side of the row. Spacer占用尽可能多的空间,将它之前的视图推到左侧,将它之后的视图推到行的右侧。 I've got it to a point where this looks great on iOS.我已经达到了在 iOS 上看起来很棒的程度。

On macOS though, my window width is much larger and can further be resized by the user.不过在 macOS 上,我的 window 宽度要大得多,用户可以进一步调整大小。 At those larger widths it starts to get awkward to see the row content separated by so much space.在那些较大的宽度下,看到行内容被如此大的空间分隔开来会变得很尴尬。 So I'd like to limit the width.所以我想限制宽度。 Essentially, I want to do this:本质上,我想这样做:

struct ContentView: View {
    var body: some View {
        HStack {
            // a bunch of stuff in this stack
        }
        #if os(macOS)
        .frame(width: 120)
        #endif
    }
}

But that gets me the error "Unexpected platform condition (expected 'os', 'arch', or 'swift')" coming from the line with the .frame modifier.但这让我收到来自带有.frame修饰符的行的错误“意外的平台条件(预期的'os','arch'或'swift')”。 If I recreate the entire HStack inside the platform check, as given below, everything works.如果我在平台检查中重新创建整个HStack ,如下所示,一切正常。

struct ContentView: View {
    var body: some View {
        #if os(iOS)
        HStack {
            // a bunch of stuff in this stack
        }
        #elseif os(macOS)
        HStack {
            // a bunch of stuff in this stack
        }
        .frame(width: 120)
        #endif
    }
}

But it seems very error prone to replicate everything inside the HStack , just to be able to vary the modifier based on platform.但是复制HStack中的所有内容似乎很容易出错,只是为了能够根据平台改变修饰符。 Is there really no way to conditionally compile just modifier code?真的没有办法有条件地编译修饰符代码吗?

Just separate bunch of stuff into standalone view, like只需将一堆东西分成独立视图,例如

struct ContentView: View {
    var body: some View {
        #if os(iOS)
          MainView()
        #elseif os(macOS)
          MainView()
             .frame(width: 120)
        #endif
    }
}

struct MainView: View {
    var body: some View {
        HStack {
            // a bunch of stuff in this stack
        }
    }
}

More elegant, appropriate and reusable approach to conditionally add modifier would be by using EmptyModifier() .有条件地添加修饰符的更优雅、适当和可重用的方法是使用EmptyModifier()

We can use the empty modifier to switch modifiers at compile time during development.

Let's say you want apply frame modifier based on OS Conditions, First create a custom ViewModifier like so:假设您想根据操作系统条件应用框架修改器,首先创建一个自定义ViewModifier ,如下所示:

struct CustomFrame: ViewModifier {
    func body(content: Content) -> some View {
            content
            .frame(width: 120)
        }
}

Now create an instance of CustomFrame ViewModifier and add conditions as per the business logic:现在创建ViewModifierinstance并根据业务逻辑添加条件:

struct ContentView: View {
    
    var frameModifier: some ViewModifier {
        #if os(iOS)
        return CustomFrame()
        #elseif os(macOS)
        return EmptyModifier() // <- EmptyModifier()
        #endif
    }
    
    var body: some View {
        HStack {
            // a bunch of stuff in this stack
        }
        .modifier(frameModifier)  // <- Use custom modifiers like this.
    }
}

This will let you add modifiers conditionally to any view in Swifty way .这将允许您以Swifty way conditionally地向任何视图添加modifiers

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM