此仓库收集了各种UIKit类中我发现有用的典型修复和工作方案。虽然UIKit是一个非常好的框架,但有时会遇到一些不应该出现的问题。幸运的是,通常可以在不深入私有API和那些不寻常的事情的情况下修复行为。
请注意,这并不是一个典型的“类别袋”工具包。在这里,您找不到义务的 UIColor+Hex
或 UIView+Geometry
类别 :) 目标是修复破损或考虑不周全的东西,而不是带来新特性。
无需多言,以下是模块的快速概述。
长期以来,我一直对原装容器视图控制器不会自动将supportedInterfaceOrientations
转发给当前活动的子控制器感到恼火。我们应该为此使用委托,但这很快就会变成一团糟——当你需要使用委托做其他事情时。
目前有两个类别方法可以修改这种行为并设置正确的子转发
// Put this somewhere early in the app life cycle
[UINavigationController nn_setupCorrectInterfaceOrientationManagement];
[UITabBarController nn_setupCorrectInterfaceOrientationManagement];
在典型的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
批量更新是损坏的。很可能是由相同的后台引擎驱动的,它们都存在许多相似的错误,在某些不幸的情况下会导致崩溃或不正确显示的数据。
为了处理这个问题,提供了 NNTableViewReloader
和 NNCollectionViewReloader
类。将它们视为视图的可丢弃包装器,具有相同的重新加载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的更详细描述(包含实时示例)。