SwiftUI 使用SwiftUI实现跑马灯效果 Marquee

OC类型的demo很多 这里就不提了 

直接上代码吧

public struct MarqueeText : View {

    public var text = ""

    public var font: UIFont

    public var leftFade: CGFloat

    public var rightFade: CGFloat

    public var startDelay: Double

    @State private var animate = false

    public var body : some View {

        let stringWidth = text.getWidthOfString(usingFont: font)

        let stringHeight = text.heightOfString(usingFont: font)

        return ZStack {

            GeometryReader { geometry in

                Group {

                    Text(self.text).lineLimit(1)

                        .font(.init(font))

                        .offset(x: self.animate ? -stringWidth - stringHeight * 2 : 0)

                        .animation(Animation.linear(duration: Double(stringWidth) / 30).delay(startDelay).repeatForever(autoreverses: false)

                        )

                        .onAppear() {

                            if geometry.size.width < stringWidth {

                                self.animate = true

                            }

                        }

                        .fixedSize(horizontal: true, vertical: false)

                        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)

                    Text(self.text).lineLimit(1)

                        .font(.init(font))

                        .offset(x: self.animate ? 0 : stringWidth + stringHeight * 2)

                        .animation(Animation.linear(duration: Double(stringWidth) / 30).delay(startDelay).repeatForever(autoreverses: false)

                        )

                        .fixedSize(horizontal: true, vertical: false)

                        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)

                }.offset(x: leftFade)

                .mask(

                    HStack(spacing:0) {

                        Rectangle()

                            .frame(width:2)

                            .opacity(0)

                        LinearGradient(gradient: Gradient(colors: [Color.black.opacity(0), Color.black]), startPoint: .leading, endPoint: .trailing)

                            .frame(width:leftFade)

                        LinearGradient(gradient: Gradient(colors: [Color.black, Color.black]), startPoint: .leading, endPoint: .trailing)

                        LinearGradient(gradient: Gradient(colors: [Color.black, Color.black.opacity(0)]), startPoint: .leading, endPoint: .trailing)

                            .frame(width:rightFade)

                        Rectangle()

                            .frame(width:2)

                            .opacity(0)

                    }).frame(width: geometry.size.width + leftFade).offset(x: leftFade * -1)

            }

        }.frame(height: stringHeight)

    }

    public init(text: String, font: UIFont, leftFade: CGFloat, rightFade: CGFloat, startDelay: Double) {

        self.text = text

        self.font = font

        self.leftFade = leftFade

        self.rightFade = rightFade

        self.startDelay = startDelay

    }

}

extension String {

    func getWidthOfString(usingFont font: UIFont) -> CGFloat {

        let fontAttributes = [NSAttributedString.Key.font: font]

        let size = self.size(withAttributes: fontAttributes)

        return size.width

    }

    func heightOfString(usingFont font: UIFont) -> CGFloat {

        let fontAttributes = [NSAttributedString.Key.font: font]

        let size = self.size(withAttributes: fontAttributes)

        return size.height

    }

}

调用的时候

//跑马灯

                    MarqueeText(

                         text: "文字文字文字文字文字文字文字文字文字文字文字文字文字文字",

                         font: UIFont.preferredFont(forTextStyle: .subheadline),

                         leftFade: 15,

                         rightFade: 15,

                         startDelay: 1)

                        .padding(.leading,100)

                        .padding(.trailing,100)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值