Skip to content

Instantly share code, notes, and snippets.

@timonus
Last active January 6, 2017 19:01
Show Gist options
  • Save timonus/452456f6790c2fb78723 to your computer and use it in GitHub Desktop.
Save timonus/452456f6790c2fb78723 to your computer and use it in GitHub Desktop.
AppSwitchScrollStopper
// UIWindow+AppSwitchScrollStopper.h
// Created by Tim Johnsen on 3/27/16.
#import <UIKit/UIKit.h>
@interface UIWindow (AppSwitchScrollStopper)
/// Call this early on in your app's lifecycle to avoid
/// scroll-related flashing when your app resumes from the background
- (void)installAppSwitchScrollStopper;
@end
// UIWindow+AppSwitchScrollStopper.m
// Created by Tim Johnsen on 3/27/16.
#import "UIWindow+AppSwitchScrollStopper.h"
@interface UIView (AppSwitchScrollStopper)
- (void)recursiveStopScrolling;
@end
@implementation UIView (AppSwitchScrollStopper)
- (void)recursiveStopScrolling
{
if ([self isKindOfClass:[UIScrollView class]]) {
UIScrollView *scrollView = (UIScrollView *)self;
// Stop the scrolling (http://stackoverflow.com/a/3421387/3943258)
[scrollView setContentOffset:scrollView.contentOffset animated:NO];
// Stop the scroll indicators from being captured
if (scrollView.showsHorizontalScrollIndicator) {
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsHorizontalScrollIndicator = YES;
}
if (scrollView.showsVerticalScrollIndicator) {
scrollView.showsVerticalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = YES;
}
}
for (UIView *view in self.subviews) {
[view recursiveStopScrolling];
}
}
@end
@implementation UIWindow (AppSwitchScrollStopper)
+ (void)load
{
void (^stopScrollingBlock)(NSNotification *_Nonnull notification) = ^(NSNotification *_Nonnull notification) {
for (UIWindow *window in [self windowsToStopScrolling]) {
[window recursiveStopScrolling];
}
};
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:stopScrollingBlock];
// Works in iOS extensions too!
if (&NSExtensionHostDidEnterBackgroundNotification) {
[[NSNotificationCenter defaultCenter] addObserverForName:NSExtensionHostDidEnterBackgroundNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:stopScrollingBlock];
}
}
+ (NSMutableSet<UIWindow *> *)windowsToStopScrolling
{
static NSMutableSet<UIWindow *> *windowsToStopScrolling = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
windowsToStopScrolling = [NSMutableSet new];
});
return windowsToStopScrolling;
}
- (void)installAppSwitchScrollStopper
{
[[[self class] windowsToStopScrolling] addObject:self];
}
@end
@Austinate
Copy link

That is very cool, thanks!
Maybe it will be cool to add prefixes for all methods so someone won't be in trouble if they will be copy-pasting that into their projects

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment