ios SwiftUI主工具栏项上的无限滚动标签

snvhrwxg  于 2023-05-30  发布在  iOS
关注(0)|答案(1)|浏览(144)

我有一个简单的NavigationView,它的navigationBarLeading上有一个返回按钮。对于.principal内容,它将具有非常大的文本。我希望文本只需要一行,并无限水平滚动(类似于Instagram为歌曲做的,当他们需要超过设备宽度)。
基于这个gist,我已经能够创建一个无限滚动的组件。但是,过渡将从一条边转到另一条边,这与工具栏项重叠。如何更新它,使起点和终点(trailingleading)实际上考虑后退按钮两侧的填充?

struct InfiniteLabel: View {
    let text: String
    
    @State private var go = false
    
    private let transition = AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading))
    private let alignment = Alignment(horizontal: .myLeading, vertical: .center)
    
    @State private var reset = false
    
    var body: some View {
        Text(textContent)
            .fixedSize()
            .padding(.horizontal, 4)
            .animation(nil, value: go)
            .id(go)
            .transition(transition)
            .onAppear {
                go.toggle()
            }
            .animation(.linear(duration: animationDuration).repeatForever(autoreverses: false), value: go)
            .frame(alignment: alignment)
            .id(reset)
            .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
                reset.toggle()
            }
    }
    
    private var textContent: String {
        var result = text
        while result.count < 75 {
            result += " \(text)"
        }
        return result
    }
    
    private var animationDuration: Double {
        Double(textContent.count) / 7.0
    }
}

extension HorizontalAlignment {
   private enum MyLeadingAlignment: AlignmentID {
      static func defaultValue(in dimensions: ViewDimensions) -> CGFloat {
         return dimensions[HorizontalAlignment.leading]
      }
   }
   static let myLeading = HorizontalAlignment(MyLeadingAlignment.self)
}
dnph8jn4

dnph8jn41#

像这样的吗

var body: some View {
    GeometryReader { geo in
        HStack {
            Text(textContent)
                .fixedSize()
                .animation(nil, value: go)
                .id(go)
                .transition(transition)
                .onAppear {
                    go.toggle()
                }
                .animation(.linear(duration: animationDuration).repeatForever(autoreverses: false), value: go)
                .frame(alignment: alignment)
                .id(reset)
                .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
                    reset.toggle()
                }
        }
        .clipped()
        .offset(y: -5)
    }
}

您可以使用它,使它在代码中更整洁地工作。

相关问题