A padding modifier in SwiftUI takes an EdgeInsets
, eg
.padding(.leading, 8)
However, there are only leading and trailing EdgeInsets, and not left and right. This presents a problem because not everything in RTL languages should necessarily be reversed from the way it's displayed in LTR languages.
Is there a way to achieve the same or similar effect as the padding modifier, which forces the padding to be on left or right side, regardless of directionality of the language?
Use @Environment(\.layoutDirection)
to get the current layout direction (LTR or RTL) and use it to flip .leading
and .trailing
as needed.
Here’s a ViewModifier
that wraps all that conveniently:
enum NoFlipEdge {
case left, right
}
struct NoFlipPadding: ViewModifier {
let edge: NoFlipEdge
let length: CGFloat?
@Environment(\.layoutDirection) var layoutDirection
private var computedEdge: Edge.Set {
if layoutDirection == .rightToLeft {
return edge == .left ? .trailing : .leading
} else {
return edge == .left ? .leading : .trailing
}
}
func body(content: Content) -> some View {
content
.padding(computedEdge, length)
}
}
extension View {
func padding(_ edge: NoFlipEdge, _ length: CGFloat? = nil) -> some View {
self.modifier(NoFlipPadding(edge: edge, length: length))
}
}
Use it like you would the standard padding modifiers:
Text("Text")
.padding(.left, 10)