[ASTableView] Add constrainedSizeForRowAtIndexPath: to control row heights from delegate (#1769)

* [ASTableView] constrainedSizeForRowAtIndexPath

* Quick fix to header file

* Switch to Delegate from DataSource.

* Update testing variables to reflect switch to delegate
This commit is contained in:
Hannah Troisi 2016-06-26 23:09:53 -07:00 committed by appleguy
parent ae87717263
commit db04f4b851
3 changed files with 67 additions and 3 deletions

View File

@ -433,6 +433,18 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (BOOL)shouldBatchFetchForTableView:(ASTableView *)tableView;
/**
* Provides the constrained size range for measuring the row at the index path.
* Note: the widths in the returned size range are ignored!
*
* @param tableView The sender.
*
* @param indexPath The index path of the node.
*
* @returns A constrained size range for layout the node at this index path.
*/
- (ASSizeRange)tableView:(ASTableView *)tableView constrainedSizeForRowAtIndexPath:(NSIndexPath *)indexPath;
/**
* Informs the delegate that the table view did remove the node which was previously
* at the given index path from the view hierarchy.

View File

@ -28,6 +28,7 @@
#import <CoreFoundation/CoreFoundation.h>
static const ASSizeRange kInvalidSizeRange = {CGSizeZero, CGSizeZero};
static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
//#define LOG(...) NSLog(__VA_ARGS__)
@ -125,6 +126,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
unsigned int asyncDelegateScrollViewWillEndDraggingWithVelocityTargetContentOffset:1;
unsigned int asyncDelegateTableViewWillBeginBatchFetchWithContext:1;
unsigned int asyncDelegateShouldBatchFetchForTableView:1;
unsigned int asyncDelegateTableViewConstrainedSizeForRowAtIndexPath:1;
} _asyncDelegateFlags;
struct {
@ -316,6 +318,8 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
_asyncDelegateFlags.asyncDelegateShouldBatchFetchForTableView = [_asyncDelegate respondsToSelector:@selector(shouldBatchFetchForTableView:)];
_asyncDelegateFlags.asyncDelegateScrollViewWillBeginDragging = [_asyncDelegate respondsToSelector:@selector(scrollViewWillBeginDragging:)];
_asyncDelegateFlags.asyncDelegateScrollViewDidEndDragging = [_asyncDelegate respondsToSelector:@selector(scrollViewDidEndDragging:willDecelerate:)];
_asyncDelegateFlags.asyncDelegateTableViewConstrainedSizeForRowAtIndexPath = [_asyncDelegate respondsToSelector:@selector(tableView:constrainedSizeForRowAtIndexPath:)];
}
super.delegate = (id<UITableViewDelegate>)_proxyDelegate;
@ -1069,8 +1073,17 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
- (ASSizeRange)dataController:(ASDataController *)dataController constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
{
return ASSizeRangeMake(CGSizeMake(_nodesConstrainedWidth, 0),
CGSizeMake(_nodesConstrainedWidth, FLT_MAX));
ASSizeRange constrainedSize = kInvalidSizeRange;
if (_asyncDelegateFlags.asyncDelegateTableViewConstrainedSizeForRowAtIndexPath) {
ASSizeRange delegateConstrainedSize = [_asyncDelegate tableView:self constrainedSizeForRowAtIndexPath:indexPath];
// ignore widths in the returned size range (for TableView)
constrainedSize = ASSizeRangeMake(CGSizeMake(_nodesConstrainedWidth, delegateConstrainedSize.min.height),
CGSizeMake(_nodesConstrainedWidth, delegateConstrainedSize.max.height));
} else {
constrainedSize = ASSizeRangeMake(CGSizeMake(_nodesConstrainedWidth, 0),
CGSizeMake(_nodesConstrainedWidth, FLT_MAX));
}
return constrainedSize;
}
- (NSUInteger)dataController:(ASDataController *)dataController rowsInSection:(NSUInteger)section

View File

@ -128,7 +128,6 @@
return textCellNode;
}
- (ASCellNodeBlock)tableView:(ASTableView *)tableView nodeBlockForRowAtIndexPath:(NSIndexPath *)indexPath
{
return ^{
@ -140,12 +139,52 @@
@end
@interface ASTableViewFilledDelegate : NSObject <ASTableViewDelegate>
@end
@implementation ASTableViewFilledDelegate
- (ASSizeRange)tableView:(ASTableView *)tableView constrainedSizeForRowAtIndexPath:(NSIndexPath *)indexPath
{
return ASSizeRangeMakeExactSize(CGSizeMake(10, 42));
}
@end
@interface ASTableViewTests : XCTestCase
@property (atomic, retain) ASTableView *testTableView;
@end
@implementation ASTableViewTests
- (void)testConstrainedSizeForRowAtIndexPath
{
// Initial width of the table view is non-zero and all nodes are measured with this size.
// Any subsequence size change must trigger a relayout.
// Width and height are swapped so that a later size change will simulate a rotation
ASTestTableView *tableView = [[ASTestTableView alloc] __initWithFrame:CGRectMake(0, 0, 100, 400)
style:UITableViewStylePlain];
ASTableViewFilledDelegate *delegate = [ASTableViewFilledDelegate new];
ASTableViewFilledDataSource *dataSource = [ASTableViewFilledDataSource new];
tableView.asyncDelegate = delegate;
tableView.asyncDataSource = dataSource;
[tableView reloadDataImmediately];
[tableView setNeedsLayout];
[tableView layoutIfNeeded];
for (int section = 0; section < NumberOfSections; section++) {
for (int row = 0; row < NumberOfRowsPerSection; row++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
CGRect rect = [tableView rectForRowAtIndexPath:indexPath];
XCTAssertEqual(rect.size.width, 100); // specified width should be ignored for table
XCTAssertEqual(rect.size.height, 42);
}
}
}
// TODO: Convert this to ARC.
- (void)DISABLED_testTableViewDoesNotRetainItselfAndDelegate
{