SwiftUI ScrollView 水平 RTL 无法正常工作

Oua*_*lal 10 uiscrollview right-to-left swiftui hstack

我正在尝试在我的 ios 上支持 RTL 模式,该模式是使用 swiftUI 构建的,在执行此操作以更改布局方向时一切都很好:

.environment(\.layoutDirection, .rightToLeft)
Run Code Online (Sandbox Code Playgroud)

仅使用水平 ScrollView ,它无法正常工作

当我这样做时:

 ScrollView(.horizontal) {
            HStack{
                Text("b1")
                Text("b2")
                Text("b3")
            }
        } .environment(\.layoutDirection, .rightToLeft)
Run Code Online (Sandbox Code Playgroud)

项目位置将旋转,但 HSTACK 将始终保持在左侧,如下面的屏幕截图所示: 在此输入图像描述

有什么解决方案或技巧可以使其向右吗?

Oua*_*lal 14

我找到了一个技巧来使用.flipsForRightToLeftLayoutDirection(true)和执行此操作.rotation3DEffect

就像滚动视图将被翻转一样,你需要将 HStack 的每个项目翻转到.rotation3DEffect

 ScrollView(.horizontal) {
            HStack{
                Text("b1")
                    .rotation3DEffect(Angle(degrees: 180), axis: (x: CGFloat(0), y: CGFloat(10), z: CGFloat(0)))
                Text("b2")
                 .rotation3DEffect(Angle(degrees: 180), axis: (x: CGFloat(0), y: CGFloat(10), z: CGFloat(0)))
                Text("b3")
                 .rotation3DEffect(Angle(degrees: 180), axis: (x: CGFloat(0), y: CGFloat(10), z: CGFloat(0)))
            }
        }.flipsForRightToLeftLayoutDirection(true)
        .environment(\.layoutDirection, .rightToLeft)
Run Code Online (Sandbox Code Playgroud)


Sup*_*enn 7

如果is ,则通过以编程方式滚动(使用.scrollTo)到 onAppear 中视图的尾随锚点,您将获得正确的滚动位置。如果是的话也可以工作layoutDirection.rightToLeftlayoutDirection.leftToRight

struct ScrollViewRTL<Content: View>: View {
    var showsIndicators: Bool
    @ViewBuilder var content: Content
    @Environment(\.layoutDirection) private var layoutDirection
        
    init(showsIndicators: Bool = true, @ViewBuilder content: () -> Content) {
        self.showsIndicators = showsIndicators             
        self.content = content()
    }
        
    var body: some View {
       ScrollViewReader { proxy in
         ScrollView(.horizontal, showsIndicators: showsIndicators) {
             content
                 .id("RTL")
                 .onAppear {
                     if layoutDirection == .rightToLeft {
                           proxy.scrollTo("RTL", anchor: .trailing)
                     }
                 }
             }
         }
     }
}
Run Code Online (Sandbox Code Playgroud)

用法:

 ScrollViewRTL {
     HStack {
         Text("b1")
         Text("b2")
         Text("b3")
     }
 }
Run Code Online (Sandbox Code Playgroud)