Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions AsyncDisplayKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@
258FF4281C0D152600A83844 /* ASRangeHandlerVisible.mm in Sources */ = {isa = PBXBuildFile; fileRef = 258FF4261C0D152600A83844 /* ASRangeHandlerVisible.mm */; };
25A977EF1C0D2A5500406B62 /* ASRangeHandlerVisible.mm in Sources */ = {isa = PBXBuildFile; fileRef = 258FF4261C0D152600A83844 /* ASRangeHandlerVisible.mm */; };
25BAA16F1C0D18D2002747C7 /* ASRangeHandlerVisible.h in Headers */ = {isa = PBXBuildFile; fileRef = 258FF4251C0D152600A83844 /* ASRangeHandlerVisible.h */; };
25E327561C16819500A2170C /* ASPagerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 25E327541C16819500A2170C /* ASPagerNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
25E327571C16819500A2170C /* ASPagerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 25E327541C16819500A2170C /* ASPagerNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
25E327581C16819500A2170C /* ASPagerNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 25E327551C16819500A2170C /* ASPagerNode.m */; };
25E327591C16819500A2170C /* ASPagerNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 25E327551C16819500A2170C /* ASPagerNode.m */; };
2767E9411BB19BD600EA9B77 /* ASViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
2767E9421BB19BD600EA9B77 /* ASViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ACC945AA1BA9E7C1005E1FB8 /* ASViewController.m */; };
2911485C1A77147A005D0878 /* ASControlNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2911485B1A77147A005D0878 /* ASControlNodeTests.m */; };
Expand Down Expand Up @@ -644,6 +648,8 @@
257754BD1BEE458E00737CA5 /* ASTextNodeWordKerner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASTextNodeWordKerner.m; path = TextKit/ASTextNodeWordKerner.m; sourceTree = "<group>"; };
258FF4251C0D152600A83844 /* ASRangeHandlerVisible.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeHandlerVisible.h; sourceTree = "<group>"; };
258FF4261C0D152600A83844 /* ASRangeHandlerVisible.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRangeHandlerVisible.mm; sourceTree = "<group>"; };
25E327541C16819500A2170C /* ASPagerNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPagerNode.h; sourceTree = "<group>"; };
25E327551C16819500A2170C /* ASPagerNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPagerNode.m; sourceTree = "<group>"; };
2911485B1A77147A005D0878 /* ASControlNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASControlNodeTests.m; sourceTree = "<group>"; };
292C59991A956527007E5DD6 /* ASLayoutRangeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutRangeType.h; sourceTree = "<group>"; };
292C599A1A956527007E5DD6 /* ASRangeHandlerPreload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeHandlerPreload.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -893,6 +899,8 @@
0516FA3F1A1563D200B4EBED /* ASMultiplexImageNode.mm */,
055B9FA61A1C154B00035D6D /* ASNetworkImageNode.h */,
055B9FA71A1C154B00035D6D /* ASNetworkImageNode.mm */,
25E327541C16819500A2170C /* ASPagerNode.h */,
25E327551C16819500A2170C /* ASPagerNode.m */,
D785F6601A74327E00291744 /* ASScrollNode.h */,
D785F6611A74327E00291744 /* ASScrollNode.m */,
B0F880581BEAEC7500D17647 /* ASTableNode.h */,
Expand Down Expand Up @@ -1246,6 +1254,7 @@
058D0A83195D060300B7D73C /* ASBaseDefines.h in Headers */,
054963491A1EA066000F8E56 /* ASBasicImageDownloader.h in Headers */,
2967F9E21AB0A5190072E4AB /* ASBasicImageDownloaderInternal.h in Headers */,
25E327561C16819500A2170C /* ASPagerNode.h in Headers */,
299DA1A91A828D2900162D41 /* ASBatchContext.h in Headers */,
251B8EF91BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.h in Headers */,
044285071BAA63FE00D16268 /* ASBatchFetching.h in Headers */,
Expand Down Expand Up @@ -1438,6 +1447,7 @@
B350622D1B010EFD0018CF92 /* ASScrollDirection.h in Headers */,
254C6B751BF94DF4003EC431 /* ASTextKitHelpers.h in Headers */,
B35062081B010EFD0018CF92 /* ASScrollNode.h in Headers */,
25E327571C16819500A2170C /* ASPagerNode.h in Headers */,
B35062551B010EFD0018CF92 /* ASSentinel.h in Headers */,
9C8221961BA237B80037F19A /* ASStackBaselinePositionedLayout.h in Headers */,
9C49C3701B853961000B0DD5 /* ASStackLayoutable.h in Headers */,
Expand Down Expand Up @@ -1687,6 +1697,7 @@
058D0A28195D050800B7D73C /* ASDisplayNode+AsyncDisplay.mm in Sources */,
058D0A29195D050800B7D73C /* ASDisplayNode+DebugTiming.mm in Sources */,
058D0A2A195D050800B7D73C /* ASDisplayNode+UIViewBridge.mm in Sources */,
25E327581C16819500A2170C /* ASPagerNode.m in Sources */,
058D0A14195D050800B7D73C /* ASDisplayNode.mm in Sources */,
058D0A15195D050800B7D73C /* ASDisplayNodeExtras.mm in Sources */,
0587F9BE1A7309ED00AFF0BA /* ASEditableTextNode.mm in Sources */,
Expand Down Expand Up @@ -1815,6 +1826,7 @@
B350621A1B010EFD0018CF92 /* ASDealloc2MainObject.m in Sources */,
34EFC75C1B701BD200AD841F /* ASDimension.mm in Sources */,
B350624E1B010EFD0018CF92 /* ASDisplayNode+AsyncDisplay.mm in Sources */,
25E327591C16819500A2170C /* ASPagerNode.m in Sources */,
B35062501B010EFD0018CF92 /* ASDisplayNode+DebugTiming.mm in Sources */,
254C6B891BF94F8A003EC431 /* ASTextKitRenderer+Positioning.mm in Sources */,
B35062511B010EFD0018CF92 /* ASDisplayNode+UIViewBridge.mm in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion AsyncDisplayKit/ASCollectionNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// Copyright (c) 2015 Facebook. All rights reserved.
//

#import <AsyncDisplayKit/AsyncDisplayKit.h>
#import <AsyncDisplayKit/ASCollectionView.h>

/**
* ASCollectionNode is a node based class that wraps an ASCollectionView. It can be used
Expand Down
1 change: 1 addition & 0 deletions AsyncDisplayKit/ASCollectionNode.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#import "ASCollectionNode.h"
#import "ASDisplayNode+Subclasses.h"

@implementation ASCollectionNode

Expand Down
29 changes: 29 additions & 0 deletions AsyncDisplayKit/ASPagerNode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// ASPagerNode.h
// AsyncDisplayKit
//
// Created by Levi McCallum on 12/7/15.
// Copyright © 2015 Facebook. All rights reserved.
//

#import <AsyncDisplayKit/ASCollectionNode.h>

@protocol ASPagerNodeDataSource;

@interface ASPagerNode : ASCollectionNode

@property (weak, nonatomic) id<ASPagerNodeDataSource> dataSource;

- (void)reloadData;

- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType;

@end

@protocol ASPagerNodeDataSource <NSObject>

- (NSInteger)numberOfPagesInPagerNode:(ASPagerNode *)pagerNode;

- (ASCellNode *)pagerNode:(ASPagerNode *)pagerNode nodeAtIndex:(NSInteger)index;

@end
74 changes: 74 additions & 0 deletions AsyncDisplayKit/ASPagerNode.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// ASPagerNode.m
// AsyncDisplayKit
//
// Created by Levi McCallum on 12/7/15.
// Copyright © 2015 Facebook. All rights reserved.
//

#import "ASPagerNode.h"

#import <AsyncDisplayKit/AsyncDisplayKit.h>

@interface ASPagerNode () <ASCollectionViewDataSource, ASCollectionViewDelegateFlowLayout> {
UICollectionViewFlowLayout *_flowLayout;
}

@end

@implementation ASPagerNode

- (instancetype)init
{
_flowLayout = [[UICollectionViewFlowLayout alloc] init];
_flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
_flowLayout.minimumInteritemSpacing = 0;
_flowLayout.minimumLineSpacing = 0;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably wanna expose things like this so people can get spacing between pages

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, definitely agreed. Next changes!


self = [super initWithCollectionViewLayout:_flowLayout];
if (self != nil) {
self.view.asyncDataSource = self;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is essential that we set these in -didLoad, not in -init. Some big perf problems in Pinterest were addressed by ensuring we didn't poke the creation of ASCollectionViews too early.

self.view.asyncDelegate = self;

self.view.pagingEnabled = YES;
self.view.allowsSelection = NO;
self.view.showsVerticalScrollIndicator = NO;
self.view.showsHorizontalScrollIndicator = NO;

ASRangeTuningParameters tuningParams = { .leadingBufferScreenfuls = 1.0, .trailingBufferScreenfuls = 1.0 };
[self setTuningParameters:tuningParams forRangeType:ASLayoutRangeTypePreload];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, good idea to have new defaults for these. However, please set the Preload range to 2.0 both leading and trailing.

[self setTuningParameters:tuningParams forRangeType:ASLayoutRangeTypeRender];
}
return self;
}

- (void)reloadData
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just implement this on ASCollectionNode? Redeclaring it in the header for clarity so people don't have to look at the superclass is fine for now, but we should make sure that anything relevant to ASCollectionNode is put there. Same is probably true for setTuningParameters.

{
[self.view reloadData];
}

- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not obvious that this will trigger view creation. Suggest putting it on ASCollectionNode - and creating a new data type similar to ASPendingViewState that both ASCollectionNode and/or ASTableNode (possibly different data types for each) can use to store properties like the delegate / dataSource / tuningParameters before the view is created, and apply them in -didLoad.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agree with this suggestion. I think we need to introduce a broader data type which allows any custom node to defer application of a value until the view has loaded. I think we could go about this by upgrading ASPendingViewState to support custom properties.

{
[self.view setTuningParameters:tuningParameters forRangeType:rangeType];
}

#pragma mark - ASCollectionViewDataSource

- (ASCellNode *)collectionView:(ASCollectionView *)collectionView nodeForItemAtIndexPath:(NSIndexPath *)indexPath
{
ASDisplayNodeAssert(self.dataSource != nil, @"ASPagerNode must have a data source to load paging nodes");
return [self.dataSource pagerNode:self nodeAtIndex:indexPath.item];
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
ASDisplayNodeAssert(self.dataSource != nil, @"ASPagerNode must have a data source to load paging nodes");
return [self.dataSource numberOfPagesInPagerNode:self];
}

- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
{
return ASSizeRangeMake(CGSizeZero, self.view.bounds.size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might actually make more sense for the minimum size to also be the bounds size, because we probably don't want pages laying out at a size less than the page, even if they have to flex to add more space.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to keep the restriction of having one node per a page a loose one. With an undefined minimum size, it keeps the possibility open of showing pages that have multiple nodes.

}

@end
2 changes: 2 additions & 0 deletions AsyncDisplayKit/AsyncDisplayKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

#import <AsyncDisplayKit/ASScrollNode.h>

#import <AsyncDisplayKit/ASPagerNode.h>

#import <AsyncDisplayKit/ASViewController.h>

#import <AsyncDisplayKit/ASChangeSetDataController.h>
Expand Down
Binary file added examples/PagerNode/Default-568h@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/PagerNode/Default-667h@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/PagerNode/Default-736h@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions examples/PagerNode/Podfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
pod 'AsyncDisplayKit', :path => '../..'
Loading