Merge pull request #1653 from garrettmoon/visibility

[ASViewController] Add visibility depth management
This commit is contained in:
appleguy
2016-05-12 22:42:27 -07:00
10 changed files with 407 additions and 99 deletions

View File

@@ -250,6 +250,7 @@
509E68661B3AEDD7009B9150 /* CGRect+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E201B376416007741D0 /* CGRect+ASConvenience.m */; };
636EA1A41C7FF4EC00EE152F /* NSArray+Diffing.m in Sources */ = {isa = PBXBuildFile; fileRef = DBC452DA1C5BF64600B16017 /* NSArray+Diffing.m */; };
636EA1A51C7FF4EF00EE152F /* ASDefaultPlayButton.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */; };
680346941CE4052A0009FEB4 /* ASNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FC85DC1CE29AB700EDD713 /* ASNavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; };
68355B311CB5799E001D4E68 /* ASImageNode+AnimatedImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68355B2E1CB5799E001D4E68 /* ASImageNode+AnimatedImage.mm */; };
68355B341CB579B9001D4E68 /* ASImageNode+AnimatedImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68355B2E1CB5799E001D4E68 /* ASImageNode+AnimatedImage.mm */; };
68355B3A1CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B361CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m */; };
@@ -272,6 +273,17 @@
68EE0DBE1C1B4ED300BA1B99 /* ASMainSerialQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 68EE0DBB1C1B4ED300BA1B99 /* ASMainSerialQueue.h */; };
68EE0DBF1C1B4ED300BA1B99 /* ASMainSerialQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */; };
68EE0DC01C1B4ED300BA1B99 /* ASMainSerialQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */; };
68FC85DE1CE29AB700EDD713 /* ASNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FC85DC1CE29AB700EDD713 /* ASNavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; };
68FC85DF1CE29AB700EDD713 /* ASNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85DD1CE29AB700EDD713 /* ASNavigationController.m */; };
68FC85E21CE29B7E00EDD713 /* ASTabBarController.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FC85E01CE29B7E00EDD713 /* ASTabBarController.h */; settings = {ATTRIBUTES = (Public, ); }; };
68FC85E31CE29B7E00EDD713 /* ASTabBarController.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FC85E01CE29B7E00EDD713 /* ASTabBarController.h */; settings = {ATTRIBUTES = (Public, ); }; };
68FC85E41CE29B7E00EDD713 /* ASTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85E11CE29B7E00EDD713 /* ASTabBarController.m */; };
68FC85E51CE29B7E00EDD713 /* ASTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85E11CE29B7E00EDD713 /* ASTabBarController.m */; };
68FC85E61CE29B9400EDD713 /* ASNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85DD1CE29AB700EDD713 /* ASNavigationController.m */; };
68FC85E91CE29C7D00EDD713 /* ASVisibilityProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FC85E71CE29C7D00EDD713 /* ASVisibilityProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; };
68FC85EA1CE29C7D00EDD713 /* ASVisibilityProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FC85E71CE29C7D00EDD713 /* ASVisibilityProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; };
68FC85EB1CE29C7D00EDD713 /* ASVisibilityProtocols.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */; };
68FC85EC1CE29C7D00EDD713 /* ASVisibilityProtocols.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */; };
698548631CA9E025008A345F /* ASEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 698548611CA9E025008A345F /* ASEnvironment.h */; settings = {ATTRIBUTES = (Public, ); }; };
698548641CA9E025008A345F /* ASEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 698548611CA9E025008A345F /* ASEnvironment.h */; settings = {ATTRIBUTES = (Public, ); }; };
698C8B611CAB49FC0052DC3F /* ASLayoutableExtensibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 698C8B601CAB49FC0052DC3F /* ASLayoutableExtensibility.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -787,6 +799,12 @@
68B8A4E01CBDB958007E4543 /* ASWeakProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASWeakProxy.m; sourceTree = "<group>"; };
68EE0DBB1C1B4ED300BA1B99 /* ASMainSerialQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMainSerialQueue.h; sourceTree = "<group>"; };
68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMainSerialQueue.mm; sourceTree = "<group>"; };
68FC85DC1CE29AB700EDD713 /* ASNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASNavigationController.h; sourceTree = "<group>"; };
68FC85DD1CE29AB700EDD713 /* ASNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASNavigationController.m; sourceTree = "<group>"; };
68FC85E01CE29B7E00EDD713 /* ASTabBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTabBarController.h; sourceTree = "<group>"; };
68FC85E11CE29B7E00EDD713 /* ASTabBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTabBarController.m; sourceTree = "<group>"; };
68FC85E71CE29C7D00EDD713 /* ASVisibilityProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASVisibilityProtocols.h; sourceTree = "<group>"; };
68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASVisibilityProtocols.m; sourceTree = "<group>"; };
698548611CA9E025008A345F /* ASEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEnvironment.h; sourceTree = "<group>"; };
698C8B601CAB49FC0052DC3F /* ASLayoutableExtensibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutableExtensibility.h; path = AsyncDisplayKit/Layout/ASLayoutableExtensibility.h; sourceTree = "<group>"; };
69CB62A91CB8165900024920 /* _ASDisplayViewAccessiblity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASDisplayViewAccessiblity.h; sourceTree = "<group>"; };
@@ -1075,6 +1093,8 @@
68355B2E1CB5799E001D4E68 /* ASImageNode+AnimatedImage.mm */,
0516FA3E1A1563D200B4EBED /* ASMultiplexImageNode.h */,
0516FA3F1A1563D200B4EBED /* ASMultiplexImageNode.mm */,
68FC85DC1CE29AB700EDD713 /* ASNavigationController.h */,
68FC85DD1CE29AB700EDD713 /* ASNavigationController.m */,
055B9FA61A1C154B00035D6D /* ASNetworkImageNode.h */,
055B9FA71A1C154B00035D6D /* ASNetworkImageNode.mm */,
25E327541C16819500A2170C /* ASPagerNode.h */,
@@ -1083,6 +1103,8 @@
A2763D781CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.m */,
D785F6601A74327E00291744 /* ASScrollNode.h */,
D785F6611A74327E00291744 /* ASScrollNode.m */,
68FC85E01CE29B7E00EDD713 /* ASTabBarController.h */,
68FC85E11CE29B7E00EDD713 /* ASTabBarController.m */,
B0F880581BEAEC7500D17647 /* ASTableNode.h */,
9CFFC6C11CCAC768006A6476 /* ASTableNode.mm */,
055F1A3219ABD3E3004DAFF1 /* ASTableView.h */,
@@ -1098,6 +1120,8 @@
764D83D21C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h */,
764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m */,
DB55C2651C641AE4004EDCF5 /* ASContextTransitioning.h */,
68FC85E71CE29C7D00EDD713 /* ASVisibilityProtocols.h */,
68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */,
92074A5E1CC8B9DD00918F75 /* tvOS */,
058D09E1195D050800B7D73C /* Details */,
058D0A01195D050800B7D73C /* Private */,
@@ -1493,6 +1517,7 @@
058D0A82195D060300B7D73C /* ASAssert.h in Headers */,
0516FA3C1A15563400B4EBED /* ASAvailability.h in Headers */,
AEB7B01A1C5962EA00662EF4 /* ASDefaultPlayButton.h in Headers */,
68FC85E21CE29B7E00EDD713 /* ASTabBarController.h in Headers */,
ACF6ED1A1B17843500DA7C62 /* ASBackgroundLayoutSpec.h in Headers */,
058D0A83195D060300B7D73C /* ASBaseDefines.h in Headers */,
054963491A1EA066000F8E56 /* ASBasicImageDownloader.h in Headers */,
@@ -1508,6 +1533,7 @@
AC3C4A511A1139C100143C57 /* ASCollectionView.h in Headers */,
AEEC47E11C20C2DD00EC1693 /* ASVideoNode.h in Headers */,
DE8BEAC11C2DF3FC00D57C12 /* ASDelegateProxy.h in Headers */,
68FC85DE1CE29AB700EDD713 /* ASNavigationController.h in Headers */,
205F0E1D1B373A2C007741D0 /* ASCollectionViewLayoutController.h in Headers */,
AC3C4A541A113EEC00143C57 /* ASCollectionViewProtocols.h in Headers */,
058D0A49195D05CB00B7D73C /* ASControlNode+Subclasses.h in Headers */,
@@ -1533,6 +1559,7 @@
0587F9BD1A7309ED00AFF0BA /* ASEditableTextNode.h in Headers */,
DE6EA3221C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h in Headers */,
1950C4491A3BB5C1005C8279 /* ASEqualityHelpers.h in Headers */,
68FC85E91CE29C7D00EDD713 /* ASVisibilityProtocols.h in Headers */,
257754A81BEE44CD00737CA5 /* ASTextKitContext.h in Headers */,
DB55C2611C6408D6004EDCF5 /* _ASTransitionContext.h in Headers */,
464052221A3F83C40061C0BA /* ASFlowLayoutController.h in Headers */,
@@ -1667,6 +1694,7 @@
CC3B20841C3F76D600798563 /* ASPendingStateController.h in Headers */,
92074A621CC8BA1900918F75 /* ASImageNode+tvOS.h in Headers */,
B35061F71B010EFD0018CF92 /* ASCollectionViewProtocols.h in Headers */,
68FC85E31CE29B7E00EDD713 /* ASTabBarController.h in Headers */,
DE6EA3231C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h in Headers */,
9C70F20F1CDBE9FF007D6C76 /* ASLayoutManager.h in Headers */,
B35061FA1B010EFD0018CF92 /* ASControlNode+Subclasses.h in Headers */,
@@ -1674,6 +1702,7 @@
B35062171B010EFD0018CF92 /* ASDataController.h in Headers */,
B35062191B010EFD0018CF92 /* ASDealloc2MainObject.h in Headers */,
34EFC75B1B701BAF00AD841F /* ASDimension.h in Headers */,
68FC85EA1CE29C7D00EDD713 /* ASVisibilityProtocols.h in Headers */,
A37320101C571B740011FC94 /* ASTextNode+Beta.h in Headers */,
DBABFAFC1C6A8D2F0039EA4A /* _ASTransitionContext.h in Headers */,
9C70F2061CDA4F0C007D6C76 /* ASTraitCollection.h in Headers */,
@@ -1685,6 +1714,7 @@
B35062521B010EFD0018CF92 /* ASDisplayNodeInternal.h in Headers */,
B35062001B010EFD0018CF92 /* ASEditableTextNode.h in Headers */,
B350625B1B010F070018CF92 /* ASEqualityHelpers.h in Headers */,
680346941CE4052A0009FEB4 /* ASNavigationController.h in Headers */,
B350621B1B010EFD0018CF92 /* ASFlowLayoutController.h in Headers */,
B350621D1B010EFD0018CF92 /* ASHighlightOverlayLayer.h in Headers */,
C78F7E2B1BF7809800CDEAFC /* ASTableNode.h in Headers */,
@@ -1975,6 +2005,7 @@
files = (
058D0A22195D050800B7D73C /* _ASAsyncTransaction.mm in Sources */,
E55D86321CA8A14000A0C26F /* ASLayoutable.mm in Sources */,
68FC85E41CE29B7E00EDD713 /* ASTabBarController.m in Sources */,
058D0A23195D050800B7D73C /* _ASAsyncTransactionContainer.m in Sources */,
058D0A24195D050800B7D73C /* _ASAsyncTransactionGroup.m in Sources */,
68355B3A1CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m in Sources */,
@@ -2004,6 +2035,7 @@
AC3C4A521A1139C100143C57 /* ASCollectionView.mm in Sources */,
9CFFC6C21CCAC768006A6476 /* ASTableNode.mm in Sources */,
205F0E1E1B373A2C007741D0 /* ASCollectionViewLayoutController.mm in Sources */,
68FC85EB1CE29C7D00EDD713 /* ASVisibilityProtocols.m in Sources */,
058D0A13195D050800B7D73C /* ASControlNode.mm in Sources */,
464052211A3F83C40061C0BA /* ASDataController.mm in Sources */,
B30BF6531C5964B0004FCD53 /* ASLayoutManager.m in Sources */,
@@ -2028,6 +2060,7 @@
430E7C911B4C23F100697A4C /* ASIndexPath.m in Sources */,
ACF6ED231B17843500DA7C62 /* ASInsetLayoutSpec.mm in Sources */,
ACF6ED4C1B17847A00DA7C62 /* ASInternalHelpers.mm in Sources */,
68FC85DF1CE29AB700EDD713 /* ASNavigationController.m in Sources */,
ACF6ED251B17843500DA7C62 /* ASLayout.mm in Sources */,
DB55C2631C6408D6004EDCF5 /* _ASTransitionContext.m in Sources */,
92074A631CC8BA1900918F75 /* ASImageNode+tvOS.m in Sources */,
@@ -2161,6 +2194,7 @@
34EFC7641B701CC600AD841F /* ASCenterLayoutSpec.mm in Sources */,
18C2ED831B9B7DE800F627B3 /* ASCollectionNode.mm in Sources */,
E55D86331CA8A14000A0C26F /* ASLayoutable.mm in Sources */,
68FC85EC1CE29C7D00EDD713 /* ASVisibilityProtocols.m in Sources */,
68B8A4E41CBDB958007E4543 /* ASWeakProxy.m in Sources */,
9C70F20A1CDBE949007D6C76 /* ASTableNode.mm in Sources */,
69CB62AE1CB8165900024920 /* _ASDisplayViewAccessiblity.mm in Sources */,
@@ -2209,6 +2243,7 @@
044285101BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm in Sources */,
B35062271B010EFD0018CF92 /* ASRangeController.mm in Sources */,
0442850A1BAA63FE00D16268 /* ASBatchFetching.m in Sources */,
68FC85E61CE29B9400EDD713 /* ASNavigationController.m in Sources */,
34EFC76F1B701CF700AD841F /* ASRatioLayoutSpec.mm in Sources */,
254C6B8B1BF94F8A003EC431 /* ASTextKitShadower.mm in Sources */,
34EFC7661B701CD200AD841F /* ASRelativeSize.mm in Sources */,
@@ -2223,6 +2258,7 @@
9C70F2051CDA4F06007D6C76 /* ASTraitCollection.m in Sources */,
34EFC7781B701D3100AD841F /* ASStackUnpositionedLayout.mm in Sources */,
DE84918E1C8FFF9F003D89E9 /* ASRunLoopQueue.mm in Sources */,
68FC85E51CE29B7E00EDD713 /* ASTabBarController.m in Sources */,
AC026B6C1BD57D6F00BBC17E /* ASChangeSetDataController.m in Sources */,
34EFC7741B701D0A00AD841F /* ASStaticLayoutSpec.mm in Sources */,
92074A6A1CC8BADA00918F75 /* ASControlNode+tvOS.m in Sources */,

View File

@@ -0,0 +1,15 @@
//
// ASNavigationController.h
// Pods
//
// Created by Garrett Moon on 4/27/16.
//
//
#import <UIKit/UIKit.h>
#import "ASVisibilityProtocols.h"
@interface ASNavigationController : UINavigationController <ASManagesChildVisibilityDepth>
@end

View File

@@ -0,0 +1,93 @@
//
// ASNavigationController.m
// Pods
//
// Created by Garrett Moon on 4/27/16.
//
//
#import "ASNavigationController.h"
@implementation ASNavigationController
{
BOOL _parentManagesVisibilityDepth;
NSInteger _visibilityDepth;
}
ASVisibilityDidMoveToParentViewController;
ASVisibilityViewWillAppear;
ASVisibilityViewDidDisappearImplementation;
ASVisibilitySetVisibilityDepth;
ASVisibilityDepthImplementation;
- (void)visibilityDepthDidChange
{
for (UIViewController *viewController in self.viewControllers) {
if ([viewController conformsToProtocol:@protocol(ASVisibilityDepth)]) {
[(id <ASVisibilityDepth>)viewController visibilityDepthDidChange];
}
}
}
- (NSInteger)visibilityDepthOfChildViewController:(UIViewController *)childViewController
{
NSUInteger viewControllerIndex = [self.viewControllers indexOfObject:childViewController];
NSAssert(viewControllerIndex != NSNotFound, @"childViewController is not in the navigation stack.");
if (viewControllerIndex == self.viewControllers.count - 1) {
//view controller is at the top, just return our own visibility depth.
return [self visibilityDepth];
} else if (viewControllerIndex == 0) {
//view controller is the root view controller. Can be accessed by holding the back button.
return [self visibilityDepth] + 1;
}
return [self visibilityDepth] + self.viewControllers.count - 1 - viewControllerIndex;
}
#pragma mark - UIKit overrides
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
{
NSArray *viewControllers = [super popToViewController:viewController animated:animated];
[self visibilityDepthDidChange];
return viewControllers;
}
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated
{
NSArray *viewControllers = [super popToRootViewControllerAnimated:animated];
[self visibilityDepthDidChange];
return viewControllers;
}
- (void)setViewControllers:(NSArray *)viewControllers
{
[super setViewControllers:viewControllers];
[self visibilityDepthDidChange];
}
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated
{
[super setViewControllers:viewControllers animated:animated];
[self visibilityDepthDidChange];
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[super pushViewController:viewController animated:animated];
[self visibilityDepthDidChange];
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
UIViewController *viewController = [super popViewControllerAnimated:animated];
[self visibilityDepthDidChange];
return viewController;
}
@end

View File

@@ -0,0 +1,15 @@
//
// ASTabBarController.h
// AsyncDisplayKit
//
// Created by Garrett Moon on 5/10/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "ASVisibilityProtocols.h"
@interface ASTabBarController : UITabBarController <ASManagesChildVisibilityDepth>
@end

View File

@@ -0,0 +1,70 @@
//
// ASTabBarController.m
// AsyncDisplayKit
//
// Created by Garrett Moon on 5/10/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import "ASTabBarController.h"
@implementation ASTabBarController
{
BOOL _parentManagesVisibilityDepth;
NSInteger _visibilityDepth;
}
ASVisibilityDidMoveToParentViewController;
ASVisibilityViewWillAppear;
ASVisibilityViewDidDisappearImplementation;
ASVisibilitySetVisibilityDepth;
ASVisibilityDepthImplementation;
- (void)visibilityDepthDidChange
{
for (UIViewController *viewController in self.viewControllers) {
if ([viewController conformsToProtocol:@protocol(ASVisibilityDepth)]) {
[(id <ASVisibilityDepth>)viewController visibilityDepthDidChange];
}
}
}
- (NSInteger)visibilityDepthOfChildViewController:(UIViewController *)childViewController
{
if (self.selectedViewController == childViewController) {
return [self visibilityDepth];
}
return [self visibilityDepth] + 1;
}
#pragma mark - UIKit overrides
- (void)setViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers
{
[super setViewControllers:viewControllers];
[self visibilityDepthDidChange];
}
- (void)setViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers animated:(BOOL)animated
{
[super setViewControllers:viewControllers animated:animated];
[self visibilityDepthDidChange];
}
- (void)setSelectedIndex:(NSUInteger)selectedIndex
{
[super setSelectedIndex:selectedIndex];
[self visibilityDepthDidChange];
}
- (void)setSelectedViewController:(__kindof UIViewController *)selectedViewController
{
[super setSelectedViewController:selectedViewController];
[self visibilityDepthDidChange];
}
@end

View File

@@ -8,6 +8,7 @@
#import <UIKit/UIKit.h>
#import <AsyncDisplayKit/ASDisplayNode.h>
#import <AsyncDisplayKit/ASVisibilityProtocols.h>
@class ASTraitCollection;
@@ -16,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
typedef ASTraitCollection * _Nonnull (^ASDisplayTraitsForTraitCollectionBlock)(UITraitCollection *traitCollection);
typedef ASTraitCollection * _Nonnull (^ASDisplayTraitsForTraitWindowSizeBlock)(CGSize windowSize);
@interface ASViewController<__covariant DisplayNodeType : ASDisplayNode *> : UIViewController
@interface ASViewController<__covariant DisplayNodeType : ASDisplayNode *> : UIViewController <ASVisibilityDepth>
- (instancetype)initWithNode:(DisplayNodeType)node NS_DESIGNATED_INITIALIZER;

View File

@@ -9,17 +9,18 @@
#import "ASViewController.h"
#import "ASAssert.h"
#import "ASDimension.h"
#import "ASDisplayNodeInternal.h"
#import "ASDisplayNode+FrameworkPrivate.h"
#import "ASDisplayNode+Beta.h"
#import "ASTraitCollection.h"
#import "ASEnvironmentInternal.h"
#import "ASRangeControllerUpdateRangeProtocol+Beta.h"
#define AS_LOG_VISIBILITY_CHANGES 0
@implementation ASViewController
{
BOOL _ensureDisplayed;
BOOL _automaticallyAdjustRangeModeBasedOnViewEvents;
BOOL _parentManagesVisibilityDepth;
NSInteger _visibilityDepth;
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
@@ -45,21 +46,10 @@
_node = node;
_automaticallyAdjustRangeModeBasedOnViewEvents = NO;
return self;
}
- (void)dealloc
{
if (_traitColectionContext != nil) {
// The setter will iterate through the VC's subnodes and replace the traitCollectionContext in their ASEnvironmentTraitCollection with nil.
// Since the VC holds the only strong reference to this context and we are in the process of destroying
// the VC, all the references in the subnodes will be unsafe unless we nil them out. More than likely all the subnodes will be dealloc'ed
// as part of the VC being dealloc'ed, but this is just to make extra sure.
self.traitColectionContext = nil;
}
}
- (void)loadView
{
ASDisplayNodeAssertTrue(!_node.layerBacked);
@@ -95,21 +85,54 @@
[super viewDidLayoutSubviews];
}
ASVisibilityDidMoveToParentViewController;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
_ensureDisplayed = YES;
[_node measureWithSizeRange:[self nodeConstrainedSize]];
[_node recursivelyFetchData];
[self updateCurrentRangeModeWithModeIfPossible:ASLayoutRangeModeFull];
if (_parentManagesVisibilityDepth == NO) {
[self setVisibilityDepth:0];
}
}
- (void)viewDidDisappear:(BOOL)animated
ASVisibilitySetVisibilityDepth;
ASVisibilityViewDidDisappearImplementation;
ASVisibilityDepthImplementation;
- (void)visibilityDepthDidChange
{
[super viewDidDisappear:animated];
[self updateCurrentRangeModeWithModeIfPossible:ASLayoutRangeModeMinimum];
ASLayoutRangeMode rangeMode = ASLayoutRangeModeForVisibilityDepth(self.visibilityDepth);
#if AS_LOG_VISIBILITY_CHANGES
NSString *rangeModeString;
switch (rangeMode) {
case ASLayoutRangeModeMinimum:
rangeModeString = @"Minimum";
break;
case ASLayoutRangeModeFull:
rangeModeString = @"Full";
break;
case ASLayoutRangeModeVisibleOnly:
rangeModeString = @"Visible Only";
break;
case ASLayoutRangeModeLowMemory:
rangeModeString = @"Low Memory";
break;
default:
break;
}
NSLog(@"Updating visibility of:%@ to: %@ (visibility depth: %d)", self, rangeModeString, self.visibilityDepth);
#endif
[self updateCurrentRangeModeWithModeIfPossible:rangeMode];
}
#pragma mark - Automatic range mode
@@ -127,7 +150,9 @@
- (void)updateCurrentRangeModeWithModeIfPossible:(ASLayoutRangeMode)rangeMode
{
if (!_automaticallyAdjustRangeModeBasedOnViewEvents) { return; }
if (![_node conformsToProtocol:@protocol(ASRangeControllerUpdateRangeProtocol)]) { return; }
if (![_node conformsToProtocol:@protocol(ASRangeControllerUpdateRangeProtocol)]) {
return;
}
id<ASRangeControllerUpdateRangeProtocol> updateRangeNode = (id<ASRangeControllerUpdateRangeProtocol>)_node;
[updateRangeNode updateCurrentRangeWithMode:rangeMode];
@@ -146,80 +171,4 @@
return _node.interfaceState;
}
#pragma mark - ASEnvironmentTraitCollection
- (void)setTraitColectionContext:(id)traitColectionContext
{
if (_traitColectionContext != traitColectionContext) {
// propagate first so that nodes aren't hanging around with a dealloc'ed pointer
ASEnvironmentTraitCollectionUpdateDisplayContext(self.node, traitColectionContext);
_traitColectionContext = traitColectionContext;
}
}
- (ASEnvironmentTraitCollection)displayTraitsForTraitCollection:(UITraitCollection *)traitCollection
{
if (self.overrideDisplayTraitsWithTraitCollection) {
ASTraitCollection *asyncTraitCollection = self.overrideDisplayTraitsWithTraitCollection(traitCollection);
self.traitColectionContext = asyncTraitCollection.traitCollectionContext;
return [asyncTraitCollection environmentTraitCollection];
}
ASEnvironmentTraitCollection asyncTraitCollection = ASEnvironmentTraitCollectionFromUITraitCollection(traitCollection);
asyncTraitCollection.displayContext = self.traitColectionContext;
return asyncTraitCollection;
}
- (ASEnvironmentTraitCollection)displayTraitsForWindowSize:(CGSize)windowSize
{
if (self.overrideDisplayTraitsWithWindowSize) {
ASTraitCollection *traitCollection = self.overrideDisplayTraitsWithWindowSize(windowSize);
self.traitColectionContext = traitCollection.traitCollectionContext;
return [traitCollection environmentTraitCollection];
}
return self.node.environmentTraitCollection;
}
- (void)progagateNewDisplayTraits:(ASEnvironmentTraitCollection)traitCollection
{
ASEnvironmentState environmentState = self.node.environmentState;
ASEnvironmentTraitCollection oldTraitCollection = environmentState.traitCollection;
if (ASEnvironmentTraitCollectionIsEqualToASEnvironmentTraitCollection(traitCollection, oldTraitCollection) == NO) {
environmentState.traitCollection = traitCollection;
self.node.environmentState = environmentState;
[self.node setNeedsLayout];
NSArray<id<ASEnvironment>> *children = [self.node children];
for (id<ASEnvironment> child in children) {
ASEnvironmentStatePropagateDown(child, environmentState.traitCollection);
}
}
}
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
{
[super traitCollectionDidChange:previousTraitCollection];
ASEnvironmentTraitCollection traitCollection = [self displayTraitsForTraitCollection:self.traitCollection];
[self progagateNewDisplayTraits:traitCollection];
}
- (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];
ASEnvironmentTraitCollection traitCollection = [self displayTraitsForTraitCollection:newCollection];
[self progagateNewDisplayTraits:traitCollection];
}
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
ASEnvironmentTraitCollection traitCollection = [self displayTraitsForWindowSize:size];
[self progagateNewDisplayTraits:traitCollection];
}
@end

