Cleaning up manual display per @secretiverhyme

This commit is contained in:
Ryan Nystrom
2014-12-02 15:22:07 -08:00
parent 8b0dbf7288
commit 531be46dfd
31 changed files with 29 additions and 1215 deletions

View File

@@ -295,12 +295,18 @@
@property (nonatomic, assign) BOOL shouldRasterizeDescendants;
/**
* @abstract Calls -setNeedsDisplay and -displayIfNeeded on the node's backing store and recursively calls -display on
* all subnodes forcing the entire node hierarchy to be displayed. This method must be called on the main thread but
* there are plans to allow this on any thread.
* @abstract Calls -setNeedsDisplay and -displayIfNeeded on the node's backing store.
*
* @note This method must be called on the main thread but there are plans to allow this on any thread.
*/
- (void)display;
/**
* @abstract Call -display on the node and recursively on all subnodes, forcing the entire node hierarchy to be
* displayed.
*/
- (void)recursivelyDisplay;
/**
* @abstract Display the node's view/layer immediately on the current thread, bypassing the background thread rendering.
*/

View File

@@ -440,13 +440,10 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
- (void)display
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert(self.nodeLoaded, @"backing store must be loaded before calling -display");
// rendering a backing store requires a node be laid out
[self layout];
for (ASDisplayNode *node in self.subnodes) {
[node display];
}
[self __layout];
CALayer *layer = [self isLayerBacked] ? self.layer : self.view.layer;
@@ -458,6 +455,15 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
[layer displayIfNeeded];
}
- (void)recursivelyDisplay
{
for (ASDisplayNode *node in self.subnodes) {
[node recursivelyDisplay];
}
[self display];
}
- (void)displayImmediately
{
ASDisplayNodeAssertMainThread();

View File

@@ -175,14 +175,14 @@ static BOOL ASRangeIsValid(NSRange range)
NSInteger index = [self indexForIndexPath:node.asyncdisplaykit_indexPath];
if (NSLocationInRange(index, _workingRange)) {
// move the node's view to the working range area, so its rendering persists
[self moveNodeToWorkingRange:node];
[self addNodeToWorkingRange:node];
} else {
// this node isn't in the working range, remove it from the view hierarchy
[self removeNodeFromWorkingView:node];
[self removeNodeFromWorkingRange:node];
}
}
- (void)removeNodeFromWorkingView:(ASCellNode *)node
- (void)removeNodeFromWorkingRange:(ASCellNode *)node
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert(node, @"invalid argument");
@@ -197,7 +197,7 @@ static BOOL ASRangeIsValid(NSRange range)
[_workingIndexPaths removeObject:node.asyncdisplaykit_indexPath];
}
- (void)moveNodeToWorkingRange:(ASCellNode *)node
- (void)addNodeToWorkingRange:(ASCellNode *)node
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert(node, @"invalid argument");
@@ -205,13 +205,15 @@ static BOOL ASRangeIsValid(NSRange range)
// if node is in the working range it should not actively be in view
[node.view removeFromSuperview];
[node recursivelyDisplay];
[_workingIndexPaths addObject:node.asyncdisplaykit_indexPath];
}
- (void)moveNode:(ASCellNode *)node toView:(UIView *)view
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert(node && view, @"invalid argument, did you mean -removeNodeFromWorkingView:?");
ASDisplayNodeAssert(node && view, @"invalid argument, did you mean -removeNodeFromWorkingRange:?");
// use an explicit transaction to force CoreAnimation to display nodes in the order they are added.
[CATransaction begin];
@@ -490,7 +492,7 @@ static NSRange ASCalculateWorkingRange(ASRangeTuningParameters params, ASScrollD
for (NSIndexPath *indexPath in removedIndexPaths) {
ASCellNode *node = [self sizedNodeForIndexPath:indexPath];
ASDisplayNodeAssert(node, @"an unsized node should never have entered the working range");
[self removeNodeFromWorkingView:node];
[self removeNodeFromWorkingRange:node];
}
// add nodes that have entered the working range (i.e., those that are in the new working range but not the old one)
@@ -499,7 +501,7 @@ static NSRange ASCalculateWorkingRange(ASRangeTuningParameters params, ASScrollD
// if a node in the working range is still sizing, the sizing logic will add it to the working range for us later
ASCellNode *node = [self sizedNodeForIndexPath:indexPath];
if (node) {
[self moveNodeToWorkingRange:node];
[self addNodeToWorkingRange:node];
} else {
ASDisplayNodeAssert(_sizedNodeCount != _totalNodeCount, @"logic error");
}
@@ -563,8 +565,6 @@ static NSRange ASCalculateWorkingRange(ASRangeTuningParameters params, ASScrollD
for (NSIndexPath *indexPath in indexPaths) {
ASCellNode *node = _nodes[indexPath];
_nodeSizes[[self indexForIndexPath:indexPath]] = [NSValue valueWithCGSize:node.calculatedSize];
[node display];
}
ASDisplayNodeAssert(_nodeSizes.count == _sizedNodeCount, @"logic error");

View File

@@ -1,3 +0,0 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
pod 'AsyncDisplayKit', :path => '../..'

View File

@@ -1,377 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
2930E8401A1FCA890032D7B3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2930E83F1A1FCA890032D7B3 /* main.m */; };
2930E8431A1FCA890032D7B3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2930E8421A1FCA890032D7B3 /* AppDelegate.m */; };
2930E8451A1FCA890032D7B3 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2930E8441A1FCA890032D7B3 /* Images.xcassets */; };
2930E8481A1FCA890032D7B3 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2930E8461A1FCA890032D7B3 /* LaunchScreen.xib */; };
2930E85F1A1FCABC0032D7B3 /* ExpensiveController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2930E85E1A1FCABC0032D7B3 /* ExpensiveController.m */; };
2930E8621A1FF18A0032D7B3 /* PostNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 2930E8611A1FF18A0032D7B3 /* PostNode.m */; };
2930E8651A1FF58A0032D7B3 /* ShareNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 2930E8641A1FF58A0032D7B3 /* ShareNode.m */; };
2983606D1A200AE50022B4F8 /* PlaceholderTextNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 2983606C1A200AE50022B4F8 /* PlaceholderTextNode.m */; };
29CF6DDF1A250F960031DF86 /* CheapController.m in Sources */ = {isa = PBXBuildFile; fileRef = 29CF6DDE1A250F960031DF86 /* CheapController.m */; };
7A7B2A305C39C4CA59331E10 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DABEBB92D527C244C86ADF06 /* libPods.a */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
2930E83A1A1FCA890032D7B3 /* Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sample.app; sourceTree = BUILT_PRODUCTS_DIR; };
2930E83E1A1FCA890032D7B3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
2930E83F1A1FCA890032D7B3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
2930E8411A1FCA890032D7B3 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
2930E8421A1FCA890032D7B3 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
2930E8441A1FCA890032D7B3 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
2930E8471A1FCA890032D7B3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
2930E85D1A1FCABC0032D7B3 /* ExpensiveController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpensiveController.h; sourceTree = "<group>"; };
2930E85E1A1FCABC0032D7B3 /* ExpensiveController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExpensiveController.m; sourceTree = "<group>"; };
2930E8601A1FF18A0032D7B3 /* PostNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PostNode.h; sourceTree = "<group>"; };
2930E8611A1FF18A0032D7B3 /* PostNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PostNode.m; sourceTree = "<group>"; };
2930E8631A1FF58A0032D7B3 /* ShareNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareNode.h; sourceTree = "<group>"; };
2930E8641A1FF58A0032D7B3 /* ShareNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShareNode.m; sourceTree = "<group>"; };
2983606B1A200AE50022B4F8 /* PlaceholderTextNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlaceholderTextNode.h; sourceTree = "<group>"; };
2983606C1A200AE50022B4F8 /* PlaceholderTextNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlaceholderTextNode.m; sourceTree = "<group>"; };
29CF6DDD1A250F960031DF86 /* CheapController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CheapController.h; sourceTree = "<group>"; };
29CF6DDE1A250F960031DF86 /* CheapController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CheapController.m; sourceTree = "<group>"; };
AC624CB0EACE6790C185F790 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
BFA8076C256CAC9E6E153731 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
DABEBB92D527C244C86ADF06 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
2930E8371A1FCA890032D7B3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7A7B2A305C39C4CA59331E10 /* libPods.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
2930E8311A1FCA890032D7B3 = {
isa = PBXGroup;
children = (
2930E83C1A1FCA890032D7B3 /* Sample */,
2930E83B1A1FCA890032D7B3 /* Products */,
E4382CEF3F9728AD310690EE /* Pods */,
3AD89B2B22B71B86CDE10916 /* Frameworks */,
);
sourceTree = "<group>";
};
2930E83B1A1FCA890032D7B3 /* Products */ = {
isa = PBXGroup;
children = (
2930E83A1A1FCA890032D7B3 /* Sample.app */,
);
name = Products;
sourceTree = "<group>";
};
2930E83C1A1FCA890032D7B3 /* Sample */ = {
isa = PBXGroup;
children = (
2930E8411A1FCA890032D7B3 /* AppDelegate.h */,
2930E8421A1FCA890032D7B3 /* AppDelegate.m */,
2930E8441A1FCA890032D7B3 /* Images.xcassets */,
2930E8461A1FCA890032D7B3 /* LaunchScreen.xib */,
2930E83D1A1FCA890032D7B3 /* Supporting Files */,
2930E85D1A1FCABC0032D7B3 /* ExpensiveController.h */,
2930E85E1A1FCABC0032D7B3 /* ExpensiveController.m */,
29CF6DDD1A250F960031DF86 /* CheapController.h */,
29CF6DDE1A250F960031DF86 /* CheapController.m */,
2930E8601A1FF18A0032D7B3 /* PostNode.h */,
2930E8611A1FF18A0032D7B3 /* PostNode.m */,
2983606B1A200AE50022B4F8 /* PlaceholderTextNode.h */,
2983606C1A200AE50022B4F8 /* PlaceholderTextNode.m */,
2930E8631A1FF58A0032D7B3 /* ShareNode.h */,
2930E8641A1FF58A0032D7B3 /* ShareNode.m */,
);
path = Sample;
sourceTree = "<group>";
};
2930E83D1A1FCA890032D7B3 /* Supporting Files */ = {
isa = PBXGroup;
children = (
2930E83E1A1FCA890032D7B3 /* Info.plist */,
2930E83F1A1FCA890032D7B3 /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
3AD89B2B22B71B86CDE10916 /* Frameworks */ = {
isa = PBXGroup;
children = (
DABEBB92D527C244C86ADF06 /* libPods.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
E4382CEF3F9728AD310690EE /* Pods */ = {
isa = PBXGroup;
children = (
BFA8076C256CAC9E6E153731 /* Pods.debug.xcconfig */,
AC624CB0EACE6790C185F790 /* Pods.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
2930E8391A1FCA890032D7B3 /* Sample */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2930E8571A1FCA890032D7B3 /* Build configuration list for PBXNativeTarget "Sample" */;
buildPhases = (
21550E146D80CC7748448A11 /* Check Pods Manifest.lock */,
2930E8361A1FCA890032D7B3 /* Sources */,
2930E8371A1FCA890032D7B3 /* Frameworks */,
2930E8381A1FCA890032D7B3 /* Resources */,
15832E3E36BB198D0274923F /* Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = Sample;
productName = Sample;
productReference = 2930E83A1A1FCA890032D7B3 /* Sample.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
2930E8321A1FCA890032D7B3 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = "Ryan Nystrom";
TargetAttributes = {
2930E8391A1FCA890032D7B3 = {
CreatedOnToolsVersion = 6.1;
};
};
};
buildConfigurationList = 2930E8351A1FCA890032D7B3 /* Build configuration list for PBXProject "Sample" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 2930E8311A1FCA890032D7B3;
productRefGroup = 2930E83B1A1FCA890032D7B3 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
2930E8391A1FCA890032D7B3 /* Sample */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
2930E8381A1FCA890032D7B3 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2930E8481A1FCA890032D7B3 /* LaunchScreen.xib in Resources */,
2930E8451A1FCA890032D7B3 /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
15832E3E36BB198D0274923F /* Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
showEnvVarsInLog = 0;
};
21550E146D80CC7748448A11 /* Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
2930E8361A1FCA890032D7B3 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2930E85F1A1FCABC0032D7B3 /* ExpensiveController.m in Sources */,
2930E8621A1FF18A0032D7B3 /* PostNode.m in Sources */,
29CF6DDF1A250F960031DF86 /* CheapController.m in Sources */,
2983606D1A200AE50022B4F8 /* PlaceholderTextNode.m in Sources */,
2930E8651A1FF58A0032D7B3 /* ShareNode.m in Sources */,
2930E8431A1FCA890032D7B3 /* AppDelegate.m in Sources */,
2930E8401A1FCA890032D7B3 /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
2930E8461A1FCA890032D7B3 /* LaunchScreen.xib */ = {
isa = PBXVariantGroup;
children = (
2930E8471A1FCA890032D7B3 /* Base */,
);
name = LaunchScreen.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
2930E8551A1FCA890032D7B3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
2930E8561A1FCA890032D7B3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
2930E8581A1FCA890032D7B3 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = BFA8076C256CAC9E6E153731 /* Pods.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = Sample/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 7.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
2930E8591A1FCA890032D7B3 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = AC624CB0EACE6790C185F790 /* Pods.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = Sample/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 7.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
2930E8351A1FCA890032D7B3 /* Build configuration list for PBXProject "Sample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2930E8551A1FCA890032D7B3 /* Debug */,
2930E8561A1FCA890032D7B3 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2930E8571A1FCA890032D7B3 /* Build configuration list for PBXNativeTarget "Sample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2930E8581A1FCA890032D7B3 /* Debug */,
2930E8591A1FCA890032D7B3 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 2930E8321A1FCA890032D7B3 /* Project object */;
}

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Sample.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Sample.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,20 +0,0 @@
/* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

View File

@@ -1,48 +0,0 @@
/* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import "AppDelegate.h"
#import "ExpensiveController.h"
#import "CheapController.h"
#define AS_DEMO_PRELOADING 1
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
CGRect screenBounds = [[UIScreen mainScreen] bounds];
UIWindow *window = [[UIWindow alloc] initWithFrame:screenBounds];
CheapController *cheap = [[CheapController alloc] init];
cheap.tabBarItem.title = @"Cheap";
cheap.tabBarItem.image = [UIImage imageNamed:@"cheap"];
ExpensiveController *expensive = [[ExpensiveController alloc] init];
expensive.tabBarItem.title = @"Expensive";
expensive.tabBarItem.image = [UIImage imageNamed:@"expensive"];
#if AS_DEMO_PRELOADING
[expensive preloadForSize:screenBounds.size];
#endif
UITabBarController *tab = [[UITabBarController alloc] init];
tab.viewControllers = @[cheap, expensive];
window.rootViewController = tab;
[window makeKeyAndVisible];
[self setWindow:window];
return YES;
}
@end

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6250" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Wait Wait, Don't Show Me!" textAlignment="center" lineBreakMode="middleTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumFontSize="18" preferredMaxLayoutWidth="441" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="143" width="441" height="36"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="30"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstAttribute="trailing" secondItem="kId-c2-rCX" secondAttribute="trailing" constant="19" id="VgG-Sf-JFm"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="548" y="455"/>
</view>
</objects>
</document>

View File

@@ -1,16 +0,0 @@
/* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import <UIKit/UIKit.h>
@interface CheapController : UIViewController
@end

View File

@@ -1,46 +0,0 @@
/* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import "CheapController.h"
@interface CheapController ()
{
UILabel *_cheapLabel;
}
@end
@implementation CheapController
- (instancetype)init
{
if (self = [super init]) {
_cheapLabel = [[UILabel alloc] init];
_cheapLabel.text = @"I'm a cheap date.";
[_cheapLabel sizeToFit];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_cheapLabel];
}
- (void)viewDidLayoutSubviews
{
_cheapLabel.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));
}
@end

View File

@@ -1,18 +0,0 @@
/* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import <UIKit/UIKit.h>
@interface ExpensiveController : UIViewController
- (void)preloadForSize:(CGSize)size;
@end

View File

@@ -1,123 +0,0 @@
/* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import "ExpensiveController.h"
#import <AsyncDisplayKit/AsyncDisplayKit.h>
#import "PostNode.h"
static NSUInteger const kNumberOfPosts = 20;
@interface ExpensiveController () <ASTableViewDataSource, ASTableViewDelegate>
{
ASTableView *_tableView;
}
@end
@implementation ExpensiveController
- (instancetype)init
{
if (self = [super init]) {
_tableView = [[ASTableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.asyncDataSource = self;
_tableView.asyncDelegate = self;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view addSubview:_tableView];
if (self.tabBarController) {
UIEdgeInsets insets = _tableView.contentInset;
insets.bottom = CGRectGetHeight(self.tabBarController.tabBar.bounds);
_tableView.contentInset = insets;
_tableView.scrollIndicatorInsets = insets;
}
}
- (void)viewDidLayoutSubviews
{
CGRect bounds = self.view.bounds;
_tableView.frame = bounds;
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
#pragma mark -
#pragma mark Public Actions
- (void)preloadForSize:(CGSize)size
{
// without setting the frame the size is CGRectZero which will likely cause layout asserts to fail
_tableView.frame = (CGRect){ CGPointZero, size };
[_tableView reloadData];
}
#pragma mark -
#pragma mark Getters
+ (NSString *)randomPost
{
static NSArray *posts = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
posts = @[
@"Nulla vitae elit libero, a **pharetra augue**. Curabitur blandit tempus porttitor. Donec sed odio dui. Donec id elit non mi porta gravida at eget metus. Donec ullamcorper nulla non metus auctor fringilla. Cras mattis consectetur purus sit amet fermentum.",
@"Donec id elit non mi porta gravida at **eget metus**. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. **Donec ullamcorper nulla** non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Donec id elit non mi porta gravida at eget metus.\nFusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Donec ullamcorper nulla non metus auctor fringilla.",
@"Nullam id dolor id nibh ultricies vehicula ut id **elit**. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Praesent commodo cursus magna, vel scelerisque nisl **consectetur et**.\nNullam id dolor id nibh ultricies vehicula ut id elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
@"Sed posuere consectetur est at lobortis. Etiam porta sem malesuada magna mollis euismod. Curabitur blandit tempus **porttitor**. Nullam id dolor id nibh ultricies vehicula ut id elit.\nCurabitur blandit tempus porttitor.",
@"Aenean lacinia bibendum nulla sed consectetur. Morbi leo risus, porta ac consectetur ac, **vestibulum at eros**. Vestibulum id ligula porta felis euismod semper. Nullam id dolor id nibh ultricies vehicula ut id elit.Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec ullamcorper nulla non metus auctor fringilla.",
@"Nullam quis risus eget urna mollis ornare vel eu leo.\nSed posuere consectetur est at lobortis. Fusce dapibus, tellus ac cursus **commodo**, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nulla vitae **elit libero**, a pharetra augue.",
];
});
NSUInteger randomIndex = arc4random() % posts.count;
return posts[randomIndex];
}
#pragma mark -
#pragma mark ASTableViewDataSource
- (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:-indexPath.row * 60 * 60 * 24];
NSString *text = [self.class randomPost];
PostNode *node = [[PostNode alloc] initWithDate:date text:text];
return node;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return kNumberOfPosts;
}
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
@end

View File

@@ -1,68 +0,0 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,23 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "cheap.png"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "cheap@2x.png"
},
{
"idiom" : "universal",
"scale" : "3x",
"filename" : "cheap@3x.png"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,23 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x",
"filename" : "expensive.png"
},
{
"idiom" : "universal",
"scale" : "2x",
"filename" : "expensive@2x.png"
},
{
"idiom" : "universal",
"scale" : "3x",
"filename" : "expensive@3x.png"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>com.whoisryannystrom.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@@ -1,16 +0,0 @@
/* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import <AsyncDisplayKit/AsyncDisplayKit.h>
@interface PlaceholderTextNode : ASTextNode
@end

View File

@@ -1,58 +0,0 @@
/* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import "PlaceholderTextNode.h"
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
@interface PlaceholderTextNode ()
{
CALayer *_placeholderLayer;
BOOL _displayFinished;
}
@end
@implementation PlaceholderTextNode
- (instancetype)init
{
if (!(self = [super init]))
return nil;
_placeholderLayer = [CALayer layer];
_placeholderLayer.backgroundColor = [UIColor colorWithWhite:0.7f alpha:0.5f].CGColor;
return self;
}
- (void)willEnterHierarchy
{
[super willEnterHierarchy];
if (!_displayFinished) {
[self.layer addSublayer:_placeholderLayer];
}
}
- (void)layout
{
_placeholderLayer.frame = (CGRect){ CGPointZero, self.calculatedSize };
}
- (void)displayDidFinish
{
_displayFinished = YES;
[_placeholderLayer removeFromSuperlayer];
[super displayDidFinish];
}
@end

View File

@@ -1,18 +0,0 @@
/* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import <AsyncDisplayKit/AsyncDisplayKit.h>
@interface PostNode : ASCellNode
- (instancetype)initWithDate:(NSDate *)date text:(NSString *)text;
@end

View File

@@ -1,138 +0,0 @@
/* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import "PostNode.h"
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
#import "ShareNode.h"
#import "PlaceholderTextNode.h"
static CGFloat const kTopPadding = 15.f;
static CGFloat const kOuterPadding = 10.f;
static CGFloat const kTextPadding = 10.f;
@interface PostNode ()
{
PlaceholderTextNode *_textNode;
PlaceholderTextNode *_dateNode;
ShareNode *_shareNode;
ASDisplayNode *_divider;
}
@end
@implementation PostNode
+ (NSDateFormatter *)dateFormatter
{
NSString * const formatterKey = @"dateFormatter";
NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
NSDateFormatter *dateFormatter = threadDictionary[formatterKey];
if (!dateFormatter) {
dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [NSLocale currentLocale];
dateFormatter.dateStyle = NSDateFormatterLongStyle;
dateFormatter.timeStyle = NSDateFormatterNoStyle;
threadDictionary[formatterKey] = dateFormatter;
}
return dateFormatter;
}
- (instancetype)initWithDate:(NSDate *)date text:(NSString *)text
{
if (!(self = [super init]))
return nil;
NSString *dateString = [[self.class dateFormatter] stringFromDate:date];
_dateNode = [[PlaceholderTextNode alloc] init];
_dateNode.attributedString = [[NSAttributedString alloc] initWithString:dateString attributes:[self dateTextStyle]];
[self addSubnode:_dateNode];
_textNode = [[PlaceholderTextNode alloc] init];
_textNode.attributedString = [self styledTextString:text];
[self addSubnode:_textNode];
_divider = [[ASDisplayNode alloc] init];
_divider.backgroundColor = [UIColor lightGrayColor];
[self addSubnode:_divider];
_shareNode = [[ShareNode alloc] init];
[self addSubnode:_shareNode];
return self;
}
// purposefully expensive for demo
- (NSAttributedString *)styledTextString:(NSString *)originalText
{
NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:originalText attributes:[self textStyle]];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\*\\*[\\w\\s]+\\*\\*" options:kNilOptions error:nil];
[regex enumerateMatchesInString:originalText options:kNilOptions range:NSMakeRange(0,originalText.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSRange range = [result rangeAtIndex:0];
[attributedText addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"HelveticaNeue-Bold" size:16.0f] range:range];
}];
return attributedText;
}
- (NSDictionary *)dateTextStyle
{
UIFont *font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:12.0f];
UIColor *color = [UIColor colorWithWhite:0.7f alpha:1.f];
return @{ NSFontAttributeName: font,
NSForegroundColorAttributeName: color };
}
- (NSDictionary *)textStyle
{
UIFont *font = [UIFont fontWithName:@"HelveticaNeue" size:16.0f];
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
style.paragraphSpacing = 0.5 * font.lineHeight;
style.hyphenationFactor = 1.0;
return @{ NSFontAttributeName: font,
NSParagraphStyleAttributeName: style };
}
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
{
CGSize dateSize = [_dateNode measure:CGSizeMake((constrainedSize.width - 2 * kOuterPadding) / 2.f, constrainedSize.height)];
CGSize textSize = [_textNode measure:CGSizeMake(constrainedSize.width - 2 * kOuterPadding, constrainedSize.height)];
[_shareNode measure:constrainedSize];
return CGSizeMake(constrainedSize.width, dateSize.height + textSize.height + 2 * kTopPadding + kTextPadding);
}
- (void)layout
{
CGFloat pixelHeight = 1.0f / [[UIScreen mainScreen] scale];
_divider.frame = CGRectMake(0.0f, 0.0f, self.calculatedSize.width, pixelHeight);
CGSize dateSize = _dateNode.calculatedSize;
_dateNode.frame = CGRectMake(kOuterPadding, kTopPadding, dateSize.width, dateSize.height);
CGSize textSize = _textNode.calculatedSize;
_textNode.frame = CGRectMake(kOuterPadding, CGRectGetMaxY(_dateNode.frame) + kTextPadding, textSize.width, textSize.height);
CGSize iconSize = _shareNode.calculatedSize;
_shareNode.frame = CGRectMake(self.calculatedSize.width - kOuterPadding - iconSize.width, kTopPadding, iconSize.width, iconSize.width);
}
@end

View File

@@ -1,16 +0,0 @@
/* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import <AsyncDisplayKit/AsyncDisplayKit.h>
@interface ShareNode : ASControlNode
@end

View File

@@ -1,72 +0,0 @@
/* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import "ShareNode.h"
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
static NSUInteger const kRingCount = 3;
static CGFloat const kRingStrokeWidth = 1.f;
static CGSize const kIconSize = (CGSize){ 40.f, 10.f };
@interface ShareNode ()
{
ASImageNode *_iconNode;
}
@end
@implementation ShareNode
+ (UIImage *)drawIcon
{
UIGraphicsBeginImageContextWithOptions(kIconSize, NO, [UIScreen mainScreen].scale);
[[UIColor colorWithRed:0.f green:122/255.f blue:1.f alpha:1.f] setStroke];
for (NSUInteger i = 0; i < kRingCount; i++) {
CGFloat x = i * kIconSize.width / kRingCount;
CGRect frame = CGRectMake(x, 0.f, kIconSize.height, kIconSize.height);
CGRect strokeFrame = CGRectInset(frame, kRingStrokeWidth, kRingStrokeWidth);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:strokeFrame cornerRadius:kIconSize.height / 2.f];
[path setLineWidth:kRingStrokeWidth];
[path stroke];
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
- (instancetype)init
{
if (!(self = [super init]))
return nil;
_iconNode = [[ASImageNode alloc] init];
_iconNode.image = [self.class drawIcon];
[self addSubnode:_iconNode];
return self;
}
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
{
return kIconSize;
}
- (void)layout
{
_iconNode.frame = (CGRect){ CGPointZero, self.calculatedSize };
}
@end

View File

@@ -1,19 +0,0 @@
/* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}