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 is compatible with both iOS and tvOS!
Check it out!
How To Get Started
- Clone MarqueeLabel from GitHub, and check out the demo project.
- Read the MarqueeLabel CocoaDocs documentation.
- 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.
- Add MarqueeLabel.h and MarqueeLabel.m, or MarqueeLabel.swift, to your project.
- Add QuartzCore.framework to your project frameworks.
- Import MarqueeLabel and replace your UILabels with MarqueeLabels as needed.
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
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 it's 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!
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.
UILabel *lengthyLabel = [[UILabel alloc] initWithFrame:aFrame];
MarqueeLabel *lengthyLabel = [[MarqueeLabel alloc] initWithFrame:aFrame duration:8.0 andFadeLength:10.0f];
var lengthyLabel = UILabel.init(frame:aFrame)
var lengthyLabel = MarqueeLabel.initWithFrame(frame:aFrame duration:8.0 andFadeLength:10.0)
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!
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)
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
restartLabelinstance 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!
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!
controllerLabelsShouldAnimate: 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.
Give me a shout if you're using this in your project!