View File

@@ -0,0 +1,103 @@
//
// ASVisibilityProtocols.h
// Pods
//
// Created by Garrett Moon on 4/27/16.
//
//
#import "ASLayoutRangeType.h"
#import "ASBaseDefines.h"
@class UIViewController;
ASDISPLAYNODE_EXTERN_C_BEGIN
extern ASLayoutRangeMode ASLayoutRangeModeForVisibilityDepth(NSUInteger visibilityDepth);
ASDISPLAYNODE_EXTERN_C_END
@protocol ASVisibilityDepth <NSObject>
/**
* @abstract Represents the number of user actions necessary to reach the view controller. An increased visibility
* depth indicates a higher number of user interactions for the view controller to be visible again. For example,
* an onscreen navigation controller's top view controller should have a visibility depth of 0. The view controller
* one from the top should have a visibility deptch of 1 as should the root view controller in the stack (because
* the user can hold the back button to pop to the root view controller).
*
* Visibility depth is used to automatically adjust ranges on range controllers (and thus free up memory) and can
* be used to reduce memory usage of other items as well.
*/
- (NSInteger)visibilityDepth;
- (void)visibilityDepthDidChange;
@end
/**
* @abstract Container view controllers should adopt this protocol to indicate that they will manage their child's
* visibilityDepth. For example, ASNavigationController adopts this protocol and manages its childrens visibility
* depth.
*
* If you adopt this protocol, you *must* also emit visibilityDepthDidChange messages to child view controllers.
*
* @param childViewController Expected to return the visibility depth of the child view controller.
*/
@protocol ASManagesChildVisibilityDepth <ASVisibilityDepth>
- (NSInteger)visibilityDepthOfChildViewController:(UIViewController *)childViewController;
@end
#define ASVisibilitySetVisibilityDepth \
- (void)setVisibilityDepth:(NSUInteger)visibilityDepth \
{ \
if (_visibilityDepth == visibilityDepth) { \
return; \
} \
_visibilityDepth = visibilityDepth; \
[self visibilityDepthDidChange]; \
}
#define ASVisibilityDepthImplementation \
- (NSInteger)visibilityDepth \
{ \
if (self.parentViewController && _parentManagesVisibilityDepth == NO) { \
_parentManagesVisibilityDepth = [self.parentViewController conformsToProtocol:@protocol(ASManagesChildVisibilityDepth)]; \
} \
\
if (_parentManagesVisibilityDepth) { \
return [(id <ASManagesChildVisibilityDepth>)self.parentViewController visibilityDepthOfChildViewController:self]; \
} \
return _visibilityDepth; \
}
#define ASVisibilityViewDidDisappearImplementation \
- (void)viewDidDisappear:(BOOL)animated \
{ \
[super viewDidDisappear:animated]; \
\
if (_parentManagesVisibilityDepth == NO) { \
[self setVisibilityDepth:1]; \
} \
}
#define ASVisibilityViewWillAppear \
- (void)viewWillAppear:(BOOL)animated \
{ \
[super viewWillAppear:animated]; \
\
if (_parentManagesVisibilityDepth == NO) { \
[self setVisibilityDepth:0]; \
} \
}
#define ASVisibilityDidMoveToParentViewController \
- (void)didMoveToParentViewController:(UIViewController *)parent \
{ \
[super didMoveToParentViewController:parent]; \
[self visibilityDepthDidChange]; \
}

