mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-01 10:23:15 +00:00
Merge pull request #143 from facebook/placeholder-api
Node placeholder API
This commit is contained in:
commit
bf01b07443
@ -185,6 +185,24 @@
|
||||
*/
|
||||
- (void)displayDidFinish ASDISPLAYNODE_REQUIRES_SUPER;
|
||||
|
||||
/**
|
||||
* @abstract Indicates that the receiver is about to display its subnodes. This method is not called if there are no
|
||||
* subnodes present.
|
||||
*
|
||||
* @discussion Subclasses may override this method to be notified when subnode display (asynchronous or synchronous) is
|
||||
* about to begin.
|
||||
*/
|
||||
- (void)subnodeDisplayWillStart:(ASDisplayNode *)subnode ASDISPLAYNODE_REQUIRES_SUPER;
|
||||
|
||||
/**
|
||||
* @abstract Indicates that the receiver is finished displaying its subnodes. This method is not called if there are
|
||||
* no subnodes present.
|
||||
*
|
||||
* @discussion Subclasses may override this method to be notified when subnode display (asynchronous or synchronous) is
|
||||
* about to begin.
|
||||
*/
|
||||
- (void)subnodeDisplayDidFinish:(ASDisplayNode *)subnode ASDISPLAYNODE_REQUIRES_SUPER;
|
||||
|
||||
|
||||
/**
|
||||
* @abstract Marks the receiver's bounds as needing to be redrawn, with a scale value.
|
||||
@ -303,6 +321,26 @@
|
||||
- (void)reclaimMemory ASDISPLAYNODE_REQUIRES_SUPER;
|
||||
|
||||
|
||||
/** @name Placeholders */
|
||||
|
||||
/**
|
||||
* @abstract Optionally provide an image to serve as the placeholder for the backing store while the contents are being
|
||||
* displayed.
|
||||
*
|
||||
* @discussion
|
||||
* Subclasses may override this method and return an image to use as the placeholder. Take caution as there may be a
|
||||
* time and place where this method is called on a background thread. Note that -[UIImage imageNamed:] is not thread
|
||||
* safe when using image assets.
|
||||
*
|
||||
* To retrieve the CGSize to do any image drawing, use the node's calculatedSize property.
|
||||
*
|
||||
* Defaults to nil.
|
||||
*
|
||||
* @note Called on the display queue and/or main queue (MUST BE THREAD SAFE)
|
||||
*/
|
||||
- (UIImage *)placeholderImage;
|
||||
|
||||
|
||||
/** @name Description */
|
||||
|
||||
|
||||
|
@ -330,6 +330,14 @@
|
||||
|
||||
- (void)recursivelyReclaimMemory;
|
||||
|
||||
/**
|
||||
* @abstract Toggle displaying a placeholder over the node that covers content until the node and all subnodes are
|
||||
* displayed.
|
||||
*
|
||||
* @discussion Defaults to NO.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL placeholderEnabled;
|
||||
|
||||
|
||||
/** @name Hit Testing */
|
||||
|
||||
|
@ -184,6 +184,8 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
_replaceAsyncSentinel = nil;
|
||||
|
||||
_displaySentinel = nil;
|
||||
|
||||
_pendingDisplayNodes = nil;
|
||||
}
|
||||
|
||||
#pragma mark - UIResponder overrides
|
||||
@ -270,6 +272,10 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
TIME_SCOPED(_debugTimeForDidLoad);
|
||||
[self didLoad];
|
||||
}
|
||||
|
||||
if (self.placeholderEnabled) {
|
||||
[self _setupPlaceholderLayer];
|
||||
}
|
||||
}
|
||||
|
||||
- (UIView *)view
|
||||
@ -349,6 +355,7 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
- (CGSize)measure:(CGSize)constrainedSize
|
||||
{
|
||||
ASDisplayNodeAssertThreadAffinity(self);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (![self __shouldSize])
|
||||
return CGSizeZero;
|
||||
@ -365,6 +372,18 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
|
||||
ASDisplayNodeAssertTrue(_size.width >= 0.0);
|
||||
ASDisplayNodeAssertTrue(_size.height >= 0.0);
|
||||
|
||||
// we generate placeholders at measure: time so that a node is guaranteed to have a placeholder ready to go
|
||||
if (self.placeholderEnabled && [self displaysAsynchronously]) {
|
||||
if (!_placeholderImage) {
|
||||
_placeholderImage = [self placeholderImage];
|
||||
}
|
||||
|
||||
if (_placeholderLayer) {
|
||||
_placeholderLayer.contents = (id)_placeholderImage.CGImage;
|
||||
}
|
||||
}
|
||||
|
||||
return _size;
|
||||
}
|
||||
|
||||
@ -448,8 +467,10 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (CGRectEqualToRect(_layer.bounds, CGRectZero))
|
||||
if (CGRectEqualToRect(_layer.bounds, CGRectZero)) {
|
||||
return; // Performing layout on a zero-bounds view often results in frame calculations with negative sizes after applying margins, which will cause measure: on subnodes to assert.
|
||||
}
|
||||
_placeholderLayer.frame = _layer.bounds;
|
||||
[self layout];
|
||||
[self layoutDidFinish];
|
||||
}
|
||||
@ -1091,6 +1112,60 @@ static NSInteger incrementIfFound(NSInteger i) {
|
||||
_supernode = supernode;
|
||||
}
|
||||
|
||||
// Track that a node will be displayed as part of the current node hierarchy.
|
||||
// The node sending the message should usually be passed as the parameter, similar to the delegation pattern.
|
||||
- (void)_pendingNodeWillDisplay:(ASDisplayNode *)node
|
||||
{
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
[_pendingDisplayNodes addObject:node];
|
||||
}
|
||||
|
||||
// Notify that a node that was pending display finished
|
||||
// The node sending the message should usually be passed as the parameter, similar to the delegation pattern.
|
||||
- (void)_pendingNodeDidDisplay:(ASDisplayNode *)node
|
||||
{
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
[_pendingDisplayNodes removeObject:node];
|
||||
|
||||
// only trampoline if there is a placeholder and nodes are done displaying
|
||||
if ([self _pendingDisplayNodesHaveFinished] && _placeholderLayer.superlayer) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self _tearDownPlaceholderLayer];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method to check that all nodes that the current node is waiting to display are finished
|
||||
// Use this method to check to remove any placeholder layers
|
||||
- (BOOL)_pendingDisplayNodesHaveFinished
|
||||
{
|
||||
return _pendingDisplayNodes.count == 0;
|
||||
}
|
||||
|
||||
// Helper method to summarize whether or not the node run through the display process
|
||||
- (BOOL)_implementsDisplay
|
||||
{
|
||||
return _flags.implementsDrawRect == YES || _flags.implementsImageDisplay == YES;
|
||||
}
|
||||
|
||||
- (void)_setupPlaceholderLayer
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
_placeholderLayer = [CALayer layer];
|
||||
// do not set to CGFLOAT_MAX in the case that something needs to be overtop the placeholder
|
||||
_placeholderLayer.zPosition = 9999.0;
|
||||
}
|
||||
|
||||
- (void)_tearDownPlaceholderLayer
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
[_placeholderLayer removeFromSuperlayer];
|
||||
}
|
||||
|
||||
#pragma mark - For Subclasses
|
||||
|
||||
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
||||
@ -1111,6 +1186,11 @@ static NSInteger incrementIfFound(NSInteger i) {
|
||||
return _constrainedSize;
|
||||
}
|
||||
|
||||
- (UIImage *)placeholderImage
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)invalidateCalculatedSize
|
||||
{
|
||||
ASDisplayNodeAssertThreadAffinity(self);
|
||||
@ -1142,6 +1222,7 @@ static NSInteger incrementIfFound(NSInteger i) {
|
||||
- (void)reclaimMemory
|
||||
{
|
||||
self.layer.contents = nil;
|
||||
_placeholderLayer.contents = nil;
|
||||
}
|
||||
|
||||
- (void)recursivelyReclaimMemory
|
||||
@ -1159,10 +1240,36 @@ static NSInteger incrementIfFound(NSInteger i) {
|
||||
|
||||
- (void)displayWillStart
|
||||
{
|
||||
// in case current node takes longer to display than it's subnodes, treat it as a dependent node
|
||||
[self _pendingNodeWillDisplay:self];
|
||||
|
||||
[_supernode subnodeDisplayWillStart:self];
|
||||
|
||||
if (_placeholderImage && _placeholderLayer) {
|
||||
_placeholderLayer.contents = (id)_placeholderImage.CGImage;
|
||||
[self.layer addSublayer:_placeholderLayer];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)displayDidFinish
|
||||
{
|
||||
[self _pendingNodeDidDisplay:self];
|
||||
|
||||
[_supernode subnodeDisplayDidFinish:self];
|
||||
|
||||
if (_placeholderLayer && [self _pendingDisplayNodesHaveFinished]) {
|
||||
[self _tearDownPlaceholderLayer];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)subnodeDisplayWillStart:(ASDisplayNode *)subnode
|
||||
{
|
||||
[self _pendingNodeWillDisplay:subnode];
|
||||
}
|
||||
|
||||
- (void)subnodeDisplayDidFinish:(ASDisplayNode *)subnode
|
||||
{
|
||||
[self _pendingNodeDidDisplay:subnode];
|
||||
}
|
||||
|
||||
- (void)setNeedsDisplayAtScale:(CGFloat)contentsScale
|
||||
@ -1394,6 +1501,14 @@ static void _recursivelySetDisplaySuspended(ASDisplayNode *node, CALayer *layer,
|
||||
_flags.displaySuspended = flag;
|
||||
|
||||
self.asyncLayer.displaySuspended = flag;
|
||||
|
||||
if ([self _implementsDisplay]) {
|
||||
if (flag) {
|
||||
[_supernode subnodeDisplayDidFinish:self];
|
||||
} else {
|
||||
[_supernode subnodeDisplayWillStart:self];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isInHierarchy
|
||||
|
@ -59,6 +59,8 @@ extern id ASDisplayNodeFindFirstSubnode(ASDisplayNode *start, BOOL (^block)(ASDi
|
||||
*/
|
||||
extern id ASDisplayNodeFindFirstSubnodeOfClass(ASDisplayNode *start, Class c);
|
||||
|
||||
extern UIColor *ASDisplayNodeDefaultPlaceholderColor();
|
||||
|
||||
/**
|
||||
Disable willAppear / didAppear / didDisappear notifications for a sub-hierarchy, then re-enable when done. Nested calls are supported.
|
||||
*/
|
||||
|
@ -122,6 +122,15 @@ extern id ASDisplayNodeFindFirstSubnodeOfClass(ASDisplayNode *start, Class c)
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - Placeholders
|
||||
|
||||
UIColor *ASDisplayNodeDefaultPlaceholderColor()
|
||||
{
|
||||
return [UIColor colorWithWhite:0.95 alpha:1.0];
|
||||
}
|
||||
|
||||
#pragma mark - Hierarchy Notifications
|
||||
|
||||
void ASDisplayNodeDisableHierarchyNotifications(ASDisplayNode *node)
|
||||
{
|
||||
[node __incrementVisibilityNotificationsDisabled];
|
||||
|
@ -53,6 +53,11 @@ typedef UIImage *(^asimagenode_modification_block_t)(UIImage *image);
|
||||
*/
|
||||
@property (nonatomic, assign) ASImageNodeTint tint;
|
||||
|
||||
/**
|
||||
@abstract The placeholder color.
|
||||
*/
|
||||
@property (nonatomic, strong) UIColor *placeholderColor;
|
||||
|
||||
/**
|
||||
* @abstract Indicates whether efficient cropping of the receiver is enabled.
|
||||
*
|
||||
|
@ -13,6 +13,7 @@
|
||||
#import <AsyncDisplayKit/ASAssert.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNodeInternal.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
|
||||
|
||||
#import "ASImageNode+CGExtras.h"
|
||||
|
||||
@ -91,6 +92,7 @@
|
||||
_cropEnabled = YES;
|
||||
_cropRect = CGRectMake(0.5, 0.5, 0, 0);
|
||||
_cropDisplayBounds = CGRectNull;
|
||||
_placeholderColor = ASDisplayNodeDefaultPlaceholderColor();
|
||||
|
||||
return self;
|
||||
}
|
||||
@ -139,6 +141,14 @@
|
||||
return _tint;
|
||||
}
|
||||
|
||||
- (void)setPlaceholderColor:(UIColor *)placeholderColor
|
||||
{
|
||||
_placeholderColor = placeholderColor;
|
||||
|
||||
// prevent placeholders if we don't have a color
|
||||
self.placeholderEnabled = placeholderColor != nil;
|
||||
}
|
||||
|
||||
- (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer;
|
||||
{
|
||||
BOOL hasValidCropBounds = _cropEnabled && !CGRectIsNull(_cropDisplayBounds) && !CGRectIsEmpty(_cropDisplayBounds);
|
||||
|
@ -69,6 +69,18 @@ typedef NS_ENUM(NSUInteger, ASTextNodeHighlightStyle) {
|
||||
*/
|
||||
@property (nonatomic, readonly, assign) NSUInteger lineCount;
|
||||
|
||||
#pragma mark - Placeholders
|
||||
|
||||
/**
|
||||
@abstract The placeholder color.
|
||||
*/
|
||||
@property (nonatomic, strong) UIColor *placeholderColor;
|
||||
|
||||
/**
|
||||
@abstract Inset each line of the placeholder.
|
||||
*/
|
||||
@property (nonatomic, assign) UIEdgeInsets placeholderInsets;
|
||||
|
||||
#pragma mark - Shadow
|
||||
|
||||
/**
|
||||
|
@ -14,6 +14,7 @@
|
||||
#import <AsyncDisplayKit/ASHighlightOverlayLayer.h>
|
||||
#import <AsyncDisplayKit/ASTextNodeCoreTextAdditions.h>
|
||||
#import <AsyncDisplayKit/ASTextNodeTextKitHelpers.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
|
||||
|
||||
#import "ASTextNodeRenderer.h"
|
||||
#import "ASTextNodeShadower.h"
|
||||
@ -135,6 +136,11 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f)
|
||||
self.accessibilityTraits = UIAccessibilityTraitStaticText;
|
||||
|
||||
_constrainedSize = CGSizeMake(-INFINITY, -INFINITY);
|
||||
|
||||
// Placeholders
|
||||
self.placeholderEnabled = YES;
|
||||
_placeholderColor = ASDisplayNodeDefaultPlaceholderColor();
|
||||
_placeholderInsets = UIEdgeInsetsMake(1.0, 0.0, 1.0, 0.0);
|
||||
}
|
||||
|
||||
return self;
|
||||
@ -666,6 +672,43 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f)
|
||||
return [self.class _adjustRendererRect:frame forShadowPadding:self.shadowPadding];
|
||||
}
|
||||
|
||||
#pragma mark - Placeholders
|
||||
|
||||
- (void)setPlaceholderColor:(UIColor *)placeholderColor
|
||||
{
|
||||
_placeholderColor = placeholderColor;
|
||||
|
||||
// prevent placeholders if we don't have a color
|
||||
self.placeholderEnabled = placeholderColor != nil;
|
||||
}
|
||||
|
||||
- (UIImage *)placeholderImage
|
||||
{
|
||||
CGSize size = self.calculatedSize;
|
||||
UIGraphicsBeginImageContext(size);
|
||||
[self.placeholderColor setFill];
|
||||
|
||||
ASTextNodeRenderer *renderer = [self _renderer];
|
||||
NSRange textRange = [renderer visibleRange];
|
||||
|
||||
// cap height is both faster and creates less subpixel blending
|
||||
NSArray *lineRects = [self _rectsForTextRange:textRange measureOption:ASTextNodeRendererMeasureOptionLineHeight];
|
||||
|
||||
// fill each line with the placeholder color
|
||||
for (NSValue *rectValue in lineRects) {
|
||||
CGRect lineRect = [rectValue CGRectValue];
|
||||
CGRect fillBounds = UIEdgeInsetsInsetRect(lineRect, self.placeholderInsets);
|
||||
|
||||
if (fillBounds.size.width > 0.0 && fillBounds.size.height > 0.0) {
|
||||
UIRectFill(fillBounds);
|
||||
}
|
||||
}
|
||||
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return image;
|
||||
}
|
||||
|
||||
#pragma mark - Touch Handling
|
||||
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
|
@ -53,6 +53,12 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)());
|
||||
UIView *_view;
|
||||
CALayer *_layer;
|
||||
|
||||
UIImage *_placeholderImage;
|
||||
CALayer *_placeholderLayer;
|
||||
|
||||
// keeps track of nodes/subnodes that have not finished display, used with placeholders
|
||||
NSMutableSet *_pendingDisplayNodes;
|
||||
|
||||
_ASPendingState *_pendingViewState;
|
||||
|
||||
struct {
|
||||
|
@ -75,7 +75,7 @@ static const CGFloat kInnerPadding = 10.0f;
|
||||
|
||||
// kitten image, with a purple background colour serving as placeholder
|
||||
_imageNode = [[ASNetworkImageNode alloc] init];
|
||||
_imageNode.backgroundColor = [UIColor purpleColor];
|
||||
_imageNode.backgroundColor = ASDisplayNodeDefaultPlaceholderColor();
|
||||
_imageNode.URL = [NSURL URLWithString:[NSString stringWithFormat:@"http://placekitten.com/%zd/%zd",
|
||||
(NSInteger)roundl(_kittenSize.width),
|
||||
(NSInteger)roundl(_kittenSize.height)]];
|
||||
|
BIN
examples/Placeholders/Default-568h@2x.png
Normal file
BIN
examples/Placeholders/Default-568h@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
examples/Placeholders/Default-667h@2x.png
Normal file
BIN
examples/Placeholders/Default-667h@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
BIN
examples/Placeholders/Default-736h@3x.png
Normal file
BIN
examples/Placeholders/Default-736h@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
3
examples/Placeholders/Podfile
Normal file
3
examples/Placeholders/Podfile
Normal file
@ -0,0 +1,3 @@
|
||||
source 'https://github.com/CocoaPods/Specs.git'
|
||||
platform :ios, '8.0'
|
||||
pod 'AsyncDisplayKit', :path => '../..'
|
372
examples/Placeholders/Sample.xcodeproj/project.pbxproj
Normal file
372
examples/Placeholders/Sample.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,372 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0585428019D4DBE100606EA6 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0585427F19D4DBE100606EA6 /* Default-568h@2x.png */; };
|
||||
05E2128719D4DB510098F589 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 05E2128619D4DB510098F589 /* main.m */; };
|
||||
05E2128A19D4DB510098F589 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 05E2128919D4DB510098F589 /* AppDelegate.m */; };
|
||||
05E2128D19D4DB510098F589 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 05E2128C19D4DB510098F589 /* ViewController.m */; };
|
||||
29A7F3A51A3638DE00CF34F2 /* SlowpokeTextNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 29A7F3A41A3638DE00CF34F2 /* SlowpokeTextNode.m */; };
|
||||
29E35E9B1A2F8DB0007B4B17 /* SlowpokeImageNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 29E35E9A1A2F8DB0007B4B17 /* SlowpokeImageNode.m */; };
|
||||
29E35E9E1A2F8DBC007B4B17 /* SlowpokeShareNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 29E35E9D1A2F8DBC007B4B17 /* SlowpokeShareNode.m */; };
|
||||
29E35EA01A2F9650007B4B17 /* logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 29E35E9F1A2F9650007B4B17 /* logo.png */; };
|
||||
29E35EA31A2FD0E9007B4B17 /* PostNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 29E35EA21A2FD0E9007B4B17 /* PostNode.m */; };
|
||||
3EC0CDCBA10D483D9F386E5E /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D24B17D1E4A4E7A9566C5E9 /* libPods.a */; };
|
||||
6C2C82AC19EE274300767484 /* Default-667h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6C2C82AA19EE274300767484 /* Default-667h@2x.png */; };
|
||||
6C2C82AD19EE274300767484 /* Default-736h@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6C2C82AB19EE274300767484 /* Default-736h@3x.png */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0585427F19D4DBE100606EA6 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "../Default-568h@2x.png"; sourceTree = "<group>"; };
|
||||
05E2128119D4DB510098F589 /* Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
05E2128519D4DB510098F589 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
05E2128619D4DB510098F589 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
05E2128819D4DB510098F589 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
05E2128919D4DB510098F589 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
05E2128B19D4DB510098F589 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
|
||||
05E2128C19D4DB510098F589 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
|
||||
088AA6578212BE9BFBB07B70 /* 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>"; };
|
||||
29A7F3A31A3638DE00CF34F2 /* SlowpokeTextNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlowpokeTextNode.h; sourceTree = "<group>"; };
|
||||
29A7F3A41A3638DE00CF34F2 /* SlowpokeTextNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SlowpokeTextNode.m; sourceTree = "<group>"; };
|
||||
29E35E991A2F8DB0007B4B17 /* SlowpokeImageNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlowpokeImageNode.h; sourceTree = "<group>"; };
|
||||
29E35E9A1A2F8DB0007B4B17 /* SlowpokeImageNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SlowpokeImageNode.m; sourceTree = "<group>"; };
|
||||
29E35E9C1A2F8DBC007B4B17 /* SlowpokeShareNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlowpokeShareNode.h; sourceTree = "<group>"; };
|
||||
29E35E9D1A2F8DBC007B4B17 /* SlowpokeShareNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SlowpokeShareNode.m; sourceTree = "<group>"; };
|
||||
29E35E9F1A2F9650007B4B17 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = "<group>"; };
|
||||
29E35EA11A2FD0E9007B4B17 /* PostNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PostNode.h; sourceTree = "<group>"; };
|
||||
29E35EA21A2FD0E9007B4B17 /* PostNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PostNode.m; sourceTree = "<group>"; };
|
||||
3D24B17D1E4A4E7A9566C5E9 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6C2C82AA19EE274300767484 /* Default-667h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h@2x.png"; sourceTree = SOURCE_ROOT; };
|
||||
6C2C82AB19EE274300767484 /* Default-736h@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h@3x.png"; sourceTree = SOURCE_ROOT; };
|
||||
C068F1D3F0CC317E895FCDAB /* 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>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
05E2127E19D4DB510098F589 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3EC0CDCBA10D483D9F386E5E /* libPods.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
05E2127819D4DB510098F589 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
05E2128319D4DB510098F589 /* Sample */,
|
||||
05E2128219D4DB510098F589 /* Products */,
|
||||
1A943BF0259746F18D6E423F /* Frameworks */,
|
||||
1AE410B73DA5C3BD087ACDD7 /* Pods */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
05E2128219D4DB510098F589 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
05E2128119D4DB510098F589 /* Sample.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
05E2128319D4DB510098F589 /* Sample */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
05E2128819D4DB510098F589 /* AppDelegate.h */,
|
||||
05E2128919D4DB510098F589 /* AppDelegate.m */,
|
||||
29E35E9F1A2F9650007B4B17 /* logo.png */,
|
||||
29E35EA11A2FD0E9007B4B17 /* PostNode.h */,
|
||||
29E35EA21A2FD0E9007B4B17 /* PostNode.m */,
|
||||
29E35E991A2F8DB0007B4B17 /* SlowpokeImageNode.h */,
|
||||
29E35E9A1A2F8DB0007B4B17 /* SlowpokeImageNode.m */,
|
||||
29E35E9C1A2F8DBC007B4B17 /* SlowpokeShareNode.h */,
|
||||
29E35E9D1A2F8DBC007B4B17 /* SlowpokeShareNode.m */,
|
||||
29A7F3A31A3638DE00CF34F2 /* SlowpokeTextNode.h */,
|
||||
29A7F3A41A3638DE00CF34F2 /* SlowpokeTextNode.m */,
|
||||
05E2128419D4DB510098F589 /* Supporting Files */,
|
||||
05E2128B19D4DB510098F589 /* ViewController.h */,
|
||||
05E2128C19D4DB510098F589 /* ViewController.m */,
|
||||
);
|
||||
path = Sample;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
05E2128419D4DB510098F589 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0585427F19D4DBE100606EA6 /* Default-568h@2x.png */,
|
||||
6C2C82AA19EE274300767484 /* Default-667h@2x.png */,
|
||||
6C2C82AB19EE274300767484 /* Default-736h@3x.png */,
|
||||
05E2128519D4DB510098F589 /* Info.plist */,
|
||||
05E2128619D4DB510098F589 /* main.m */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1A943BF0259746F18D6E423F /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3D24B17D1E4A4E7A9566C5E9 /* libPods.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1AE410B73DA5C3BD087ACDD7 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C068F1D3F0CC317E895FCDAB /* Pods.debug.xcconfig */,
|
||||
088AA6578212BE9BFBB07B70 /* Pods.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
05E2128019D4DB510098F589 /* Sample */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 05E212A419D4DB510098F589 /* Build configuration list for PBXNativeTarget "Sample" */;
|
||||
buildPhases = (
|
||||
E080B80F89C34A25B3488E26 /* Check Pods Manifest.lock */,
|
||||
05E2127D19D4DB510098F589 /* Sources */,
|
||||
05E2127E19D4DB510098F589 /* Frameworks */,
|
||||
05E2127F19D4DB510098F589 /* Resources */,
|
||||
F012A6F39E0149F18F564F50 /* Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Sample;
|
||||
productName = Sample;
|
||||
productReference = 05E2128119D4DB510098F589 /* Sample.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
05E2127919D4DB510098F589 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0600;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
TargetAttributes = {
|
||||
05E2128019D4DB510098F589 = {
|
||||
CreatedOnToolsVersion = 6.0.1;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 05E2127C19D4DB510098F589 /* Build configuration list for PBXProject "Sample" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 05E2127819D4DB510098F589;
|
||||
productRefGroup = 05E2128219D4DB510098F589 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
05E2128019D4DB510098F589 /* Sample */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
05E2127F19D4DB510098F589 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
29E35EA01A2F9650007B4B17 /* logo.png in Resources */,
|
||||
0585428019D4DBE100606EA6 /* Default-568h@2x.png in Resources */,
|
||||
6C2C82AC19EE274300767484 /* Default-667h@2x.png in Resources */,
|
||||
6C2C82AD19EE274300767484 /* Default-736h@3x.png in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
E080B80F89C34A25B3488E26 /* 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;
|
||||
};
|
||||
F012A6F39E0149F18F564F50 /* 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;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
05E2127D19D4DB510098F589 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
29A7F3A51A3638DE00CF34F2 /* SlowpokeTextNode.m in Sources */,
|
||||
29E35E9B1A2F8DB0007B4B17 /* SlowpokeImageNode.m in Sources */,
|
||||
29E35E9E1A2F8DBC007B4B17 /* SlowpokeShareNode.m in Sources */,
|
||||
05E2128D19D4DB510098F589 /* ViewController.m in Sources */,
|
||||
05E2128A19D4DB510098F589 /* AppDelegate.m in Sources */,
|
||||
29E35EA31A2FD0E9007B4B17 /* PostNode.m in Sources */,
|
||||
05E2128719D4DB510098F589 /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
05E212A219D4DB510098F589 /* 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.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
05E212A319D4DB510098F589 /* 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.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
05E212A519D4DB510098F589 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = C068F1D3F0CC317E895FCDAB /* 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;
|
||||
};
|
||||
05E212A619D4DB510098F589 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 088AA6578212BE9BFBB07B70 /* 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 */
|
||||
05E2127C19D4DB510098F589 /* Build configuration list for PBXProject "Sample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
05E212A219D4DB510098F589 /* Debug */,
|
||||
05E212A319D4DB510098F589 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
05E212A419D4DB510098F589 /* Build configuration list for PBXNativeTarget "Sample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
05E212A519D4DB510098F589 /* Debug */,
|
||||
05E212A619D4DB510098F589 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 05E2127919D4DB510098F589 /* Project object */;
|
||||
}
|
7
examples/Placeholders/Sample.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
examples/Placeholders/Sample.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:Sample.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
1
examples/Placeholders/Sample.xcworkspace/contents.xcworkspacedata
generated
Normal file
1
examples/Placeholders/Sample.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?><Workspace version='1.0'><FileRef location='group:Sample.xcodeproj'/><FileRef location='group:Pods/Pods.xcodeproj'/></Workspace>
|
18
examples/Placeholders/Sample/AppDelegate.h
Normal file
18
examples/Placeholders/Sample/AppDelegate.h
Normal file
@ -0,0 +1,18 @@
|
||||
/* 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
|
27
examples/Placeholders/Sample/AppDelegate.m
Normal file
27
examples/Placeholders/Sample/AppDelegate.m
Normal file
@ -0,0 +1,27 @@
|
||||
/* 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 "ViewController.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
self.window.backgroundColor = [UIColor whiteColor];
|
||||
self.window.rootViewController = [[ViewController alloc] init];
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
36
examples/Placeholders/Sample/Info.plist
Normal file
36
examples/Placeholders/Sample/Info.plist
Normal file
@ -0,0 +1,36 @@
|
||||
<?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.facebook.AsyncDisplayKit.$(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>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
16
examples/Placeholders/Sample/PostNode.h
Normal file
16
examples/Placeholders/Sample/PostNode.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* 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 : ASDisplayNode
|
||||
|
||||
@end
|
88
examples/Placeholders/Sample/PostNode.m
Normal file
88
examples/Placeholders/Sample/PostNode.m
Normal file
@ -0,0 +1,88 @@
|
||||
/* 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 "SlowpokeShareNode.h"
|
||||
#import "SlowpokeTextNode.h"
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
|
||||
|
||||
@interface PostNode ()
|
||||
{
|
||||
SlowpokeTextNode *_textNode;
|
||||
SlowpokeShareNode *_needyChildNode; // this node slows down display
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PostNode
|
||||
|
||||
// turn on to demo that the parent displays a placeholder even if it takes the longest
|
||||
//+ (void)drawRect:(CGRect)bounds withParameters:(id<NSObject>)parameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing
|
||||
//{
|
||||
// usleep( (long)(1.2 * USEC_PER_SEC) ); // artificial delay of 1.2s
|
||||
//
|
||||
// // demonstrates that the parent node should also adhere to the placeholder
|
||||
// [[UIColor colorWithWhite:0.95 alpha:1.0] setFill];
|
||||
// UIRectFill(bounds);
|
||||
//}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (!(self = [super init]))
|
||||
return nil;
|
||||
|
||||
_textNode = [[SlowpokeTextNode alloc] init];
|
||||
_textNode.placeholderInsets = UIEdgeInsetsMake(3.0, 0.0, 3.0, 0.0);
|
||||
_textNode.placeholderEnabled = YES;
|
||||
|
||||
NSString *text = @"Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh.";
|
||||
NSDictionary *attributes = @{ NSFontAttributeName: [UIFont systemFontOfSize:17.0] };
|
||||
_textNode.attributedString = [[NSAttributedString alloc] initWithString:text attributes:attributes];
|
||||
|
||||
_needyChildNode = [[SlowpokeShareNode alloc] init];
|
||||
_needyChildNode.opaque = NO;
|
||||
|
||||
[self addSubnode:_textNode];
|
||||
[self addSubnode:_needyChildNode];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (UIImage *)placeholderImage
|
||||
{
|
||||
CGSize size = self.calculatedSize;
|
||||
UIGraphicsBeginImageContext(size);
|
||||
[[UIColor colorWithWhite:0.9 alpha:1] setFill];
|
||||
UIRectFill((CGRect){CGPointZero, size});
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return image;
|
||||
}
|
||||
|
||||
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
||||
{
|
||||
CGSize textSize = [_textNode measure:constrainedSize];
|
||||
CGSize shareSize = [_needyChildNode measure:constrainedSize];
|
||||
|
||||
return CGSizeMake(constrainedSize.width, textSize.height + 10.0 + shareSize.height);
|
||||
}
|
||||
|
||||
- (void)layout
|
||||
{
|
||||
CGSize textSize = _textNode.calculatedSize;
|
||||
CGSize needyChildSize = _needyChildNode.calculatedSize;
|
||||
|
||||
_textNode.frame = (CGRect){CGPointZero, textSize};
|
||||
_needyChildNode.frame = (CGRect){0.0, CGRectGetMaxY(_textNode.frame) + 10.0, needyChildSize};
|
||||
}
|
||||
|
||||
@end
|
16
examples/Placeholders/Sample/SlowpokeImageNode.h
Normal file
16
examples/Placeholders/Sample/SlowpokeImageNode.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* 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 SlowpokeImageNode : ASImageNode
|
||||
|
||||
@end
|
65
examples/Placeholders/Sample/SlowpokeImageNode.m
Normal file
65
examples/Placeholders/Sample/SlowpokeImageNode.m
Normal file
@ -0,0 +1,65 @@
|
||||
/* 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 "SlowpokeImageNode.h"
|
||||
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
|
||||
|
||||
static CGFloat const kASDKLogoAspectRatio = 2.79;
|
||||
|
||||
@implementation SlowpokeImageNode
|
||||
|
||||
+ (UIImage *)displayWithParameters:(id<NSObject>)parameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelledBlock
|
||||
{
|
||||
usleep( (long)(0.5 * USEC_PER_SEC) ); // artificial delay of 0.5s
|
||||
|
||||
return [super displayWithParameters:parameters isCancelled:isCancelledBlock];
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
self.placeholderEnabled = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
||||
{
|
||||
if (constrainedSize.width > 0.0) {
|
||||
return CGSizeMake(constrainedSize.width, constrainedSize.width / kASDKLogoAspectRatio);
|
||||
} else if (constrainedSize.height > 0.0) {
|
||||
return CGSizeMake(constrainedSize.height * kASDKLogoAspectRatio, constrainedSize.height);
|
||||
}
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
- (UIImage *)placeholderImage
|
||||
{
|
||||
CGSize size = self.calculatedSize;
|
||||
UIGraphicsBeginImageContext(size);
|
||||
[[UIColor colorWithWhite:0.9 alpha:1] setStroke];
|
||||
|
||||
UIBezierPath *path = [UIBezierPath bezierPath];
|
||||
[path moveToPoint:CGPointZero];
|
||||
[path addLineToPoint:(CGPoint){size.width, size.height}];
|
||||
[path stroke];
|
||||
|
||||
[path moveToPoint:(CGPoint){size.width, 0.0}];
|
||||
[path addLineToPoint:(CGPoint){0.0, size.height}];
|
||||
[path stroke];
|
||||
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return image;
|
||||
}
|
||||
|
||||
@end
|
16
examples/Placeholders/Sample/SlowpokeShareNode.h
Normal file
16
examples/Placeholders/Sample/SlowpokeShareNode.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* 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 SlowpokeShareNode : ASControlNode
|
||||
|
||||
@end
|
43
examples/Placeholders/Sample/SlowpokeShareNode.m
Normal file
43
examples/Placeholders/Sample/SlowpokeShareNode.m
Normal file
@ -0,0 +1,43 @@
|
||||
/* 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 "SlowpokeShareNode.h"
|
||||
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
|
||||
|
||||
static NSUInteger const kRingCount = 3;
|
||||
static CGFloat const kRingStrokeWidth = 1.0;
|
||||
static CGSize const kIconSize = (CGSize){ 60.0, 17.0 };
|
||||
|
||||
@implementation SlowpokeShareNode
|
||||
|
||||
+ (void)drawRect:(CGRect)bounds withParameters:(id<NSObject>)parameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing
|
||||
{
|
||||
usleep( (long)(0.8 * USEC_PER_SEC) ); // artificial delay of 0.8s
|
||||
|
||||
[[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];
|
||||
}
|
||||
}
|
||||
|
||||
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
||||
{
|
||||
return kIconSize;
|
||||
}
|
||||
|
||||
@end
|
16
examples/Placeholders/Sample/SlowpokeTextNode.h
Normal file
16
examples/Placeholders/Sample/SlowpokeTextNode.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* 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 SlowpokeTextNode : ASTextNode
|
||||
|
||||
@end
|
25
examples/Placeholders/Sample/SlowpokeTextNode.m
Normal file
25
examples/Placeholders/Sample/SlowpokeTextNode.m
Normal file
@ -0,0 +1,25 @@
|
||||
/* 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 "SlowpokeTextNode.h"
|
||||
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
|
||||
|
||||
@implementation SlowpokeTextNode
|
||||
|
||||
+ (void)drawRect:(CGRect)bounds withParameters:(id<NSObject>)parameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing
|
||||
{
|
||||
usleep( (long)(1.0 * USEC_PER_SEC) ); // artificial delay of 1.0
|
||||
|
||||
[super drawRect:bounds withParameters:parameters isCancelled:isCancelledBlock isRasterizing:isRasterizing];
|
||||
}
|
||||
|
||||
@end
|
16
examples/Placeholders/Sample/ViewController.h
Normal file
16
examples/Placeholders/Sample/ViewController.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* 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 ViewController : UIViewController
|
||||
|
||||
@end
|
105
examples/Placeholders/Sample/ViewController.m
Normal file
105
examples/Placeholders/Sample/ViewController.m
Normal file
@ -0,0 +1,105 @@
|
||||
/* 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 "ViewController.h"
|
||||
|
||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
|
||||
#import "PostNode.h"
|
||||
#import "SlowpokeImageNode.h"
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
|
||||
|
||||
@interface ViewController ()
|
||||
{
|
||||
PostNode *_postNode;
|
||||
SlowpokeImageNode *_imageNode;
|
||||
UIButton *_displayButton;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation ViewController
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark UIViewController
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (!(self = [super init]))
|
||||
return nil;
|
||||
|
||||
_displayButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[_displayButton setTitle:@"Display me!" forState:UIControlStateNormal];
|
||||
[_displayButton addTarget:self action:@selector(onDisplayButton:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
UIColor *tintBlue = [UIColor colorWithRed:0 green:122/255.0 blue:1.0 alpha:1.0];
|
||||
[_displayButton setTitleColor:tintBlue forState:UIControlStateNormal];
|
||||
[_displayButton setTitleColor:[tintBlue colorWithAlphaComponent:0.5] forState:UIControlStateHighlighted];
|
||||
_displayButton.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
[self.view addSubview:_displayButton];
|
||||
}
|
||||
|
||||
- (void)viewWillLayoutSubviews
|
||||
{
|
||||
CGFloat padding = 20.0;
|
||||
CGRect bounds = self.view.bounds;
|
||||
CGFloat constrainedWidth = CGRectGetWidth(bounds);
|
||||
CGSize constrainedSize = CGSizeMake(constrainedWidth - 2 * padding, CGFLOAT_MAX);
|
||||
|
||||
CGSize postSize = [_postNode measure:constrainedSize];
|
||||
CGSize imageSize = [_imageNode measure:constrainedSize];
|
||||
|
||||
_imageNode.frame = (CGRect){padding, padding, imageSize};
|
||||
_postNode.frame = (CGRect){padding, CGRectGetMaxY(_imageNode.frame) + 10.0, postSize};
|
||||
|
||||
CGFloat buttonHeight = 55.0;
|
||||
_displayButton.frame = (CGRect){0.0, CGRectGetHeight(bounds) - buttonHeight, CGRectGetWidth(bounds), buttonHeight};
|
||||
}
|
||||
|
||||
// this method is pretty gross and just for demonstration :]
|
||||
- (void)createAndDisplayNodes
|
||||
{
|
||||
[_imageNode.view removeFromSuperview];
|
||||
[_postNode.view removeFromSuperview];
|
||||
|
||||
// ASImageNode gets placeholders by default
|
||||
_imageNode = [[SlowpokeImageNode alloc] init];
|
||||
_imageNode.image = [UIImage imageNamed:@"logo"];
|
||||
|
||||
_postNode = [[PostNode alloc] init];
|
||||
|
||||
// change to NO to see text placeholders, change to YES to see the parent placeholder
|
||||
// this placeholder will cover all subnodes while they are displaying, just a like a stage curtain!
|
||||
_postNode.placeholderEnabled = NO;
|
||||
|
||||
[self.view addSubview:_imageNode.view];
|
||||
[self.view addSubview:_postNode.view];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Actions
|
||||
|
||||
- (void)onDisplayButton:(id)sender
|
||||
{
|
||||
[self createAndDisplayNodes];
|
||||
}
|
||||
|
||||
@end
|
BIN
examples/Placeholders/Sample/logo.png
Executable file
BIN
examples/Placeholders/Sample/logo.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 103 KiB |
20
examples/Placeholders/Sample/main.m
Normal file
20
examples/Placeholders/Sample/main.m
Normal file
@ -0,0 +1,20 @@
|
||||
/* 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]));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user