mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-28 19:05:49 +00:00
Automatically relayout cells after orientation changed.
This commit is contained in:
parent
8da9ddd884
commit
e657bedd40
@ -15,6 +15,7 @@
|
||||
#import "ASDisplayNodeInternal.h"
|
||||
#import "ASBatchFetching.h"
|
||||
#import "UICollectionViewLayout+ASConvenience.h"
|
||||
#import "ASInternalHelpers.h"
|
||||
|
||||
const static NSUInteger kASCollectionViewAnimationNone = UITableViewRowAnimationNone;
|
||||
|
||||
@ -121,6 +122,8 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
BOOL _implementsInsetSection;
|
||||
|
||||
ASBatchContext *_batchContext;
|
||||
|
||||
BOOL _pendingRelayoutForAllRows;
|
||||
}
|
||||
|
||||
@property (atomic, assign) BOOL asyncDataSourceLocked;
|
||||
@ -168,6 +171,11 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
|
||||
[self registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"_ASCollectionViewCell"];
|
||||
|
||||
if (ASSystemVersionLessThan8()) {
|
||||
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -177,6 +185,11 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
// This bug might be iOS 7-specific.
|
||||
super.delegate = nil;
|
||||
super.dataSource = nil;
|
||||
|
||||
if (ASSystemVersionLessThan8()) {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@ -462,6 +475,32 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Orientation Change Handling
|
||||
|
||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
|
||||
{
|
||||
_pendingRelayoutForAllRows = YES;
|
||||
}
|
||||
|
||||
- (void)deviceOrientationDidChange
|
||||
{
|
||||
_pendingRelayoutForAllRows = YES;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
if (_pendingRelayoutForAllRows) {
|
||||
_pendingRelayoutForAllRows = NO;
|
||||
[self performBatchAnimated:NO updates:^{
|
||||
[_dataController relayoutAllRows];
|
||||
} completion:nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Batch Fetching
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#import "ASRangeController.h"
|
||||
#import "ASDisplayNodeInternal.h"
|
||||
#import "ASBatchFetching.h"
|
||||
#import "ASInternalHelpers.h"
|
||||
|
||||
//#define LOG(...) NSLog(__VA_ARGS__)
|
||||
#define LOG(...)
|
||||
@ -131,6 +132,8 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
|
||||
NSIndexPath *_contentOffsetAdjustmentTopVisibleRow;
|
||||
CGFloat _contentOffsetAdjustment;
|
||||
|
||||
BOOL _pendingRelayoutForAllRows;
|
||||
}
|
||||
|
||||
@property (atomic, assign) BOOL asyncDataSourceLocked;
|
||||
@ -183,6 +186,11 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
|
||||
_batchContext = [[ASBatchContext alloc] init];
|
||||
|
||||
_automaticallyAdjustsContentOffset = NO;
|
||||
|
||||
if (ASSystemVersionLessThan8()) {
|
||||
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style
|
||||
@ -220,6 +228,11 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
|
||||
// This bug might be iOS 7-specific.
|
||||
super.delegate = nil;
|
||||
super.dataSource = nil;
|
||||
|
||||
if (ASSystemVersionLessThan8()) {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@ -343,6 +356,31 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
|
||||
[_dataController endUpdatesAnimated:animated completion:completion];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Orientation Change Handling
|
||||
|
||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
|
||||
{
|
||||
_pendingRelayoutForAllRows = YES;
|
||||
}
|
||||
|
||||
- (void)deviceOrientationDidChange
|
||||
{
|
||||
_pendingRelayoutForAllRows = YES;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
if (_pendingRelayoutForAllRows) {
|
||||
_pendingRelayoutForAllRows = NO;
|
||||
[self beginUpdates];
|
||||
[_dataController relayoutAllRows];
|
||||
[self endUpdates];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Editing
|
||||
|
||||
|
||||
@ -154,6 +154,12 @@ typedef NSUInteger ASDataControllerAnimationOptions;
|
||||
|
||||
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions;
|
||||
|
||||
/**
|
||||
* Re-measures all loaded nodes. Used for external relayout (relayout that is caused by a change in constrained size of each and every cell node,
|
||||
* for example, after an orientation change).
|
||||
*/
|
||||
- (void)relayoutAllRows;
|
||||
|
||||
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions;
|
||||
|
||||
- (void)reloadDataWithAnimationOptions:(ASDataControllerAnimationOptions)animationOptions completion:(void (^)())completion;
|
||||
|
||||
@ -555,6 +555,26 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)relayoutAllRows
|
||||
{
|
||||
[self performEditCommandWithBlock:^{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
LOG(@"Edit Command - relayoutRows");
|
||||
[_editingTransactionQueue waitUntilAllOperationsAreFinished];
|
||||
|
||||
NSArray *indexPaths = ASIndexPathsForMultidimensionalArray(_completedNodes);
|
||||
NSArray *loadedNodes = ASFindElementsInMultidimensionalArrayAtIndexPaths(_completedNodes, indexPaths);
|
||||
|
||||
for (NSUInteger i = 0; i < loadedNodes.count && i < indexPaths.count; i++) {
|
||||
// TODO: The current implementation does not make use of different constrained sizes per node.
|
||||
CGSize constrainedSize = [_dataSource dataController:self constrainedSizeForNodeAtIndexPath:indexPaths[i]];
|
||||
ASCellNode *node = loadedNodes[i];
|
||||
[node measure:constrainedSize];
|
||||
node.frame = CGRectMake(0.0f, 0.0f, node.calculatedSize.width, node.calculatedSize.height);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||
{
|
||||
[self performEditCommandWithBlock:^{
|
||||
|
||||
@ -24,4 +24,8 @@ CGFloat ASCeilPixelValue(CGFloat f);
|
||||
|
||||
CGFloat ASRoundPixelValue(CGFloat f);
|
||||
|
||||
BOOL ASSystemVersionLessThan8();
|
||||
|
||||
BOOL ASSystemVersionLessThanVersion(NSString *version);
|
||||
|
||||
ASDISPLAYNODE_EXTERN_C_END
|
||||
|
||||
@ -61,3 +61,18 @@ CGFloat ASRoundPixelValue(CGFloat f)
|
||||
{
|
||||
return roundf(f * ASScreenScale()) / ASScreenScale();
|
||||
}
|
||||
|
||||
BOOL ASSystemVersionLessThan8()
|
||||
{
|
||||
static BOOL lessThan8;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
lessThan8 = ASSystemVersionLessThanVersion(@"8");
|
||||
});
|
||||
return lessThan8;
|
||||
}
|
||||
|
||||
BOOL ASSystemVersionLessThanVersion(NSString *version)
|
||||
{
|
||||
return [[[UIDevice currentDevice] systemVersion] compare:version options:NSNumericSearch] == NSOrderedAscending;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user