View File

@@ -0,0 +1,23 @@
//
// ASVisibilityProtocols.m
// Pods
//
// Created by Garrett Moon on 4/28/16.
//
//
#import <Foundation/Foundation.h>
#import "ASVisibilityProtocols.h"
ASLayoutRangeMode ASLayoutRangeModeForVisibilityDepth(NSUInteger visibilityDepth)
{
if (visibilityDepth == 0) {
return ASLayoutRangeModeFull;
} else if (visibilityDepth == 1) {
return ASLayoutRangeModeMinimum;
} else if (visibilityDepth == 2) {
return ASLayoutRangeModeVisibleOnly;
}
return ASLayoutRangeModeLowMemory;
}

View File

@@ -34,6 +34,8 @@
#import <AsyncDisplayKit/ASPagerNode.h>
#import <AsyncDisplayKit/ASViewController.h>
#import <AsyncDisplayKit/ASNavigationController.h>
#import <AsyncDisplayKit/ASTabBarController.h>
#import <AsyncDisplayKit/ASRangeControllerUpdateRangeProtocol+Beta.h>
#import <AsyncDisplayKit/ASChangeSetDataController.h>
@@ -78,6 +80,7 @@
#import <AsyncDisplayKit/ASRunLoopQueue.h>
#import <AsyncDisplayKit/ASTextKitComponents.h>
#import <AsyncDisplayKit/ASTraitCollection.h>
#import <AsyncDisplayKit/ASVisibilityProtocols.h>
#import <AsyncDisplayKit/AsyncDisplayKit+Debug.h>