TextureGroup / Texture

Smooth asynchronous user interfaces for iOS apps.
https://texturegroup.org/
Other
8.02k stars 1.3k forks source link

ASTableNode custom width #182

Open garrettmoon opened 7 years ago

garrettmoon commented 7 years ago

From @psk239 on January 31, 2017 18:9

I am using an ASViewController to display an ASTableNode and I would like for the width to be different for an iPad screen vs an iPhone screen (i.e. 540 pt max width).

I posted on #general in the Slack channel and was told to try style.preferredSize either in the init or viewDidLoad and nothing really changed, the ASTableNode is still full width.

Here is sample code of what I am trying:

@implementation SampleViewControllerClass //<- this is a subclass of ASViewController

- (instancetype)init {

    _tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain];

     // This isn't the actual value, just trying to see if anything changes
    _tableNode.style.preferredSize = CGSizeMake(100.0f, 400.0f);

    if (self = [super initWithNode:_tableNode]) {
        // Some config code here
    }

    return self;
}

@end

I've also tried setting tableNode.style.preferredLayoutSize, tableNode.style.maxWidth, and tableNode.style.width in both the init and viewDidLoad methods and nothing changed. Would appreciate any help.

Copied from original issue: facebookarchive/AsyncDisplayKit#2957

garrettmoon commented 7 years ago

From @maicki on January 31, 2017 18:11

@psk239 Hey! Try not to add the table node as root node to the view controller. Use an ASDisplayNode as root node and add the table node as subnode to it.

garrettmoon commented 7 years ago

From @psk239 on January 31, 2017 18:28

@maicki that worked with the following code:

@implementation SampleViewControllerClass //<- this is a subclass of ASViewController

- (instancetype)init {

    ASDisplayNode *displayNode = [[ASDisplayNode alloc] init];

    _tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain];
    [displayNode addSubnode:_tableNode];

    if (self = [super initWithNode:displayNode]) {
        // Some config code here
    }

    return self;
}

- (void)viewDidLoad {

    [super viewDidLoad];
    _tableNode.view.frame = CGRectMake(0.0f, 0.0f, 540.0f, self.view.bounds.size.height);
}

@end

but the following code didn't work:

- (instancetype)initWithTeacher:(nonnull CDKTeacher *)loggedInTeacher school:(nonnull CDKSchool *)school {

    ASDisplayNode *displayNode = [[ASDisplayNode alloc] init];

    _tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain];
    // this doesn't work
    _tableNode.style.maxWidth = ASDimensionMake(540.0f);
    // This doesn't work either
    _tableNode.style.minWidth = ASDimensionMake(20.0f);

    [displayNode addSubnode:_tableNode];

    if (self = [super initWithNode:displayNode]) {

    }
    return self;
}

- (void)viewDidLoad {

    [super viewDidLoad];
    // This didn't work either
    _tableNode.style.preferredSize = CGSizeMake(540.0f, self.view.bounds.size.height);

    // This does work but I would rather not have to handle frame calculation for rotation
    _tableNode.view.frame = CGRectMake(...);
}
garrettmoon commented 7 years ago

From @psk239 on February 1, 2017 1:41

This is what I ended up doing, wasn't the best solution but it works:

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -  Initiallizers
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

- (instancetype)init {

    _tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain];

    if (IS_TABLET) {
        ASDisplayNode *displayNode = [[ASDisplayNode alloc] init];

        [displayNode addSubnode:_tableNode];

        if (self = [super initWithNode:displayNode]) {

        }
        return self;
    }

    if (self = [super initWithNode:_tableNode]) {

    }

    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    if (IS_TABLET) {
        CGSize adjustedSize = CGSizeMake(self.view.bounds.size.width - self.tableNodeInsets.right, self.view.bounds.size.height - self.tableNodeInsets.bottom);

        _tableNode.frame = [self tableNodeFrameToSize:adjustedSize];

      //This is a work in progress, currently trying to figure out how to expand draggable area
        _tableNode.hitTestSlop = UIEdgeInsetsMake(0.0f, -400.0f, 0.0f, -400.0f);

        self.node.clipsToBounds = NO;
        self.node.hitTestSlop = UIEdgeInsetsMake(0.0f, -400.0f, 0.0f, -400.0f);
    }

    _tableNode.view.showsVerticalScrollIndicator = NO;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - UIViewController overwritten methods
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {

    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    if (IS_TABLET) {

        CGSize adjustedSize = CGSizeMake(size.width - self.tableNodeInsets.right, size.height - self.tableNodeInsets.bottom);

        CGRect finishingRect = [self tableNodeFrameToSize:adjustedSize];

        BOOL isAnimated = coordinator.animated;

        if (!CGRectEqualToRect(finishingRect, _tableNode.frame)) {

            if (isAnimated) {

                [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {

                    _tableNode.frame = finishingRect;

                } completion:nil];

            } else {
                _tableNode.frame = finishingRect;
            }
        }
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - Setters
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

- (void)setTableNodeInsets:(UIEdgeInsets)tableNodeInsets {
    _tableNodeInsets = tableNodeInsets;
    CGSize adjustedSize = CGSizeMake(self.view.bounds.size.width - _tableNodeInsets.right, self.view.bounds.size.height - _tableNodeInsets.bottom);

    _tableNode.frame = [self tableNodeFrameToSize:adjustedSize];
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - Private Methods
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

- (CGSize)tableNodeSizeToViewSize:(CGSize)size {

    CGSize retSize = size;

    if (size.width > kCDBCommonStoryWallMaxWidth) {
        retSize.width = kCDBCommonStoryWallMaxWidth;
    }

    return retSize;
}

- (CGRect)tableNodeFrameToSize:(CGSize)parentSize {

    CGSize retSize = [self tableNodeSizeToViewSize:parentSize];

    CGFloat xValue = fabs((parentSize.width - retSize.width)) / 2.0f + self.tableNodeInsets.left;
    CGFloat yValue = self.tableNodeInsets.top;

    return CGRectMake(xValue, yValue, retSize.width, retSize.height);
}

@end
garrettmoon commented 7 years ago

From @hannahmbanana on February 9, 2017 21:31

@maicki - When using style.minWidth and style.maxWidth, does the node need a need a preferred size set as well? Is it possible to use minWidth and maxWidth only?

garrettmoon commented 7 years ago

From @hannahmbanana on February 9, 2017 21:34

@psk239 - Would you be willing to put together a quick sample project showing this? Thanks!

garrettmoon commented 7 years ago

From @psk239 on February 17, 2017 2:30

@hannahmbanana Here you go LINK