Skip to content

Commit a0ccf6c

Browse files
committed
Expand the first or last button width to make appearance looks good with a notch (e.g. iPhone X). Fixes issue CEWendel#302.
1 parent 33cc837 commit a0ccf6c

File tree

2 files changed

+71
-5
lines changed

2 files changed

+71
-5
lines changed

MGSwipeTableCell/MGSwipeTableCell.h

+2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ typedef NS_ENUM(NSInteger, MGSwipeEasingFunction) {
8888
@property (nonatomic, assign) CGFloat bottomMargin;
8989
/** Distance between the buttons. Default value : 0 */
9090
@property (nonatomic, assign) CGFloat buttonsDistance;
91+
/** If true, expands the last button length by safeAreaInsets. Useful for devices with a notch (e.g. iPhone X) */
92+
@property (nonatomic, assign) BOOL expandLastButtonBySafeAreaInsets;
9193

9294
/** Animation settings when the swipe buttons are shown */
9395
@property (nonatomic, strong, nonnull) MGSwipeAnimation * showAnimation;

MGSwipeTableCell/MGSwipeTableCell.m

+69-5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ -(UIView *) hitTest:(CGPoint)point withEvent:(UIEvent *)event
5252
@interface MGSwipeButtonsView : UIView
5353
@property (nonatomic, weak) MGSwipeTableCell * cell;
5454
@property (nonatomic, strong) UIColor * backgroundColorCopy;
55+
@property (nonatomic, assign) CGFloat safeInset;
5556
@end
5657

5758
@implementation MGSwipeButtonsView
@@ -64,6 +65,7 @@ @implementation MGSwipeButtonsView
6465
UIView * _expansionBackground;
6566
UIView * _expansionBackgroundAnimated;
6667
CGRect _expandedButtonBoundsCopy;
68+
MGSwipeDirection _direction;
6769
MGSwipeExpansionLayout _expansionLayout;
6870
CGFloat _expansionOffset;
6971
CGFloat _buttonsDistance;
@@ -72,7 +74,7 @@ @implementation MGSwipeButtonsView
7274

7375
#pragma mark Layout
7476

75-
-(instancetype) initWithButtons:(NSArray*) buttonsArray direction:(MGSwipeDirection) direction differentWidth:(BOOL) differentWidth buttonsDistance:(CGFloat) buttonsDistance
77+
-(instancetype) initWithButtons:(NSArray*) buttonsArray direction:(MGSwipeDirection) direction differentWidth:(BOOL) differentWidth buttonsDistance:(CGFloat) buttonsDistance safeInset: (CGFloat) safeInset
7678
{
7779
CGFloat containerWidth = 0;
7880
CGSize maxSize = CGSizeZero;
@@ -86,12 +88,14 @@ -(instancetype) initWithButtons:(NSArray*) buttonsArray direction:(MGSwipeDirect
8688
containerWidth = maxSize.width * buttonsArray.count + buttonsDistance * (buttonsArray.count - 1);
8789
}
8890

89-
if (self = [super initWithFrame:CGRectMake(0, 0, containerWidth, maxSize.height)]) {
91+
if (self = [super initWithFrame:CGRectMake(0, 0, containerWidth + safeInset, maxSize.height)]) {
9092
_fromLeft = direction == MGSwipeDirectionLeftToRight;
9193
_buttonsDistance = buttonsDistance;
9294
_container = [[UIView alloc] initWithFrame:self.bounds];
9395
_container.clipsToBounds = YES;
9496
_container.backgroundColor = [UIColor clearColor];
97+
_direction = direction;
98+
_safeInset = safeInset;
9599
[self addSubview:_container];
96100
_buttons = _fromLeft ? buttonsArray: [[buttonsArray reverseObjectEnumerator] allObjects];
97101
for (UIView * button in _buttons) {
@@ -106,6 +110,12 @@ -(instancetype) initWithButtons:(NSArray*) buttonsArray direction:(MGSwipeDirect
106110
button.autoresizingMask = UIViewAutoresizingFlexibleHeight;
107111
[_container insertSubview:button atIndex: _fromLeft ? 0: _container.subviews.count];
108112
}
113+
// Expand last button to make it look good with a notch.
114+
if (safeInset > 0 && _buttons.count > 0) {
115+
UIView * notchButton = _direction == MGSwipeDirectionRightToLeft ? [_buttons lastObject] : [_buttons firstObject];
116+
notchButton.frame = CGRectMake(0, 0, notchButton.frame.size.width + safeInset, notchButton.frame.size.height);
117+
[self adjustContentEdge:notchButton edgeDelta:safeInset];
118+
}
109119
[self resetButtons];
110120
}
111121
return self;
@@ -131,6 +141,39 @@ -(void) resetButtons
131141
}
132142
}
133143

144+
-(void) setSafeInset:(CGFloat)safeInset {
145+
CGFloat diff = safeInset - _safeInset;
146+
if (diff != 0) {
147+
_safeInset = safeInset;
148+
// Adjust last button length (fit the safeInset to make it look good with a notch)
149+
UIView * notchButton = _direction == MGSwipeDirectionRightToLeft ? [_buttons lastObject] : [_buttons firstObject];
150+
notchButton.frame = CGRectMake(0, 0, notchButton.bounds.size.width + diff, notchButton.frame.size.height);
151+
// Adjust last button content edge (to correctly align the text/icon)
152+
[self adjustContentEdge:notchButton edgeDelta:diff];
153+
// Adjust container size
154+
CGRect frame = self.frame;
155+
frame.size.width += diff;
156+
if (_direction == MGSwipeDirectionRightToLeft) {
157+
frame.origin.x -= diff;
158+
}
159+
self.frame = frame;
160+
}
161+
}
162+
163+
-(void) adjustContentEdge: (UIView *) view edgeDelta:(CGFloat) delta {
164+
if ([view isKindOfClass:[UIButton class]]) {
165+
UIButton * btn = (UIButton *) view;
166+
UIEdgeInsets contentInsets = btn.contentEdgeInsets;
167+
if (_direction == MGSwipeDirectionRightToLeft) {
168+
contentInsets.right += delta;
169+
}
170+
else {
171+
contentInsets.left += delta;
172+
}
173+
btn.contentEdgeInsets = contentInsets;
174+
}
175+
}
176+
134177
-(void) layoutExpansion: (CGFloat) offset
135178
{
136179
_expansionOffset = offset;
@@ -406,6 +449,7 @@ -(instancetype) init
406449
self.transition = MGSwipeTransitionBorder;
407450
self.threshold = 0.5;
408451
self.offset = 0;
452+
self.expandLastButtonBySafeAreaInsets = YES;
409453
self.keepButtonsSwiped = YES;
410454
self.enableSwipeBounces = YES;
411455
self.swipeBounceRate = 1.0;
@@ -717,8 +761,26 @@ -(void) layoutSubviews
717761
_swipeOverlay.frame = CGRectMake(0, 0, self.bounds.size.width, self.contentView.bounds.size.height);
718762
[self fixRegionAndAccesoryViews];
719763
if (_swipeView.image && !CGSizeEqualToSize(prevSize, _swipeOverlay.bounds.size)) {
720-
//refresh safeInsets in situations like layout change, orientation chage, table resize, etc.
764+
//refresh safeInsets in situations like layout change, orientation change, table resize, etc.
721765
UIEdgeInsets safeInsets = [self getSafeInsets];
766+
// Check last button safe insets
767+
if (_leftView && _leftSwipeSettings.expandLastButtonBySafeAreaInsets) {
768+
CGFloat width = _leftView.bounds.size.width;
769+
_leftView.safeInset = safeInsets.left;
770+
if (_swipeOffset > 0 && _leftView.bounds.size.width != width) {
771+
// Adapt offset to the view change size due to safeInsets
772+
_swipeOffset += _leftView.bounds.size.width - width;
773+
}
774+
}
775+
if (_rightView && _rightSwipeSettings.expandLastButtonBySafeAreaInsets) {
776+
CGFloat width = _rightView.bounds.size.width;
777+
_rightView.safeInset = safeInsets.right;
778+
if (_swipeOffset < 0 && _rightView.bounds.size.width != width) {
779+
// Adapt offset to the view change size due to safeInsets
780+
_swipeOffset -= _rightView.bounds.size.width - width;
781+
}
782+
}
783+
// Check container safe insets
722784
if (safeInsets.left !=0 || safeInsets.right != 0) {
723785
if (_leftView) {
724786
[self changeFrameSafe:_leftView x: -_leftView.bounds.size.width - safeInsets.left];
@@ -776,14 +838,16 @@ -(void) createSwipeViewIfNeeded
776838

777839
[self fetchButtonsIfNeeded];
778840
if (!_leftView && _leftButtons.count > 0) {
779-
_leftView = [[MGSwipeButtonsView alloc] initWithButtons:_leftButtons direction:MGSwipeDirectionLeftToRight differentWidth:_allowsButtonsWithDifferentWidth buttonsDistance:_leftSwipeSettings.buttonsDistance];
841+
CGFloat safeInset = _leftSwipeSettings.expandLastButtonBySafeAreaInsets ? safeInsets.left : 0;
842+
_leftView = [[MGSwipeButtonsView alloc] initWithButtons:_leftButtons direction:MGSwipeDirectionLeftToRight differentWidth:_allowsButtonsWithDifferentWidth buttonsDistance:_leftSwipeSettings.buttonsDistance safeInset:safeInset];
780843
_leftView.cell = self;
781844
_leftView.frame = CGRectMake(-_leftView.bounds.size.width - safeInsets.left, _leftSwipeSettings.topMargin, _leftView.bounds.size.width, _swipeOverlay.bounds.size.height - _leftSwipeSettings.topMargin - _leftSwipeSettings.bottomMargin);
782845
_leftView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight;
783846
[_swipeOverlay addSubview:_leftView];
784847
}
785848
if (!_rightView && _rightButtons.count > 0) {
786-
_rightView = [[MGSwipeButtonsView alloc] initWithButtons:_rightButtons direction:MGSwipeDirectionRightToLeft differentWidth:_allowsButtonsWithDifferentWidth buttonsDistance:_rightSwipeSettings.buttonsDistance];
849+
CGFloat safeInset = _rightSwipeSettings.expandLastButtonBySafeAreaInsets ? safeInsets.right : 0;
850+
_rightView = [[MGSwipeButtonsView alloc] initWithButtons:_rightButtons direction:MGSwipeDirectionRightToLeft differentWidth:_allowsButtonsWithDifferentWidth buttonsDistance:_rightSwipeSettings.buttonsDistance safeInset:safeInset];
787851
_rightView.cell = self;
788852
_rightView.frame = CGRectMake(_swipeOverlay.bounds.size.width - safeInsets.right, _rightSwipeSettings.topMargin, _rightView.bounds.size.width, _swipeOverlay.bounds.size.height - _rightSwipeSettings.topMargin - _rightSwipeSettings.bottomMargin);
789853
_rightView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;

0 commit comments

Comments
 (0)