SwiftUI Platform-Dependent Padding Modifier
March 28, 2024 • #IOS #IPad OS #MacOS #Swift #SwiftUI
Some SwiftUI views I have require padding one platform and none on the other. To avoid preprocessor switches everywhere I created a custom view modifier for it.
I am still not really convinced that SwiftUI is that great. I do not get the excitement. To me, it is too constrained and cumbersome. I have enjoyed the freedom of the web technologies from vanilla CSS to single-page applications with Vue.js and Vuex (not en vogue anymore by now). Whenever you try to get off the happy path, it will turn into pain nowhere as fast as in SwiftUI. At least on macOS and when you try to maintain a multi-platform user interface. Dusty AppKit still appears superior to me and I think storyboards just should have gotten more love.
Anyway, here is the code. A simple enum to have a safe way to tell the modifier which platform it should be effective on. And a switch statement combined with preprocessor switches.
struct PlatformPadding: ViewModifier {
let edges: Edge.Set
let length: CGFloat?
let platform: Platform
init(_ platform: Platform, _ edges: Edge.Set = .all, _ length: CGFloat? = nil) {
self.edges = edges
self.length = length
self.platform = platform
}
func body(content: Content) -> some View {
switch platform {
case .iOS:
#if os(iOS)
content.padding(edges, length)
#else
content
#endif
case .macOS:
#if os(macOS)
content.padding(edges, length)
#else
content
#endif
}
}
}
To not always have to call .modifier(PlatformPadding(.macOS))
, I created an extension on View
.
extension View {
func platformPadding(_ platform: Platform, _ edges: Edge.Set = .all, _ length: CGFloat? = nil) -> some View {
modifier(PlatformPadding(platform, edges, length))
}
}
And finally, this is all to apply it on a view:
Form {
// View code here.
}
.platformPadding(.macOS)