如何在Swift中使用MarqueeLabel?

How to use MarqueeLabel in Swift?

我想知道是否有一种方法可以启用文本的水平滚动,即选取框类型的文本。我使用了这个库:https://github.com/cbpowell/MarqueeLabel 并将“MarqueeLabel.Swift”文件添加到我的应用程序中。但是到目前为止,它并没有显示出我想要的跑马灯效果。

我是这样实现的:

class ViewController: UIViewController 
{
@IBOutlet weak var marqueeLabel: MarqueeLabel! 
override func viewDidLoad() {
    super.viewDidLoad()
        self.marqueeLabel.tag = 101
        self.marqueeLabel.type = .Continuous
        self.marqueeLabel.speed = .Duration(5)
        self.marqueeLabel.animationCurve = .EaseInOut
        self.marqueeLabel.fadeLength = 10.0
        self.marqueeLabel.leadingBuffer = 30.0
        self.marqueeLabel.trailingBuffer = 20.0
        self.marqueeLabel.restartLabel()
 }
}

我已经根据中的解决方案在界面生成器中设置了自定义class。还是不行。

我得到的只是一个没有字幕效果(或水平文本滚动)的标签显示。

P.S:我也是 iOS 开发的新手。此外,在实现此库之前,我尝试使用 UIScrollView 和 UITextView。而且我无法使用 UIWebView,因为我正试图在 TVOS 中实现它。

我的问题是:

  1. 我代码哪里出错了?

  2. 是否有使用 Swift 显示选取框效果的替代方法?

提前致谢。

我使用这段代码让我的标签像选取框一样滚动:

@IBOutlet weak var firstLabel: UILabel! 
override func viewDidLoad() {
    super.viewDidLoad()

    UIView.animateWithDuration(12.0, delay: 1, options: ([.CurveLinear, .Repeat]), animations: {() -> Void in
            self.firstLabel.center = CGPointMake(0 - self.firstLabel.bounds.size.width / 2, self.firstLabel.center.y)
            }, completion:  { _ in })
}

是的,成功了。

在SWIFT 3:

@IBOutlet weak var YOURLABEL: UILabel!
override func viewDidLoad() {
    super.viewDidLoad()
    UIView.animate(withDuration: 12.0, delay: 1, options: ([.curveLinear, .repeat]), animations: {() -> Void in
        self.YOURLABEL.center = CGPoint(x: 0 - self.YOURLABEL.bounds.size.width / 2, y: self.YOURLABEL.center.y)
    }, completion:  { _ in })
}

已针对 Swift3 更新,未使用任何第三方库或 pods

import UIKit

class ViewController: UIViewController {

    let redLabel: UILabel = {

        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = .boldSystemFont(ofSize: 16)
        label.textColor = .red
        label.text = "The first paragraph of the body should contain the strongest argument, most significant example, cleverest illustration, or an obvious beginning point."
        return label
    }()

    let greenLabel: UILabel = {

        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = .systemFont(ofSize: 14)
        label.textColor = .green
        label.text = "The second paragraph of the body should contain the second strongest argument, second most significant example, second cleverest illustration, or an obvious follow up the first paragraph in the body."
        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        title = "Marquee Label Demo"
        view.backgroundColor = .white

        view.addSubview(redLabel)
        view.addSubview(greenLabel)

        setupAutoLayout()
        startMarqueeLabelAnimation()
    }

    func startMarqueeLabelAnimation() {

        DispatchQueue.main.async(execute: {

            UIView.animate(withDuration: 10.0, delay: 1, options: ([.curveLinear, .repeat]), animations: {() -> Void in

                self.redLabel.center = CGPoint(x: 0 - self.redLabel.bounds.size.width / 2, y: self.redLabel.center.y)
                self.greenLabel.center = CGPoint(x: 0 - self.greenLabel.bounds.size.width / 2, y: self.greenLabel.center.y)

            }, completion:  nil)
        })
    }

    func setupAutoLayout() {

        redLabel.leftAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        redLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
        redLabel.heightAnchor.constraint(equalToConstant: 20).isActive = true

        greenLabel.leftAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        greenLabel.topAnchor.constraint(equalTo: redLabel.bottomAnchor, constant: 50).isActive = true
        greenLabel.heightAnchor.constraint(equalToConstant: 20).isActive = true
    }
}

特别感谢:

https://whosebug.com/users/8303852/kartik-patel

https://whosebug.com/users/8388863/sid-patel

单击此处查看演示 1

简单选取框 - Swift 4.0:

override func viewDidLoad() {
    super.viewDidLoad()
    marqueeLabel.text = " text text here!"
    _ = Timer.scheduledTimer(timeInterval: 0.3, target: self, selector: #selector(ViewController.marquee), userInfo: nil, repeats: true)
}
extension ViewController {
  @objc func marquee(){

    let str = marqueeLabel.text!
    let indexFirst = str.index(str.startIndex, offsetBy: 0)
    let indexSecond = str.index(str.startIndex, offsetBy: 1)
    marqueeLabel.text = String(str.suffix(from: indexSecond)) + String(str[indexFirst])

  }
}

由于最初的问题与 tvOS 有关,我刚刚错误地发现(经过数周的搜索!)tvOS 12 beta 已经实现了这个:

只有当祖先被聚焦时(比如当我们为电影海报添加标题并滚动到它时)才能获得选取框效果,当然,如果那样的话,可以直接使用 TVUIKit (like in this example 中的 TVPosterView是目标,但它仍然适用于单个标签。

在Swift 4

代码

UIView.animate(withDuration: 1.0, delay: 1, options: ([.curveLinear, .repeat]), animations: {() -> Void in
            self.marqueeLABEL.center = CGPoint(x: self.marqueeLABEL.bounds.size.width, y: self.marqueeLABEL.center.y)
        }, completion:  { _ in })

你应该像这样使用它才会起作用。

注意:您可能会遇到性能问题,因为它在 Thread 中使用递归,因此为了获得更好的性能,您应该使用 CATextLayer 和 CAScrollLayer。

import UIKit
import SnapKit

class ViewController: UIViewController {
    
    let label = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        label.lineBreakMode = .byWordWrapping
        label.numberOfLines = 0
       
        label.text = "We couldn't turn around 'Til we were upside down I'll be the bad guy now But no, I ain't too proud I couldn't be there Even when I try You don't believe it We do this every time"
       
        view.addSubview(label)
        label.snp.makeConstraints { (make) in
           make.height.equalTo(20)
            make.top.leading.trailing.equalTo(self.view.safeAreaLayoutGuide).inset(50)
        }
      
        autoScroll()
    }
    
    @objc func autoScroll() {
        UIView.animate(withDuration: 12.0, delay: 1, options: ([.curveLinear, .repeat]), animations: {() -> Void in
            self.label.center = CGPoint(x: 0 - self.label.bounds.size.width / 2,y: self.label.center.y)
        }, completion:  { _ in
            self.autoScroll()
        })
    }
}