Code Monkey home page Code Monkey logo

marqueelabel's Introduction

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!

GIF of MarqueeLabelDemo in action

How To Get Started

  1. Clone MarqueeLabel from GitHub, and check out the demo project.
  2. Read through the documentation embedded in the MarqueeLabel.swift source.
  3. Take a look at the special notes section to be aware of any gotchas.
  4. Drop in MarqueeLabel as a replacement to your lengthy UILabels!
  5. Help out with bug fixes and new features.

Installation

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

  1. Add MarqueeLabel.swift, to your project.
  2. Add QuartzCore.framework to your project frameworks.
  3. 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

Buy Me A Coffee

Give me a shout if you're using this in your project!

marqueelabel's People

Contributors

8secz-johndpope avatar aaronbrethorst avatar ale-gen avatar alexbell avatar amarcadet avatar amosavian avatar bbodenmiller avatar ben9923 avatar bleeez avatar cbpowell avatar delannoyk avatar dillan avatar edrflt avatar eric avatar felix-dumit avatar fredpi avatar hariseldon78 avatar hyperkit avatar ikesyo avatar jw97 avatar kwongius avatar lucasderraugh avatar markbeaton avatar matthewcheok avatar mazyod avatar readmecritic avatar thenortheestern avatar toshi0383 avatar vladkorotnev avatar yoiang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

marqueelabel's Issues

Continuously scrolls right

Hi,

Please how use Continuously scrolls right (with a pause at the original position if animationDelay is set).

thx for help

Stops scrolling

When a MarqueeLabel is implemented in an initial ViewController, and another ViewController is pushed on, and then popped off again (returning to the initial ViewController) the MarqueeLabel no longer animates.

Label animation

If the app goes into the background then foreground the label stop animating.

Animating the frame of the MarqueeLabel

Hi, I've tried to animate the position of the label an encountered the following issues:

On the demo project, on view did appear I tried to animate the Alpha. Didn't work until I disabled the timer (still don't understand why).

The second problem, yet unresolved, is trying to animate the frame of it. Couldn't get it to work (the label simply snaps to it's final destination frame immediately).

it can not work on a tableview cell

it cannot get the cell nextresponder, because the cell didn't have been added on the tableview. i try to add [MarqueeLabel controllerViewAppearing:self] in viewdidappear method, it looks work well. but when i am scrolling the tableview, the animation stopped.

Centered Text

Any chance of adding this feature, as i can only have left and right alignment :-/

Removed drawRect method causes issues

Hi,

your missing drawRect method causes issues :-(
My programmatically created tableViews and all other views have no problems with this change.
I guess, it has something to do with my collectionView but I'm not quite sure. This is the only place in my app, where I use MarqueeLabel in my storyboard. Maybe it has something to do with the initWithCoder call.

- (void)drawRect:(CGRect)rect {
    // Do nothing, override UILabel drawing
}

WITH DRAWRECT:
ios simulator bildschirmfoto 17 05 2014 00 40 25

WITHOUT DRAWRECT:
ios simulator bildschirmfoto 17 05 2014 00 40 42

marqueeLable Not working in CustomUitableview Cell

Hi

This is really nice Class.

I used it two places.

  1. on viewcontroller header label to set header of scree.

It is working fine for me.

Issue=>

  1. But This lable is not working in my custom table cell

I am having three subview in custom cell and i want to pul this lable in each subview and scroll it.

Labels in table in custom cells won't display before scrolling down and up again

I've tried everything. I have a table view controller with custom cells which have marquee labels. I configure them in the cellForRowAtIndexPath method and if the screen appears all views and subviews show up except the marquee labels. Then if I just scroll a bit down and up the label works. The array from which the labels get their data contents the same valid data. I tried moving some code to different methods from willDisplayCell till viewDidAppear but nothing worked. I hope you have any idea.

problem while add MarqueeLabel in a navigation bar

I tried to add MarqueeLabel to a navigation bar, but it can not run any animation

problem is the "firstAvailableViewController" method returns a UINavigationController, not a UIViewController showing in UINavigationController, so the animation control logic is broken, any idea to fix this?

MarqueeLabel Not Scrolling

I used the code from the demo but the MarqueeLabel just doesn't scroll! It's on the same position as in the demo app but only cut and not scrolling. Any ideas?

MarqueeLabel *rateLabelOne = [[MarqueeLabel alloc] initWithFrame:CGRectMake(10, 200, self.view.frame.size.width-20, 20) rate:50.0f andFadeLength:10.0f];

rateLabelOne.numberOfLines = 1;
rateLabelOne.opaque = NO;
rateLabelOne.enabled = YES;
rateLabelOne.fadeLength = 10.f;
rateLabelOne.shadowOffset = CGSizeMake(0.0, -1.0);
rateLabelOne.textAlignment = NSTextAlignmentLeft;
rateLabelOne.textColor = [UIColor colorWithRed:0.234 green:0.234 blue:0.234 alpha:1.000];
rateLabelOne.backgroundColor = [UIColor clearColor];
rateLabelOne.font = [UIFont fontWithName:@"Helvetica-Bold" size:17.000];
rateLabelOne.text = @"This is another long label that scrolls at a specific rate, rather than scrolling its length in a specific time window!";

// For Autoresizing test
rateLabelOne.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self.view addSubview:rateLabelOne];

