2

我有一个支持 LTR 和 RTL 语言的 SwiftUI 应用程序。它不拘泥于其中任何一个,它只取决于用户想要什么。

我在一个可垂直滚动的事物列表中有一个可水平滚动的事物列表,之前是通过UICollectionView在 a UITableViewCellinside a中实现的UITableView

对于 RTL,水平滚动行需要默认位于最右边的第一个元素上(显然与 LTR 相对)。我还没有找到实现这一点的方法。

我试过flipsForRightToLeftLayoutDirection(_:)了,但问题是它翻转了一切,包括Text()滚动视图的内部。所以阿拉伯语文本看起来是镜像的。

这是我的观点骨架-

ScrollView(.horizontal) {
  LazyHStack {
    ForEach(things) { thing in
      Text(thing.name)
    }
  }
}

关于如何实现这一目标的任何想法?提前致谢。

4

2 回答 2

2

要自动滚动到最右边的元素,您可以使用 ScrollViewReader 视图的 scrollTo 函数。

您应该为 ForEach 循环的每个元素设置一个 id,并使用 ForEach 的 onAppear 修饰符滚动到最右边的元素(最后一个 id)。仅当语言方向为从右到左时才应执行此操作(Locale.characterDirection 提供此信息)。

下面的代码说明了这一点:

struct LanguageScrollView: View {
    let things: [String] = ["Thing1", "Thing2", "Thing3", "Thing4", "Thing5", "Thing6", "Thing7", "Thing8", "Thing9", "Thing10"]
    
    var body: some View {
        ScrollView(.horizontal) {
            ScrollViewReader { value in
                LazyHStack {
                    ForEach(0..<things.count) { i in
                        Text(things[i])
                            .id(i)
                    }
                    .onAppear {
                        if getLangDirection() == .rightToLeft {
                            value.scrollTo(things.count - 1)
                        }
                    }
                }
            }
        }
    }
    
    func getLangDirection() -> Locale.LanguageDirection? {
        guard let language = Locale.current.languageCode else { return nil }
        let direction = Locale.characterDirection(forLanguage: language)
        return direction
    }
    
}
于 2021-11-17T14:20:41.773 回答
0

@MatM 上面的答案是正确的,但是,如果我们没有明确设置框架,我 LazyHStack 的大小有问题(至少在 iOS 14 上),我不知道为什么。另一件事是使用 Locale.LanguageDirection?我更喜欢使用来自 Environment 的 layoutDirection ,如下所示。请记住,我之所以写使用 HStack,是因为在 Lazy 中,除了我们定义框架外,我有一个问题,即视图无法以某种方式正确显示 RTL。

    @Environment(\.layoutDirection) var layoutDirection
    

ScrollView(.horizontal) {
            ScrollViewReader { value in
                HStack {
                    ForEach(0..<things.count) { i in
                        Text(things[i])
                            .id(i)
                    }
                    .onAppear {
                        // change things.first with whatever is the first identifier you set
                        proxy.scrollTo(things.first ?? 0, anchor: layoutDirection == LayoutDirection.rightToLeft ? .trailing : .leading)
                    }
                }
            }
        }
于 2021-11-18T07:34:39.177 回答