Skip to content

Commit

Permalink
Handle case where a subclass/something shuts the label down between a…
Browse files Browse the repository at this point in the history
…nimations [Common]
  • Loading branch information
cbpowell committed Jun 8, 2018
1 parent 62a6ddf commit a2ec26b
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 17 deletions.
34 changes: 25 additions & 9 deletions Sources/ObjC/MarqueeLabel.m
Original file line number Diff line number Diff line change
Expand Up @@ -576,22 +576,38 @@ - (void)scrollAwayWithInterval:(NSTimeInterval)interval delayAmount:(NSTimeInter

__weak __typeof__(self) weakSelf = self;
self.scrollCompletionBlock = ^(BOOL finished) {
if (!finished || !weakSelf) {
// Do not continue into the next loop
if (!weakSelf) {
return;
}

// Call returned home method
[weakSelf labelReturnedToHome:YES];

// Check to ensure that:
// 1) We don't double fire if an animation already exists
// 2) The instance is still attached to a window - this completion block is called for
// 1) The instance is still attached to a window - this completion block is called for
// many reasons, including if the animation is removed due to the view being removed
// from the UIWindow (typically when the view controller is no longer the "top" view)
if (self.window && ![weakSelf.subLabel.layer animationForKey:@"position"]) {
// Begin again, if conditions met
if (weakSelf.labelShouldScroll && !weakSelf.tapToScroll && !weakSelf.holdScrolling) {
[weakSelf scrollAwayWithInterval:interval delayAmount:delayAmount shouldReturn:shouldReturn];
}
if (!weakSelf.window) {
return;
}
// 2) We don't double fire if an animation already exists
if ([weakSelf.subLabel.layer animationForKey:@"position"]) {
return;
}
// 3) We don't not start automatically if the animation was unexpectedly interrupted
if (!finished) {
// Do not continue into the next loop
return;
}
// 4) A completion block still exists for the NEXT loop. A notable case here is if
// returnLabelToHome was called during a subclass's labelReturnToHome function
if (!weakSelf.scrollCompletionBlock) {
return;
}

// Begin again, if conditions met
if (weakSelf.labelShouldScroll && !weakSelf.tapToScroll && !weakSelf.holdScrolling) {
[weakSelf scrollAwayWithInterval:interval delayAmount:delayAmount shouldReturn:shouldReturn];
}
};

Expand Down
21 changes: 13 additions & 8 deletions Sources/Swift/MarqueeLabel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -840,11 +840,6 @@ open class MarqueeLabel: UILabel, CAAnimationDelegate {
#endif

scrollCompletionBlock = { [weak self] (finished: Bool) -> () in
guard finished else {
// Do not continue into the next loop
return
}

guard (self != nil) else {
return
}
Expand All @@ -853,17 +848,27 @@ open class MarqueeLabel: UILabel, CAAnimationDelegate {
self!.labelReturnedToHome(true)

// Check to ensure that:
// 1) We don't double fire if an animation already exists
// 2) The instance is still attached to a window - this completion block is called for

// 1) The instance is still attached to a window - this completion block is called for
// many reasons, including if the animation is removed due to the view being removed
// from the UIWindow (typically when the view controller is no longer the "top" view)
guard self!.window != nil else {
return
}

// 2) We don't double fire if an animation already exists
guard self!.sublabel.layer.animation(forKey: "position") == nil else {
return
}
// 3) We don't not start automatically if the animation was unexpectedly interrupted
guard finished else {
// Do not continue into the next loop
return
}
// 4) A completion block still exists for the NEXT loop. A notable case here is if
// returnLabelToHome() was called during a subclass's labelReturnToHome() function
guard (self!.scrollCompletionBlock != nil) else {
return
}

// Begin again, if conditions met
if (self!.labelShouldScroll() && !self!.tapToScroll && !self!.holdScrolling) {
Expand Down

0 comments on commit a2ec26b

Please sign in to comment.