Text not showing up

Hey,

I am trying to use your component on UITableViewCells, and the interesting thing here is that the frame for the label is not available till the cell is rendered and layoutSubviews is called.

So... When I set the text property, while the frame of the label is still at CGRectZero, the text never shows up, unless I call setText: again after setting the MarqueeLabel frame, which is not ideal, obviously.

MarqueeLabel *label = /* Label with CGRectZero frame */;
label.text = @"This will not work";
label.frame = theFrame;
label.text = @"This will work";

If you have an idea what this is, please assist. I am trying to fix it anyways.

Thanks!

Wrap around text?

Is it possible to set this up to Wrap around text? If not, maybe that's something you might want to add? I might just go ahead and add it today just for the hell of it.

Label won't reset if text is changed

I have a label that is set to scroll continuously. Sometimes the text exceeds to given space, then the label scrolls. Sometimes the text does not exceed the given space, then the label centers the text.

However, if I have a label that started scrolling once and for which I then replace the text (small enough to not cause it to scroll):

myLabel.text = @"New text";

...it will not re-center itself. The label is then stuck at the right-most position of the view.

My expectation would be that the label re-centers itself.

Stackoverflow in returnLabeLToOriginImmediately

Hi,

I'm investigating now a stack overflow case where returnLabeLToOriginImmediately keeps calling it self.

- (void)returnLabelToOriginImmediately {
    NSArray *labels = [self allSubLabels];
    CGFloat offset = 0.0f;
    for (UILabel *sl in labels) {
        [sl.layer removeAllAnimations];
        sl.frame = CGRectOffset(self.homeLabelFrame, offset, 0.0f);
        offset += (self.marqueeType == MLContinuousReverse ? -1 : 1) * (self.homeLabelFrame.size.width + self.fadeLength + self.continuousMarqueeExtraBuffer);
    }

    if (self.subLabel.frame.origin.x == self.homeLabelFrame.origin.x) {
        self.awayFromHome = NO;
    } else {
        [self returnLabelToOriginImmediately];
    }
}

So as you can see the IF statement the end is false.

This happens on iOS 7.0 Beta 6. I'm setting the label after the view has appeared.

'sizeWithFont:constrainedToSize:lineBreakMode:' is deprecated

Hi,
I am developing my first iOS app and I would like to use your UILabel subclass for it. Everything is working fine, great work you did with this but I am wondering about the two warnings I receive in the .m file. These methods seems to be deprecated in iOS 7 and I want to know how this affect my application. I mean, it behave like it should but when I will upload to Apple Store there could be negative responses regarding it? What do you suggest?
P.S. I didn't find you e-mail anywhere that's why I post an issue here. :)

Invisible or Incorrect Positioning when using Autolayout

By default, the label is invisible (not laid out properly) if laid out using autolayout.
As a test, I made sure the frame of the sublabel was being set to the same as the marquee label since I initialize it with an empty frame which autolayout replaces and that the intrinsic content size is passed through to autolayout:

- (void)layoutSubviews
{
    [super layoutSubviews];
    [self.subLabel setFrame:[self bounds]];
}

- (CGSize)intrinsicContentSize
{
    return [_subLabel intrinsicContentSize];
}

but this causes the label to start toward the top right of the frame it is supposed to occupy, and move toward the bottom left when animating.

wildy oscillating

I have an intermittent issue where a label is wildly oscillating and sometimes crashes when the content is greater than 30 characters.

I noticed after a crash that interval in scrollAwayWithInterval was set to something like 36.600000000000001, so I tried truncating it, but it didn't work.
I think that may be a red herring.

The problem doesn't occur every time, until it does, then it is every time.

Called by:
largeHeaderText = [[MarqueeLabel alloc] initWithFrame:CGRectMake(55, 2.3, screenRect.size.width - 110, 35) rate:5.0f andFadeLength:6.0f];

Can't set marqueelabel in block

Hi, I have set marqueelabel, it works great everywhere except in block. I have a method which request data from server, after got data it call back in block, and then I set the text for MarqueeLabel, but it can't scroll

Not possible to set scroll speed when used with storyboards

Is there a way to control the speed when I can't use the (id)initWithFrame:(CGRect)frame rate:(CGFloat)pixelsPerSec andFadeLength:(CGFloat)fadeLength; initializer?

At the moment I replaced the class of a UILabel in my storyboard with MarqueeLabel which uses the default speed. I don't see a way to adjust that.

Very long text loses custom color

Hey,

First of all - incredible control, thank you very much!

I've used MarqueeLabel to present a long line of text in continuos mode with a custom text color, and noticed that at end of every cycle of the first sub-label the text reverts to black.

As far as I can tell, this happens because the custom color is not being set to the second sub label created. I have to admit that I didn't get to the root of this, but fixed it for now locally by adding "sl.textColor = self.textColor;" after line 331.

Podspec not updated for iOS compatibility

The Podspec file is still referencing iOS 5 as compatible, but since version 1.2.4 its compatibility has been broken by auto layout support.
Podspec for 1.2.4 and 1.2.5 should be updated otherwise developers would use that versions believing in full compatibility.

halt/unhalt animation

It would be nice to have an option to halt the animation. Similar to labelize, but instead of go back to the beginning of the label, it stops where the text is animated to. When unhalted, the text then starts animating from where it was halted at.

Thanks for the nice control :)

William

Semantic Issue: Duplicate declarations of two methods...

I'm blocked from compiling because of duplicate definitions of these two methods in MarqueeLabel.m:

  • (NSAttributedString *)attributedText;
  • (void)setAttributedText:(NSAttributedString *)attributedText;

The second two are inside an #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000 block, but my version of Xcode doesn't seem to care. As I understand it, Objective-C doesn't allow overloading.

I'm running Xcode 4.6.3.

Crash Report

The marquee label is crashing for me with the following:
2012-10-29 23:47:54.970 Navigator[54234:c07] *** NSForwarding: warning: selector (0x11bbcd) for message 'v8@0:4' does not match selector known to Objective C runtime (0x85311f0)-- abort 2012-10-29 23:47:54.971 Navigator[54234:c07] -[MarqueeLabel v8@0:4]: unrecognized selector sent to instance 0x13628440

Crashing on line 327 of MarqueeLabel.m:
CGRect continuousLabelFrame = CGRectMake(self.fadeLength, 0, expectedLabelSizeDoubled.width, self.bounds.size.height);

Continuous scroll not working?

I want a label to scroll continuously, linearly. But it always slows down, then speeds up, as it nears the end of the text. I don't want that: I want a constant rate of speed, cycling forever.

Below is how I have it set up. What am I doing wrong?

