根据布局方向翻转 SwiftUI 形状
Flip a SwiftUI Shape based on layout direction
我制作了一个 SemiRoundedRectangle 形状,我用它来剪裁侧边菜单。如果用户使用 RTL 语言,我需要翻转它,但不确定实现此目的的最佳方法。
我试过 .flipsForRightToLeftLayoutDirection(true)
但这也会翻转实际的阿拉伯语文本。当我尝试旋转形状时,它不再符合 Shape 协议,因此我不能再在 .clipShape
中使用它。当我切换到阿拉伯语时,SwiftUI 中的其他所有内容都会神奇地自行翻转,是否可以添加一些东西到我的形状中以赋予它这些魔力?
感谢您的帮助:)
import SwiftUI
struct SemiRoundedRectangle: Shape {
var cornerRadius: CGFloat
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: rect.maxX, y: rect.minY))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
path.addLine(to: CGPoint(x: rect.minX+cornerRadius, y: rect.maxY))
path.addArc(center: CGPoint(x: cornerRadius, y: rect.height - cornerRadius),
radius: cornerRadius,
startAngle: .degrees(90),
endAngle: .degrees(180), clockwise: false)
path.addLine(to: CGPoint(x: 0, y: cornerRadius))
path.addArc(center: CGPoint(x: cornerRadius, y: cornerRadius),
radius: cornerRadius,
startAngle: .degrees(180),
endAngle: .degrees(270), clockwise: false)
path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
return path
}
}
struct TestView {
var body: some View {
HStack {
Text("ايه الأخبار؟")
.padding()
.background(Color.green)
.clipShape(SemiRoundedRectangle(cornerRadius: 10.0))
Spacer()
}
}
}
尝试将 clipShape
附加到 Color.green
:
struct TestView: View {
var body: some View {
HStack {
Text("ايه الأخبار؟")
.padding()
.background(
Color.green /// here!
.clipShape(SemiRoundedRectangle(cornerRadius: 10.0))
.flipsForRightToLeftLayoutDirection(true)
)
Spacer()
}
}
}
结果:
English
RTL Language
有一个通用的解决方案:
extension Shape {
func flipped(_ axis: Axis = .horizontal, anchor: UnitPoint = .center) -> ScaledShape<Self> {
switch axis {
case .horizontal:
return scale(x: -1, y: 1, anchor: anchor)
case .vertical:
return scale(x: 1, y: -1, anchor: anchor)
}
}
}
用于这种情况:
struct TestView: View {
var body: some View {
HStack {
Text("ايه الأخبار؟")
.padding()
.background(Color.green)
.clipShape(SemiRoundedRectangle(cornerRadius: 20.0).flipped())
Spacer()
}
.padding()
}
}
我制作了一个 SemiRoundedRectangle 形状,我用它来剪裁侧边菜单。如果用户使用 RTL 语言,我需要翻转它,但不确定实现此目的的最佳方法。
我试过 .flipsForRightToLeftLayoutDirection(true)
但这也会翻转实际的阿拉伯语文本。当我尝试旋转形状时,它不再符合 Shape 协议,因此我不能再在 .clipShape
中使用它。当我切换到阿拉伯语时,SwiftUI 中的其他所有内容都会神奇地自行翻转,是否可以添加一些东西到我的形状中以赋予它这些魔力?
感谢您的帮助:)
import SwiftUI
struct SemiRoundedRectangle: Shape {
var cornerRadius: CGFloat
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: rect.maxX, y: rect.minY))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
path.addLine(to: CGPoint(x: rect.minX+cornerRadius, y: rect.maxY))
path.addArc(center: CGPoint(x: cornerRadius, y: rect.height - cornerRadius),
radius: cornerRadius,
startAngle: .degrees(90),
endAngle: .degrees(180), clockwise: false)
path.addLine(to: CGPoint(x: 0, y: cornerRadius))
path.addArc(center: CGPoint(x: cornerRadius, y: cornerRadius),
radius: cornerRadius,
startAngle: .degrees(180),
endAngle: .degrees(270), clockwise: false)
path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
return path
}
}
struct TestView {
var body: some View {
HStack {
Text("ايه الأخبار؟")
.padding()
.background(Color.green)
.clipShape(SemiRoundedRectangle(cornerRadius: 10.0))
Spacer()
}
}
}
尝试将 clipShape
附加到 Color.green
:
struct TestView: View {
var body: some View {
HStack {
Text("ايه الأخبار؟")
.padding()
.background(
Color.green /// here!
.clipShape(SemiRoundedRectangle(cornerRadius: 10.0))
.flipsForRightToLeftLayoutDirection(true)
)
Spacer()
}
}
}
结果:
English | RTL Language |
---|---|
有一个通用的解决方案:
extension Shape {
func flipped(_ axis: Axis = .horizontal, anchor: UnitPoint = .center) -> ScaledShape<Self> {
switch axis {
case .horizontal:
return scale(x: -1, y: 1, anchor: anchor)
case .vertical:
return scale(x: 1, y: -1, anchor: anchor)
}
}
}
用于这种情况:
struct TestView: View {
var body: some View {
HStack {
Text("ايه الأخبار؟")
.padding()
.background(Color.green)
.clipShape(SemiRoundedRectangle(cornerRadius: 20.0).flipped())
Spacer()
}
.padding()
}
}