Kyle Kyle - 8 days ago 5
iOS Question

globally update all uitableviewcell

I'm working on a Dark mode for an application. The basic premise to have a toggle allowing users to switch between a dark and a light mode.

I'm trying to figure out the best way to update all

UITableViewCell's
. IE in 'light mode' the cells background color is whiteish and in dark more the cells background color is darkish.

Currently I am accomplishing this by using

- (void) tableView: (UITableView *) tableView
willDisplayCell: (UITableViewCell *) cell
forRowAtIndexPath: (NSIndexPath *) indexPath
{
if(darkMode)
{
cell.backgroundColor = darkBackground;
cell.textLabel.textColor = darkTextColor;
}
else
{
cell.backgroundColor = lightBackground;
cell.textLabel.textColor = lightTextColor;
}
} // End of tableView:willDisplayCell:forRowAtIndexPath:


The problem is, when a user switches from dark/light I want all cells to be redrawn so that the backgrounds are updated. I can do this on a per table base by calling an individual
uitableview
reloaddata
, but I want to have EVERY tableview already loaded in the application to reload. Is this possible?

Answer

My currently solution is to swizzle UITableView's and add a notification handler. I'm not positive if this will be my final implementation as I'm still investigating. The quick code looks something like this:

#import <JRSwizzle.h>

@implementation UITableView (Swizzle)

+ (void) load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSError *error = nil;

        const SEL deallocSel  = NSSelectorFromString(@"dealloc");

        BOOL result =
            [[self class] jr_swizzleMethod: @selector(initWithFrame:style:)
                                withMethod: @selector(initSQLProWithFrame:style:)
                                     error: &error];

        if (!result || error)
        {
            NSLog(@"Can't swizzle methods - %@", [error description]);
        }

        result =
            [[self class] jr_swizzleMethod: @selector(initWithCoder:)
                                withMethod: @selector(initSQLProWithCoder:)
                                     error: &error];

        if (!result || error)
        {
            NSLog(@"Can't swizzle methods - %@", [error description]);
        }

        result =
            [[self class] jr_swizzleMethod: deallocSel
                                withMethod: @selector(SQLProDealloc)
                                     error: &error];

        if (!result || error)
        {
            NSLog(@"Can't swizzle methods - %@", [error description]);
        }
    });
}

- (instancetype) initSQLProWithFrame: (CGRect)frame
                               style: (UITableViewStyle) style
{
    self = [self initSQLProWithFrame: frame
                               style: style];

    if(self)
    {
        NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];

        [nc addObserver: self
               selector: @selector(themeChanged)
                   name: [SQLProAppearanceManager apperanceUpdatedNotificationName]
                 object: nil];

    } // End of self

    return self;
} // End of initSQLProWithFrame:style:

- (instancetype) initSQLProWithCoder: (NSCoder*) coder
{
    self = [self initSQLProWithCoder: coder];

    if(self)
    {
        NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];

        [nc addObserver: self
               selector: @selector(themeChanged)
                   name: [SQLProAppearanceManager apperanceUpdatedNotificationName]
                 object: nil];
    } // End of self

    return self;
} // End of initSQLProWithCoder:

- (void) themeChanged
{
    [self reloadData];
} // End of themeChanged

- (void) SQLProDealloc
{
    NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];

    [nc removeObserver: self
                  name: [SQLProAppearanceManager apperanceUpdatedNotificationName]
                object: nil];

    [self SQLProDealloc];
} // End of SQLProDealloc

@end