MarqueeLabel
A drop-in replacement for UILabel, which automatically adds a scrolling marquee effect when the label's text does not fit inside the specified frame
Top Related Projects
An easy to use UITableViewCell subclass that allows to display swippable buttons with a variety of transitions.
A drop-in replacement for UILabel that supports attributes, data detectors, links, and more
[EXPERIMENTAL] Graceful morphing effects for UILabel written in Swift.
👩🎨 Elegant Attributed String composition in Swift sauce
Quick Overview
MarqueeLabel is a Swift library for iOS that provides a UILabel subclass with a scrolling marquee effect. It allows for easy implementation of scrolling text labels in iOS applications, supporting both left-to-right and right-to-left text directions.
Pros
- Easy to integrate into existing iOS projects
- Customizable scrolling behavior and appearance
- Supports both Swift and Objective-C
- Actively maintained with regular updates
Cons
- Limited to iOS platform only
- May not be suitable for complex text animations beyond scrolling
- Potential performance impact on devices with limited resources
- Requires manual setup for some advanced features
Code Examples
- Basic usage:
let marqueeLabel = MarqueeLabel(frame: CGRect(x: 20, y: 100, width: 200, height: 30))
marqueeLabel.text = "This is a scrolling label with MarqueeLabel!"
view.addSubview(marqueeLabel)
- Customizing scroll behavior:
let marqueeLabel = MarqueeLabel.init(frame: CGRect(x: 20, y: 100, width: 200, height: 30), duration: 8.0, fadeLength: 10.0)
marqueeLabel.marqueeType = .leftRight
marqueeLabel.animationCurve = .easeInOut
marqueeLabel.text = "Customized scrolling behavior!"
- Using with Auto Layout:
let marqueeLabel = MarqueeLabel()
marqueeLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(marqueeLabel)
NSLayoutConstraint.activate([
marqueeLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
marqueeLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
marqueeLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
marqueeLabel.heightAnchor.constraint(equalToConstant: 30)
])
marqueeLabel.text = "This label uses Auto Layout constraints!"
Getting Started
- Add MarqueeLabel to your project using Swift Package Manager, CocoaPods, or Carthage.
- Import the library in your Swift file:
import MarqueeLabel
- Create a MarqueeLabel instance and add it to your view:
let marqueeLabel = MarqueeLabel(frame: CGRect(x: 20, y: 100, width: 200, height: 30)) marqueeLabel.text = "Your scrolling text here" view.addSubview(marqueeLabel)
- Customize the label's appearance and behavior as needed using the available properties and methods.
Competitor Comparisons
An easy to use UITableViewCell subclass that allows to display swippable buttons with a variety of transitions.
Pros of MGSwipeTableCell
- Provides swipeable table cells with customizable buttons and actions
- Supports both left and right swipe directions
- Offers various transition styles and animations for swipe actions
Cons of MGSwipeTableCell
- Limited to table view cells, not applicable for other UI elements
- Requires more setup and configuration compared to MarqueeLabel
- May have a steeper learning curve for implementing complex swipe behaviors
Code Comparison
MarqueeLabel:
let marqueeLabel = MarqueeLabel.init(frame: CGRect(x: 20, y: 100, width: 200, height: 30))
marqueeLabel.text = "This is a long text that will scroll"
marqueeLabel.type = .continuous
marqueeLabel.speed = .duration(15)
self.view.addSubview(marqueeLabel)
MGSwipeTableCell:
cell.rightButtons = [MGSwipeButton(title: "Delete", backgroundColor: .red)]
cell.leftButtons = [MGSwipeButton(title: "More", backgroundColor: .blue)]
cell.leftSwipeSettings.transition = .rotate3D
cell.rightSwipeSettings.transition = .clipCenter
While MarqueeLabel focuses on creating scrolling text labels, MGSwipeTableCell specializes in adding swipe actions to table cells. MarqueeLabel is simpler to implement for text animations, while MGSwipeTableCell offers more complex interactions for table views. The choice between the two depends on the specific UI requirements of the project.
A drop-in replacement for UILabel that supports attributes, data detectors, links, and more
Pros of TTTAttributedLabel
- Supports rich text formatting with NSAttributedString
- Offers automatic data detection for URLs, addresses, phone numbers, etc.
- Provides customizable link appearance and handling
Cons of TTTAttributedLabel
- Lacks built-in scrolling or marquee functionality
- May require more setup for basic text display compared to UILabel
Code Comparison
TTTAttributedLabel:
let label = TTTAttributedLabel(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
label.text = "Hello, World!"
label.linkAttributes = [NSAttributedString.Key.foregroundColor: UIColor.blue]
label.activeLinkAttributes = [NSAttributedString.Key.backgroundColor: UIColor.lightGray]
label.addLink(to: URL(string: "https://example.com"), with: NSRange(location: 0, length: 5))
MarqueeLabel:
let label = MarqueeLabel(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
label.text = "Hello, World!"
label.type = .continuous
label.speed = .duration(15.0)
label.animationDelay = 2.0
MarqueeLabel focuses on creating scrolling text effects, while TTTAttributedLabel excels in rich text formatting and link handling. The choice between the two depends on the specific requirements of your project, such as whether you need scrolling text or advanced text attribute management.
[EXPERIMENTAL] Graceful morphing effects for UILabel written in Swift.
Pros of LTMorphingLabel
- Offers a variety of morphing effects for text transitions
- Supports both Swift and Objective-C
- Provides customizable animation duration and timing functions
Cons of LTMorphingLabel
- Limited to text morphing animations, not scrolling or marquee effects
- May have higher performance overhead for complex morphing effects
- Requires iOS 8.0 or later, potentially limiting compatibility with older devices
Code Comparison
MarqueeLabel:
let marqueeLabel = MarqueeLabel(frame: CGRect(x: 20, y: 100, width: 200, height: 30))
marqueeLabel.text = "This is a scrolling label"
marqueeLabel.type = .continuous
marqueeLabel.speed = .duration(15)
marqueeLabel.fadeLength = 10.0
LTMorphingLabel:
let morphingLabel = LTMorphingLabel(frame: CGRect(x: 20, y: 100, width: 200, height: 30))
morphingLabel.text = "Initial Text"
morphingLabel.morphingEffect = .evaporate
morphingLabel.text = "Morphed Text"
Both libraries offer unique label animation capabilities, with MarqueeLabel focusing on scrolling effects and LTMorphingLabel specializing in text morphing transitions. The choice between them depends on the specific animation requirements of your project.
👩🎨 Elegant Attributed String composition in Swift sauce
Pros of SwiftRichString
- Focuses on rich text styling and manipulation
- Offers a wide range of text formatting options
- Supports complex text attributes and styles
Cons of SwiftRichString
- Lacks scrolling or animation capabilities
- May require more setup for basic text styling
- Not specifically designed for marquee-style text effects
Code Comparison
MarqueeLabel:
let marqueeLabelLeft = MarqueeLabel.init(frame: CGRect(x: 0, y: 100, width: 200, height: 30))
marqueeLabelLeft.text = "This is a MarqueeLabel"
marqueeLabelLeft.type = .leftRight
marqueeLabelLeft.scrollDuration = 15.0
self.view.addSubview(marqueeLabelLeft)
SwiftRichString:
let style = Style {
$0.color = .red
$0.font = SystemFonts.boldSystemFont(ofSize: 15)
}
let attributedString = "This is a SwiftRichString".set(style: style)
let label = UILabel(frame: CGRect(x: 0, y: 100, width: 200, height: 30))
label.attributedText = attributedString
self.view.addSubview(label)
MarqueeLabel is specifically designed for creating scrolling text effects, making it ideal for marquee-style animations. It offers easy setup and control over scrolling behavior.
SwiftRichString, on the other hand, excels in rich text styling and manipulation. It provides a powerful API for creating complex text attributes and styles, but lacks built-in scrolling or animation features.
Choose MarqueeLabel for scrolling text effects, and SwiftRichString for advanced text styling and formatting needs.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Overview
MarqueeLabel is a UILabel subclass adds a scrolling marquee effect when the text of the label outgrows the available width. The label scrolling direction and speed/rate can be specified as well. All standard UILabel properties (where it makes sense) are available in MarqueeLabel, with the intent of MarqueeLabel behaving just like a UILabel.
MarqueeLabel will be maintained in Swift only starting with release 4.0!
MarqueeLabel is compatible with both iOS and tvOS, and currently works with Swift 5.0 and the iOS 12.2 SDK! (But if you're looking for prior version Swift compatibility, you can check the older releases)
Check it out!
How To Get Started
- Clone MarqueeLabel from GitHub, and check out the demo project.
- Read through the documentation embedded in the
MarqueeLabel.swift
source. - Take a look at the special notes section to be aware of any gotchas.
- Drop in MarqueeLabel as a replacement to your lengthy UILabels!
- Help out with bug fixes and new features.
Installation
CocoaPods
To use MarqueeLabel in a project, add the following to your project's Podfile:
pod 'MarqueeLabel'
Carthage
Add the following to your project's Cartfile:
github "cbpowell/MarqueeLabel"
Manual Installation
- Add MarqueeLabel.swift, to your project.
- Add QuartzCore.framework to your project frameworks.
- Import MarqueeLabel and replace your UILabels with MarqueeLabels as needed.
Using MarqueeLabel in your own Swift Framework?
See the Special Note below on supporting Cocoapods and Carthage simultaneously in a Swift framework!
Usage
MarqueeLabel automatically scrolls its text, at either a defined rate (points per second) or over a duration (seconds), whenever the length of the label's text exceeds the space available given the label's frame.
There are several options for the Marquee type, and the default is Continuous
(which looks just like what Apple typically uses). The animation curve of this scroll can be defined, and defaults to UIViewAnimationOptionCurveLinear
.
There are also several optional features to help with your integration of the scrolling nature of MarqueeLabel:
- An optional edge fade at the left and right edges of the view, in order to fade the label text into the background rather than simply being clipped off
- Leading and trailing buffers to offset the label text inside its frame, giving you better control over alignment
- "Labelization" to make your MarqueeLabel exactly like a UILabel.
- Scroll animation "holding" and pausing
See the included demo project for several use case examples!
Code
These lines of code create a MarqueeLabel that will scroll across its content in 8.0 seconds, and adds 10.0 point long fade at the left and right boundaries.
Replace:
var lengthyLabel = UILabel.init(frame:aFrame)
With:
var lengthyLabel = MarqueeLabel.init(frame: aFrame, duration: 8.0, fadeLength: 10.0)
Storyboards
If you're using Storyboards/Interface Builder you can create a MarqueeLabel instance by adding a normal UILabel view to your Storyboard, and then manually changing the view's class to MarqueeLabel
in the "Custom Class" field of the Identity Inspector tab on the Utilities panel (the right-side panel).
Note: If you forget to change the Custom Class field to MarqueeLabel
and then try to access/set MarqueeLabel-specific properties in your code, you will get crashes!
You can then configure the normal UILabel properties, as well as most of the MarqueeLabel configuration properties, via the Attributes tab of the Utility panel!
Even More
Check out the MarqueeLabel documentation for more about all the features, including:
- Bulk-manipulation class methods to conveniently restart, pause, and unpause all labels in a view controller
- Scrolling direction: left->right, right->left, and continuous looping (both left and right)
Extras
Also check out the Extras folder, a collection of subclasses, extensions, and modifications for MarqueeLabel to implement various functionality that has been requested or suggested, but not merged into the MarqueeLabel code.
Special Notes
Automatic Font Size Adjustment
Starting with release 4.1, MarqueeLabel allows setting the adjustsFontSizeToWidth
to true
. When configured this way, MarqueeLabel will check to see if the text string
(non-attributed or attributed) will fit within the frame when adjusted to the specified minimum scale factor, and:
- if the text will fit at the adjusted scale without requiring truncation, the label will not scroll. Instead, the label text will be allowed to adjust to that size and will remain static.
- if the text will not fit, the label will scroll and retain the unscaled font size (i.e., like all releases prior to 4.1)
Previously MarqueeLabel would override any attempts to set adjustsFontSizetoWidth
and minimumScaleFactor
to the default settings used by UILabel (false
, and 0.0
, respectively). As such the default behavior remains the same: the label will not adjust it's font size to 'avoid' scrolling.
IBDesignables
MarqueeLabel includes support for IBInspectable and IBDesignable, to allow configuration of the label inside Interface Builder/Storyboards. However, if you see these warnings when building:
IB Designables: Failed to update auto layout status: Failed to load designables from path (null)
IB Designables: Failed to render instance of MarqueeLabel: Failed to load designables from path (null)
...then you are likely using MarqueeLabel as a static library, which does not support IBInspectable/IBDesignable. Some workarounds include:
- Install MarqueeLabel as a dynamic framework using CocoaPods with use_frameworks! in your Podfile
- Install MarqueeLabel with Carthage
- Install MarqueeLabel by manually importing the source files into your project (may be only option if you're targeting iOS 7.0)
Automatic Scrolling
MarqueeLabel tries its best to automatically begin scrolling when appropriate, but sometimes the way your view/view controller appears onscreen can trip it up.
To combat this, you can try:
- Using the
restartLabel
instance method to manually start scrolling on a MarqueeLabel - Try using the bulk manipulation class methods - but note that these don't currently play well with UIViewController containment. You'll need to pass them the lowest UIViewController in your hierarchy.
Use in UITableView and UICollectionView
As noted above, MarqueeLabel can sometimes have trouble detecting when the scroll animation should start when used in UITableViews and UICollectionViews - although recent reviews have improved this.
Usually you'll configure the MarqueeLabel instance when building the cell in tableView:cellForRowAtIndexPath:
(or similar for UICollectionView), but at this point the cell is not onscreen so MarqueeLabel will not begin the scrolling animation. Even when the cell is eventually placed onscreen as the user scrolls, due to timing it's possible that the animation will not fire.
To make sure the scrolling animation does begin as the cell scrolls onscreen, you can use the the restartLabel
method on your MarqueeLabels inside the tableView:willDisplayCell:forRowAtIndexPath:
delegate method (or similar for UICollectionView).
That said - the UITableView/UICollectionView best practice is to minimize things like excessive animation, subviews, and custom drawing in your cells, in order to get glassy smooth scrolling. In general I would recommend against allowing your labels to automatically animate during user scrolling of the UITableView/UICollectionView. I suggest holding scrolling or labelizing the labels while the user scrolls. See the table view example in the demo!
Important Animation Note
MarqueeLabel is based on Core Animation, which does cause some problems when views appear and disappear and the repeating animation is stopped by iOS and does not automatically restart.
To address this, MarqueeLabel provides a few class methods that allow easy "restarting" of all MarqueeLabels associated with a UIViewController. Specifically, the class method restartLabelsOfController:
should be called by your view controller (which passes in self
for the controller
parameter) when it is revealed or about to be revealed. Keep in mind that presenting a modal view controller can pause repeating UIView animations in the controller that is being covered!
controllerLabelsLabelize:
and controllerLabelsAnimate:
are for convenience, allowing labelizing and re-animating all labels of a UIViewController. Labelizing can be useful for performance, such as labelizing all MarqueeLabels when a UITableView/UIScrollView starts scrolling.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
MarqueeLabel.controllerViewDidAppear(self)
}
Todo
- Ideas?
About
Charles Powell
Give me a shout if you're using this in your project!
Top Related Projects
An easy to use UITableViewCell subclass that allows to display swippable buttons with a variety of transitions.
A drop-in replacement for UILabel that supports attributes, data detectors, links, and more
[EXPERIMENTAL] Graceful morphing effects for UILabel written in Swift.
👩🎨 Elegant Attributed String composition in Swift sauce
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot