Good day! In SwiftUI, is it possible to use a modifier only for a certain os target? In the following code I would like to use the modifier .listStyle(SidebarListStyle()) only for the MacOS target because it does not exist for the iOS target. Thanks for you help.
import SwiftUI
struct ContentView: View {
@State var selection: Int?
var body: some View {
HStack() {
NavigationView {
List () {
NavigationLink(destination: FirstView(), tag: 0, selection: self.$selection) {
Text("Click Me To Display The First View")
} // End Navigation Link
NavigationLink(destination: SecondView(), tag: 1, selection: self.$selection) {
Text("Click Me To Display The Second View")
} // End Navigation Link
} // End list
.frame(minWidth: 350, maxWidth: 350)
.onAppear {
self.selection = 0
}
} // End NavigationView
.listStyle(SidebarListStyle())
.frame(maxWidth: .infinity, maxHeight: .infinity)
} // End HStack
} // End some View
} // End ContentView
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
You can create a View
extension and use it like this:
List {
// ...
}
.ifOS(.macOS) {
$0.listStyle(SidebarListStyle())
}
Here's the implementation:
enum OperatingSystem {
case macOS
case iOS
case tvOS
case watchOS
#if os(macOS)
static let current = macOS
#elseif os(iOS)
static let current = iOS
#elseif os(tvOS)
static let current = tvOS
#elseif os(watchOS)
static let current = watchOS
#else
#error("Unsupported platform")
#endif
}
extension View {
/**
Conditionally apply modifiers depending on the target operating system.
```
struct ContentView: View {
var body: some View {
Text("Unicorn")
.font(.system(size: 10))
.ifOS(.macOS, .tvOS) {
$0.font(.system(size: 20))
}
}
}
```
*/
@ViewBuilder
func ifOS<Content: View>(
_ operatingSystems: OperatingSystem...,
modifier: (Self) -> Content
) -> some View {
if operatingSystems.contains(OperatingSystem.current) {
modifier(self)
} else {
self
}
}
}
However, this will not work if you try to use a method that is not available for all the platforms you target. The only way to make that work is to use #if os(…)
directly.
I have an extension that makes it easier to do that:
extension View {
/**
Modify the view in a closure. This can be useful when you need to conditionally apply a modifier that is unavailable on certain platforms.
For example, imagine this code needing to run on macOS too where `View#actionSheet()` is not available:
```
struct ContentView: View {
var body: some View {
Text("Unicorn")
.modify {
#if os(iOS)
$0.actionSheet(…)
#else
$0
#endif
}
}
}
```
*/
func modify<T: View>(@ViewBuilder modifier: (Self) -> T) -> T {
modifier(self)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With