UIKitWorkarounds 0.2.3

UIKitWorkarounds 0.2.3

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布上次发布2016年2月

Nick Tymchenko维护。



此仓库收集了各种UIKit类中我发现有用的典型修复和工作方案。虽然UIKit是一个非常好的框架,但有时会遇到一些不应该出现的问题。幸运的是,通常可以在不深入私有API和那些不寻常的事情的情况下修复行为。

请注意,这并不是一个典型的“类别袋”工具包。在这里,您找不到义务的 UIColor+HexUIView+Geometry 类别 :) 目标是修复破损或考虑不周全的东西,而不是带来新特性。

无需多言,以下是模块的快速概述。

界面方向转发

长期以来,我一直对原装容器视图控制器不会自动将supportedInterfaceOrientations转发给当前活动的子控制器感到恼火。我们应该为此使用委托,但这很快就会变成一团糟——当你需要使用委托做其他事情时。

目前有两个类别方法可以修改这种行为并设置正确的子转发

// Put this somewhere early in the app life cycle
[UINavigationController nn_setupCorrectInterfaceOrientationManagement];
[UITabBarController nn_setupCorrectInterfaceOrientationManagement];

UINavigationController的状态栏样式

在典型的UINavigationController配置中,导航栏位于顶部,形成应用程序状态栏的背景。因此,状态栏样式应该依赖于特定导航栏的外观是有意义的。换句话说,您希望在浅色导航栏上方有深色状态栏,反之亦然。

这就是我们需要的类别

@interface UINavigationBar (NNStatusBarStyle)

@property (nonatomic, assign) UIStatusBarStyle nn_statusBarStyle UI_APPEARANCE_SELECTOR;

@end

使用非常简单

// Put this somewhere early to activate the behaviour
[UINavigationController nn_setupCorrectStatusBarStyleManagement];

[UINavigationBar appearance].nn_statusBarStyle = UIStatusBarStyleLightContent;

实现中的关键部分是知道何时我们应该放弃状态栏样式管理。也就是说,如果导航栏当前被隐藏,则状态栏样式管理就转交给顶部子视图控制器,因为它现在是形成状态栏背景的那一个。

UITableView / UICollectionView的重新加载器

不幸的是,UITableViewUICollectionView 批量更新是损坏的。很可能是由相同的后台引擎驱动的,它们都存在许多相似的错误,在某些不幸的情况下会导致崩溃或不正确显示的数据。

为了处理这个问题,提供了 NNTableViewReloaderNNCollectionViewReloader 类。将它们视为视图的可丢弃包装器,具有相同的重新加载API:

@interface NNCollectionViewReloader : NSObject

- (void)performUpdates:(void (^)())updates completion:(nullable void (^)())completion;

- (void)insertSections:(NSIndexSet *)sections;
- (void)deleteSections:(NSIndexSet *)sections;
- (void)reloadSections:(NSIndexSet *)sections;
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection;

- (void)insertItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
- (void)deleteItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
- (void)reloadItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
- (void)reloadItemsAtIndexPathsWithCustomBlock:(NSArray<NSIndexPath *> *)indexPaths;
- (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath;

@end

你可能已经注意到了一个额外的方法,reloadItemsAtIndexPathsWithCustomBlock:。它允许你使用在创建重载器时提供的自定义块来重载单元格。这在多种场景下可能很有用,例如你需要同时移动和重载数据行的情况——通常这不被支持,可能导致一些问题。

示例用法即将提供。

NNTableViewReloader *reloader = [[NNTableViewReloader alloc] initWithTableView:self.tableView];

[reloader performUpdates:^{
    [reloader insertRowsAtIndexPaths:@[ ... ] withRowAnimation:UITableViewRowAnimationFade];
    [reloader deleteRowsAtIndexPaths:@[ ... ] withRowAnimation:UITableViewRowAnimationAutomatic];
    // etc.
} completion:nil];

将很快提供关于解决bug的更详细描述(包含实时示例)。