import UIKit
class MarqueeText: UIView {
public var text: String? {
willSet {
nameLabel?.text = newValue
setNeedsLayout()
}
}
public var textColor: UIColor = UIColor.colorWithHexString(color: "ffffff") {
willSet {
nameLabel?.textColor = newValue
}
}
public var textFont: UIFont = .systemFont(ofSize: 14, weight: .medium) {
willSet {
nameLabel?.font = newValue
}
}
private weak var displayLink: CADisplayLink?
private var duration: TimeInterval = 0
/// 是否向左滚动标记
private var isLeft: Bool = true
/// 是否需要滚动标记
private var isCanRun: Bool = true
private weak var nameLabel: UILabel?
private weak var scrollView: UIScrollView?
private weak var leftGlassLayer: CAGradientLayer?
private weak var rightGlassLayer: CAGradientLayer?
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.clear
initSubviews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
displayLink?.isPaused = true
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if isCanRun {
displayLink?.isPaused = false
}
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
if isCanRun {
displayLink?.isPaused = false
}
}
deinit {
self.displayLink?.invalidate()
self.displayLink = nil
}
override func layoutSubviews() {
super.layoutSubviews()
let textSize = nameLabel?.text?.strwidth(str: (nameLabel?.text)!, font: 14)
let margin: CGFloat = 0
let textWith = textSize!.width + margin * 2
scrollView?.frame = bounds
scrollView?.backgroundColor = UIColor.clear
scrollView?.contentSize = CGSize(width: 0, height: textWith)
nameLabel?.frame = CGRect(x: 0, y: 0, width: textWith, height: textSize!.height)
duration = 0
nameLabel?.backgroundColor = UIColor.clear
isCanRun = textWith > width
displayLink?.isPaused = width >= textWith
leftGlassLayer?.isHidden = width >= textWith
rightGlassLayer?.isHidden = width >= textWith
leftGlassLayer?.frame = CGRect(x: 0, y: 0, width: 25, height: height)
rightGlassLayer?.frame = CGRect(x: width - 25, y: 0, width: 25, height: height)
}
private func initSubviews() {
let scrollView = UIScrollView()
scrollView.isUserInteractionEnabled = false
scrollView.showsVerticalScrollIndicator = false
scrollView.showsHorizontalScrollIndicator = false
addSubview(scrollView)
self.scrollView = scrollView
let nameLabel = UILabel()
nameLabel.textAlignment = .center
nameLabel.font = textFont
nameLabel.textColor = textColor
scrollView.addSubview(nameLabel)
self.nameLabel = nameLabel
let displayLink = CADisplayLink(target: self, selector: #selector(timerEvent))
displayLink.add(to: RunLoop.current, forMode: RunLoop.Mode.common)
displayLink.isPaused = true
self.displayLink = displayLink
let leftGlassLayer = CAGradientLayer()
leftGlassLayer.startPoint = .zero
leftGlassLayer.endPoint = CGPoint(x: 1, y: 0)
// leftGlassLayer.colors = [UIColor.colorWithHexString(color: "6DD781").cgColor, UIColor.colorWithHexString(color: "6DD781", alpha: 0).cgColor]
leftGlassLayer.colors = [UIColor.clear.cgColor]
layer.addSublayer(leftGlassLayer)
self.leftGlassLayer = leftGlassLayer
let rightGlassLayer = CAGradientLayer()
rightGlassLayer.startPoint = .zero
rightGlassLayer.endPoint = CGPoint(x: 1, y: 0)
// rightGlassLayer.colors = [UIColor.colorWithHexString(color: "6DD781", alpha: 0).cgColor, UIColor.colorWithHexString(color: "6DD781").cgColor]
rightGlassLayer.colors = [UIColor.clear.cgColor]
layer.addSublayer(rightGlassLayer)
self.rightGlassLayer = rightGlassLayer
}
var i = 0
@objc private func timerEvent() {
if duration == 0 {
if i == 0 {
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { [self] in
abcd()
i = 0
}
i = 1
}
} else {
abcd()
}
}
/// 定时器事件
func abcd() {
let maxWith = (nameLabel?.width ?? 0) - width + 40
let scale: TimeInterval = 0.3
if duration < 0 {
isLeft = false
duration += scale
} else if duration >= 0 && duration <= TimeInterval(maxWith) {
if isLeft {
duration -= scale
} else {
duration += scale
}
} else {
isLeft = true
duration = 0
}
scrollView?.setContentOffset(CGPoint(x: duration, y: 0), animated: false)
}
}
/**
其中 leftGlassLayer 和 rightGlassLayer 是滚动是两边的文字模糊效果的遮罩层;maxWith 为 Label 在 ScrollView 上的x轴方向上的最大滚动宽度;在不超过最大滚动宽度时,进行 self.duration += scale 操作即向右运动;超过最大滚动宽度时宽度,进行 self.duration -= scale 操作即向左运动;调整 scale 大小可以控制滚动的快慢。
作者:苍眸之宝宝
链接:https://www.jianshu.com/p/913d04808c34
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*/
使用
comName_LbBgView.addSubview(MarqueeTextView)
MarqueeTextView.snp.makeConstraints { (make) in
make.top.bottom.right.leading.equalToSuperview()
}
网友评论