I'm trying to add a detail view to SWTableViewCell.
The constraints are tied to all elements of the cell, and I'm trying to get a detailed view to animate from the table view cell.
Photo of what is now versus what is desired:
I've been spending a lot of time experimenting blindly, and trying to do a deep dive in manual auto-layout. I haven't been able to identify how to get the desired result. I attempted to transfer all the contents to another subview, however, removing elements from self did not solve this.
Code with the constraints:
- (void)initializer { layoutUpdating = NO; // Set up scroll view that will host our cell content self.cellScrollView = [[SWCellScrollView alloc] init]; self.cellScrollView.translatesAutoresizingMaskIntoConstraints = NO; self.cellScrollView.delegate = self; self.cellScrollView.showsHorizontalScrollIndicator = NO; self.cellScrollView.scrollsToTop = NO; self.cellScrollView.scrollEnabled = YES; _contentCellView = [[UIView alloc] init]; [self.cellScrollView addSubview:_contentCellView]; // Add the cell scroll view to the cell UIView *contentViewParent = self; UIView *clipViewParent = self.cellScrollView; if (![NSStringFromClass([[self.subviews objectAtIndex:0] class]) isEqualToString:kTableViewCellContentView]) { // iOS 7 contentViewParent = [self.subviews objectAtIndex:0]; clipViewParent = self; } NSArray *cellSubviews = [contentViewParent subviews]; [self insertSubview:self.cellScrollView atIndex:0]; for (UIView *subview in cellSubviews) { [_contentCellView addSubview:subview]; } // Set scroll view to perpetually have same frame as self. Specifying relative to superview doesn't work, since the latter UITableViewCellScrollView has different behaviour. [self addConstraints:@[ [NSLayoutConstraint constraintWithItem:self.cellScrollView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:self.cellScrollView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:self.cellScrollView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:self.cellScrollView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0], ]]; self.tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewTapped:)]; self.tapGestureRecognizer.cancelsTouchesInView = NO; self.tapGestureRecognizer.delegate = self; [self.cellScrollView addGestureRecognizer:self.tapGestureRecognizer]; self.longPressGestureRecognizer = [[SWLongPressGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewPressed:)]; self.longPressGestureRecognizer.cancelsTouchesInView = NO; self.longPressGestureRecognizer.minimumPressDuration = kLongPressMinimumDuration; self.longPressGestureRecognizer.delegate = self; [self.cellScrollView addGestureRecognizer:self.longPressGestureRecognizer]; // Create the left and right utility button views, as well as vanilla UIViews in which to embed them. We can manipulate the latter in order to effect clipping according to scroll position. // Such an approach is necessary in order for the utility views to sit on top to get taps, as well as allow the backgroundColor (and private UITableViewCellBackgroundView) to work properly. self.leftUtilityClipView = [[UIView alloc] init]; self.leftUtilityClipConstraint = [NSLayoutConstraint constraintWithItem:self.leftUtilityClipView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0]; self.leftUtilityButtonsView = [[SWUtilityButtonView alloc] initWithUtilityButtons:nil parentCell:self utilityButtonSelector:@selector(leftUtilityButtonHandler:)]; self.rightUtilityClipView = [[UIView alloc] initWithFrame:self.bounds]; self.rightUtilityClipConstraint = [NSLayoutConstraint constraintWithItem:self.rightUtilityClipView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]; self.rightUtilityButtonsView = [[SWUtilityButtonView alloc] initWithUtilityButtons:nil parentCell:self utilityButtonSelector:@selector(rightUtilityButtonHandler:)]; UIView *clipViews[] = { self.rightUtilityClipView, self.leftUtilityClipView }; NSLayoutConstraint *clipConstraints[] = { self.rightUtilityClipConstraint, self.leftUtilityClipConstraint }; UIView *buttonViews[] = { self.rightUtilityButtonsView, self.leftUtilityButtonsView }; NSLayoutAttribute alignmentAttributes[] = { NSLayoutAttributeRight, NSLayoutAttributeLeft }; for (NSUInteger i = 0; i < 2; ++i) { UIView *clipView = clipViews[i]; NSLayoutConstraint *clipConstraint = clipConstraints[i]; UIView *buttonView = buttonViews[i]; NSLayoutAttribute alignmentAttribute = alignmentAttributes[i]; clipConstraint.priority = UILayoutPriorityDefaultHigh; clipView.translatesAutoresizingMaskIntoConstraints = NO; clipView.clipsToBounds = YES; [clipViewParent addSubview:clipView]; [self addConstraints:@[ // Pin the clipping view to the appropriate outer edges of the cell. [NSLayoutConstraint constraintWithItem:clipView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:clipView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:clipView attribute:alignmentAttribute relatedBy:NSLayoutRelationEqual toItem:self attribute:alignmentAttribute multiplier:1.0 constant:0.0], clipConstraint, ]]; [clipView addSubview:buttonView]; [self addConstraints:@[ // Pin the button view to the appropriate outer edges of its clipping view. [NSLayoutConstraint constraintWithItem:buttonView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:clipView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:buttonView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:clipView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:buttonView attribute:alignmentAttribute relatedBy:NSLayoutRelationEqual toItem:clipView attribute:alignmentAttribute multiplier:1.0 constant:0.0], // Constrain the maximum button width so that at least a button's worth of contentView is left visible. (The button view will shrink accordingly.) [NSLayoutConstraint constraintWithItem:buttonView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationLessThanOrEqual toItem:self.contentView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:-kUtilityButtonWidthDefault], ]]; } self.utilityView = [[UIView alloc] initWithFrame: CGRectMake(0, self.bounds.size.height, self.bounds.size.width, 0)]; [self.utilityView setBackgroundColor: [UIColor darkGrayColor]]; [self addSubview: self.utilityView]; [self sendSubviewToBack: self.utilityView]; }
The table view calls a public method within beginUpdates
and endUpdates
, and the animation is UIView animateWithDuration:
.
The view hierarchy:
<UIWindow: 0x7f85cfe11840; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x608000242d60>; layer = <UIWindowLayer: 0x60800002c300>> | <UIView: 0x7f85cff08bc0; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x618000027040>> | | <UIView: 0x7f85cfc03ce0; frame = (0 0; 414 66); layer = <CALayer: 0x60000002e4c0>> | | | <LBHamburgerButton: 0x7f85cfc0cd20; baseClass = UIButton; frame = (314 10; 50 50); opaque = NO; layer = <CALayer: 0x60000002e620>> | | | | <CAShapeLayer: 0x60800022cce0> (layer) | | | | <CAShapeLayer: 0x60800022d840> (layer) | | | | <CAShapeLayer: 0x60800022d920> (layer) | | <UIView: 0x7f85cfc08e70; frame = (0 66; 414 670); layer = <CALayer: 0x60000002e5a0>> | | | <UIView: 0x7f85cff16790; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x61800002c240>> | | | | <iCarousel: 0x7f85cff16930; frame = (0 10; 414 80); autoresize = W+H; layer = <CALayer: 0x61800002c260>> | | | | | <UIView: 0x7f85cff16f10; frame = (0 0; 414 80); autoresize = W+H; gestureRecognizers = <NSArray: 0x618000241f80>; layer = <CALayer: 0x61800002c280>> | | | | | | <UIView: 0x7f85cfc13a70; frame = (108.998 -0.000800016; 196.004 80.0016); layer = <CALayer: 0x60000002fea0>> | | | | | | | <UILabel: 0x7f85cff1ebb0; frame = (0 0; 196 80); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x6180002819a0>> | | | | | | <UIView: 0x7f85cff24150; frame = (-125.656 -18.322; 225.889 116.644); userInteractionEnabled = NO; layer = <CALayer: 0x6180000279a0>> | | | | | | | <UILabel: 0x7f85cfd1af40; frame = (0 0; 196 80); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x610000488660>> | | | | | | <UIView: 0x7f85cfc1c280; frame = (313.767 -18.322; 225.889 116.644); userInteractionEnabled = NO; layer = <CALayer: 0x6000000309e0>> | | | | | | | <UILabel: 0x7f85cfd1b1c0; frame = (0 0; 196 80); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x610000489380>> | | | | | | <UIView: 0x7f85cfc19630; frame = (-444.013 -99.6275; 306.865 279.255); hidden = YES; userInteractionEnabled = NO; layer = <CALayer: 0x600000030540>> | | | | | | | <UILabel: 0x7f85cfe29790; frame = (0 0; 196 80); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60800009aae0>> | | | | <UIView: 0x7f85cff17590; frame = (0 95; 414 60); layer = <CALayer: 0x61800002c3e0>> | | | | | <UIButton: 0x7f85cff17730; frame = (0 0; 60 60); opaque = NO; layer = <CALayer: 0x61800002c440>> | | | | | <UIButton: 0x7f85cff179f0; frame = (354 0; 60 60); opaque = NO; tag = 1; layer = <CALayer: 0x61800002c460>> | | | | | <UILabel: 0x7f85cff17cb0; frame = (107 0; 200 60); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x6180002873f0>> | | | | <UIView: 0x7f85cff189d0; frame = (0 158; 414 512); layer = <CALayer: 0x61800002c620>> | | | | | <UITableView: 0x7f85d1842000; frame = (0 0; 414 512); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x618000242c70>; layer = <CALayer: 0x61800002cba0>; contentOffset: {0, 0}; contentSize: {414, 8160.0099999997765}> | | | | | | <UITableViewWrapperView: 0x7f85d1845a00; frame = (0 0; 414 512); gestureRecognizers = <NSArray: 0x618000242fa0>; layer = <CALayer: 0x61800002cca0>; contentOffset: {0, 0}; contentSize: {414, 512}> | | | | | | | <CurrentOrdersTableViewCell: 0x7f85d1821800; baseClass = UITableViewCell; frame = (0 640; 414 80); hidden = YES; autoresize = W; layer = <CALayer: 0x618000031400>> | | | | | | | | <UIView: 0x7f85cff23fb0; frame = (0 44; 320 0); layer = <CALayer: 0x618000032540>> | | | | | | | | <SWCellScrollView: 0x7f85d1876000; baseClass = UIScrollView; frame = (0 0; 414 80); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x618000249450>; layer = <CALayer: 0x6180000314c0>; contentOffset: {90, 0}; contentSize: {594, 80}> | | | | | | | | | <UIView: 0x7f85cff22ac0; frame = (90 0; 414 79.6667); layer = <CALayer: 0x6180000315c0>> | | | | | | | | | | <UITableViewCellContentView: 0x7f85cff224a0; frame = (0 0; 414 79.6667); gestureRecognizers = <NSArray: 0x618000249300>; layer = <CALayer: 0x618000031440>> | | | | | | | | | | | <UILabel: 0x7f85cff25470; frame = (20 0; 66.8 12); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x61800028aaf0>> | | | | | | | | | | | <UILabel: 0x7f85cff256f0; frame = (96.8 0; 66.8 12); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x61800028ab90>> | | | | | | | | | | | <UILabel: 0x7f85cff25970; frame = (173.6 0; 66.8 12); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x61800028ac30>> | | | | | | | | | | | <UILabel: 0x7f85cff25bf0; frame = (250.4 0; 66.8 12); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x61800028acd0>> | | | | | | | | | | | <UILabel: 0x7f85cff25e70; frame = (327.2 0; 66.8 12); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x61800028ad70>> | | | | | | | | | | | <UILabel: 0x7f85cff260f0; frame = (20 15; 66.8 12); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x61800028ae10>> | | | | | | | | | | | <UILabel: 0x7f85cfe264a0; frame = (96.8 15; 66.8 12); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60800009ba30>> | | | | | | | | | | | <UILabel: 0x7f85cfe26720; frame = (173.6 15; 66.8 12); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60800009bad0>> | | | | | | | | | | | <UILabel: 0x7f85cfe269a0; frame = (250.4 15; 66.8 12); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60800009bb70>> | | | | | | | | | | | <UILabel: 0x7f85cfe270e0; frame = (327.2 15; 66.8 12); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60800009bc10>> | | | | | | | | | <UIView: 0x7f85cff23a10; frame = (504 0; 0 80); clipsToBounds = YES; hidden = YES; layer = <CALayer: 0x618000031c00>> | | | | | | | | | | <SWUtilityButtonView: 0x7f85cff23bb0; frame = (-90 0; 90 80); layer = <CALayer: 0x618000031c60>> | | | | | | | | | | | <UIButton: 0x7f85cfe28a20; frame = (0 0; 90 80); opaque = NO; gestureRecognizers = <NSArray: 0x60800024c2d0>; layer = <CALayer: 0x608000234900>> | | | | | | | | | | | | <UIButtonLabel: 0x7f85cfe28ce0; frame = (11 29.3333; 68.3333 21.6667); opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60800009c570>> | | | | | | | | | <UIView: 0x7f85cff236b0; frame = (90 0; 0 80); clipsToBounds = YES; hidden = YES; layer = <CALayer: 0x618000031b40>> | | | | | | | | | | <SWUtilityButtonView: 0x7f85cff23850; frame = (0 0; 90 80); layer = <CALayer: 0x618000031ba0>> | | | | | | | | | | | <UIButton: 0x7f85cfe27360; frame = (0 0; 90 80); opaque = NO; gestureRecognizers = <NSArray: 0x60800024aa70>; layer = <CALayer: 0x6080002334e0>> | | | | | | | | | | | | <UIButtonLabel: 0x7f85cfe27620; frame = (8.66667 29.3333; 73 21.6667); opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60800009bd00>> | | | | | | | | | <UIImageView: 0x7f85cfe290c0; frame = (498.667 3; 2.33333 74); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x608000234f20>> | | | | | | | | <_UITableViewCellSeparatorView: 0x7f85cfe28680; frame = (0 79.6667; 414 0.333333); layer = <CALayer: 0x6080002347a0>> | | | | | | |
0 comments:
Post a Comment