CGFloat legendX = CGRectGetMaxX(self.graphTitleLabel.frame) + 20;
CGRect legendFrame = CGRectMake(legendX, self.graphTitleLabel.frame.origin.y, frame.size.width - legendX, self.graphTitleLabel.frame.size.height);
self.legendView = [[MarqueeLabel alloc] initWithFrame:legendFrame rate:30 andFadeLength:0];
self.legendView.autoresizingMask = (UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin);
self.legendView.backgroundColor = [UIColor blackColor];
[self addSubview:self.legendView];
self.legendView.textColor = [UIColor whiteColor];
self.legendView.font = [WidgetViewController titleWidgetFontOfSize:self.graphTitleLabel.font.pointSize];
self.legendView.marqueeType = MLContinuous;
self.legendView.animationCurve = UIViewAnimationCurveLinear;
self.legendView.animationDelay = 0;
self.legendView.text = @"Fourscore and seven years ago, our fathers brought forth upon this continent ";

Use an attributedText instead of an regulard Text

Hello,

Thank-you for the wonderful work !

I'm looking for a way to have in my MarqueeLabel a multi color text. I've just discover attributedText and it seam to be the good stuff to use. But when I'm using the property myMarqueeLabel.attributedText it doesn't seam to work. Is there a way to use it ?

here is my code:

NSMutableAttributedString *titleString = [[NSMutableAttributedString alloc] initWithString:@""];

    NSDictionary *attributesStrong = [NSDictionary dictionaryWithObject:FONT_OPEN_SANS_SEMI_BOLD(12) forKey:NSFontAttributeName];
    NSDictionary *attributesRegulard = [NSDictionary dictionaryWithObject:FONT_OPEN_SANS_LIGHT(12) forKey:NSFontAttributeName];
    NSAttributedString * boldText = [[NSAttributedString alloc] initWithString:@"bold text" attributes:attributesStrong];
    NSAttributedString * lightText = [[NSAttributedString alloc] initWithString:@"light text" attributes:attributesRegulard];
    [titleString appendAttributedString:boldText];
    [titleString appendAttributedString:suffixText];

    self.titleLabel.attributedText = titleString;

NSAttributedString compatibility

First off, thanks for the awesome library. MarqueeLabel is an incredibly useful tool.

However, I'm unable to use an NSAttributedString with it. I tested the exact same code with a regular UILabel and it works... am I doing something wrong or is this library unable to use attributed strings? If the latter, what are the chances of introducing this feature?

Label is truncated with "…" though it should scroll

Hi,

I have an issue with a special case in my app. The text is just approx 1px longer than the label's width. I have set fadeLength = 4.0f. The marqueeType is not set e.g "MLLeftRight"

I think I've tracked down the issue to the following method:

    - (BOOL)labelShouldScroll {
        BOOL stringLength = ([self.subLabel.text length] > 0);
        if (!stringLength) {
            return NO;
        }

        BOOL labelWidth = (self.bounds.size.width < [self subLabelSize].width + (self.marqueeType == MLContinuous ? 2 * self.fadeLength : self.fadeLength));
        return (!self.labelize && labelWidth);
    }

The problem is this if statement:
…(self.marqueeType == MLContinuous ? 2 * self.fadeLength : self.fadeLength)

when I replace it with
…(2 * self.fadeLength)

--> it does not truncate and scrolls properly
… as the label fades out on both sides, I think this should be the proper solution

Endless Loop causing App Crash

Hi,

first of all - awesome library!

Since the last update, I sometimes get an endlesse loop in "returnLabelToOriginImmediately" function. If I comment out the recursive call it works. What is the use case for the recusive function call [self returnLabelToOriginImmediately] in the last "else"?

- (void)returnLabelToOriginImmediately {

    [self.layer removeAllAnimations];

    NSArray *labels = [self.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"tag >= %i", 700]];
    CGFloat offset = 0.0f;
    for (UILabel *sl in labels) {
        [sl.layer removeAllAnimations];
        sl.frame = CGRectOffset(self.homeLabelFrame, offset, 0.0f);
        offset += (self.marqueeType == MLContinuousReverse ? -1 : 1) *    (self.homeLabelFrame.size.width + self.fadeLength + self.continuousMarqueeExtraBuffer);
    }

    if (self.subLabel.frame.origin.x == self.homeLabelFrame.origin.x) {
        self.awayFromHome = NO;
    } else {
//        [self returnLabelToOriginImmediately];
    }

}

Best regards,
Steve

Unable to change font size in MarqueeLabel

Hi Charles,

Thanks for the awesome marquee label!

I am having problems changing the Marquee label font size. I have tried changing the CGRectMake dimension and the font size, but still unable to make the font any larger.

Here is the code, please advise. Thanks in advance!

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {


        MarqueeLabel* continuousLabel = [[MarqueeLabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 60) rate:60.0f andFadeLength:5.0f];
        continuousLabel.tag = 102;
        continuousLabel.marqueeType = MLContinuous;
        continuousLabel.numberOfLines = 1;
        continuousLabel.opaque = NO;
        continuousLabel.enabled = YES;
        continuousLabel.shadowOffset = CGSizeMake(0.0, -1.0);
        continuousLabel.textAlignment = UITextAlignmentCenter;
        continuousLabel.textColor = [UIColor colorWithRed: 176.0f/255.0f green:176.0f/255.0f blue:176.0f/255.0f alpha:1.0];
        continuousLabel.backgroundColor = [UIColor clearColor];
        continuousLabel.font = [UIFont fontWithName:@"Cochin Bold" size:20.0];
        continuousLabel.text= @"Label Title";


        [self.view addSubview:continuousLabel];
    }
}

Useless gap with fadeLength when a label should not scroll

Hi,
First of all, thanks for your awesome class, you saved me a lot of time 😄

A have label with dynamic text so i don't know its content length.
When it's scrolling, i want to set a custom fadeLength so that the text gets smoothly cut.
But when it does not need to scroll, it seems logical to me that we don't need to display any fading mask.

Let's imagine this is my label frame

[              ]

When the text is too long (HELLO WORLD)

[      HELLO WO]

=> It's ok, this will scroll left

When the text fits the view (HELLO), i have this issue

[      HELLO       ] 

instead of

[HELLO             ]

There is a fadeLength large gap on the left, even if the label is left aligned.

For the moment, my quick fix is to set the labelShouldScroll property as public so that i set the fadeLength to zero.
But i think the expected behaviour would like not to applay any fading if the text fits the label.

Was it intentional?

Thx

Memory Reference Cycle

I discovered an issue in your code that results in a retain/reference cycle which effectively causes alloced MarqueeLabels to never be dealloced by ARC. I also found what equates to a memory leak in the same function.

Both occur in the -setupLabel function, specifically with the device orientation handling observer and block. In your code, you utilize "self" within a block, which per-Apple, will usually lead to reference cycles (See "Avoid Strong Reference Cycles when Capturing self" in http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html)

Following their recommendation, I created and used a __weak reference to self, which did resolve the memory reference cycle issue.

Also, the [addObserverForName::::] function that is used returns an object (id) that must be removed from the NSNotificationCenter defaultCenter such that the NotificationCenter releases that specific observer. By storing the returned NSObserver as a class ivar, then releasing it in the classes -dealloc method, I was able to fix this problem as well.

The updated code that fixes these two issues looks like:

- (void) setupLabel
{
...

    MarqueeLabel *__weak weakSelf = self;

   self.speedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillChangeStatusBarOrientationNotification
                                                      object:nil
                                                       queue:nil
                                                  usingBlock:^(NSNotification *notification){
                                                      weakSelf.orientationWillChange = YES;
                                                      [[NSNotificationCenter defaultCenter] addObserverForName:@"UIViewAnimationDidStopNotification"
                                                                                                        object:nil
                                                                                                         queue:nil
                                                                                                    usingBlock:^(NSNotification *notification){
                                                                                                        if ([notification.userInfo objectForKey:@"delegate"] == weakSelf.window) {
                                                                                                            weakSelf.orientationWillChange = NO;
                                                                                                            [weakSelf restartLabel];

                                                                                                            // Remove notification observer
                                                                                                            [[NSNotificationCenter defaultCenter] removeObserver:weakSelf name:@"UIViewAnimationDidStopNotification" object:nil];
                                                                                                        }
                                                                                                    }];
                                                  }];
}

- (void) dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [[NSNotificationCenter defaultCenter] removeObserver:self.speedObserver];
    [self.subLabel removeFromSuperview];
}

A simple fix, but definitely improves app memory footprint over long run times!

Best,
Matt

Performance issue

When implementing UITableViewCell with MarqueeLabel and pushing the view with more then 3 cells
the animation is lag and not smooth

Animating after view appeared

Hi,

I noticed that if you comment out "viewDidLoad" on the demo, and create a label in "viewDidAppear", it will not animate, unless you run

[MarqueeLabel controllerViewAppearing:self];

AFTER you added the label to the view.
This becomes a serious problem when you want to add more labels later to the same view (if you run the code above again it will restart the animation on existing labels).

Maybe I missed something?

UIView Animations when Labels are paused

Hi,

First I would just like to say, fab control - thanks alot.

I noticed a potential bug using MarqueeLabel in my app.

I'm using it to show FX prices tick by, and when I get new prices I like to fade the alpha value of the MarqueeLabel in and out using a UIVIew animation block. The animation is to signify the change in price.

This all works well unless the label is paused, if it is paused and I try to animate (say the alpha value) it stops responding. It won't reanimate if I try to unpause it etc.

Not sure if this is really a bug but just wanted to get your thoughts...

PS. my current workaround is to basically unpause and repause after the animation is complete, this works, but unfortunately the label drifts by for a moment while the animation is in progress, which kind of defeats the purpose of the original pause.

Thanks again,
Kind Regards,
John

Label animates very fast to "awayFrame"

Hey

I'm currently using your MarqueeLabel and I like it A LOT.

There's one little problem I encountered when dealing with the unwanted stopping of the animation. I restart it by a notification when I reload my tableview which contains your marqueelabels. That works, they spring back to home position and slowly start to move.

However when I switch my ViewController via an animation and come back, I see the marqueelabel perfectly reseted (as I sent the notification that my viewcontroller appeared again) on the "homeFrame", however now after 1sec the label animates VERY FAST to the awayFrame and from THERE it starts to animate slowly, going home.

Here's a video: http://cl.ly/2C21080R450n

Thanks for your help!!

Possible memory reference cycle

Hi!

I ran into a memory leak in my project earlier and I tracked it down to -setupLabel. I found out that issue #23 is still there because the line

if ([notification.userInfo objectForKey:@"delegate"] == self.window) {

still refers to self instead of weakSelf

I'm pretty new with Objective-C, so I apologize if I'm mistaken.
Anyway, thanks for the great work.

i have a tabbarcontroller,when i change tabbar ,MarqueeLabel lose animation

// Return labels to home frame
[self returnLabelToOriginImmediately];

UIViewController *viewController = [self firstAvailableViewController];
NSLog(@"viewController.isViewLoaded %d", viewController.isViewLoaded);
NSLog(@"viewController.view.window %@", viewController.view.window);
if (!(viewController.isViewLoaded && viewController.view.window)) {

    return;
}

when i change tabbar,the viewController.view.window will turn to null.
MarqueeLabel lose animation.
how can i fix it?

High speed animation bug

Hi Charles,

Thanks for this project, I'm finding it very useful. This issue has been raised several times and partially solved. As you know, on rotation the label does it's high speed animation, which you addressed via the notification centre acting on status bar orientation change. However, the bug also appears when the label's view controller changes frame size when in a popover. In a split view project, in portrait, my master table view controller is resized by the keyboard appearing. When it hides, any cells (containing labels) that had not been dequeued prior to the popover resize get the speed bug. Any ideas would be greatly appreciated.

One other point, I found the notification centre approach to solving the bug on rotation to be very detrimental to performance - the more rotations that you do the slower it gets.

Initialization with empty string issue

After initializing the marqueeLabel, if set to empty string (i.e. [marqueeLabel setText:@""]), then any other setText: call seems to have no effect (the text is not displayed), but if the self.labelText initialization from setupLabel method is changed to self.labelText = [NSString string]; (instead of self.labelText = nil;) everything seems to work just fine.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.