Skip to content

Commit 9b7a262

Browse files
committed
Improve notch handling code and better handle edge cases like orientation changes while swiping. cc issue CEWendel#302
1 parent b26444e commit 9b7a262

File tree

1 file changed

+45
-48
lines changed

1 file changed

+45
-48
lines changed

MGSwipeTableCell/MGSwipeTableCell.m

Lines changed: 45 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ -(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;
5655
@end
5756

5857
@implementation MGSwipeButtonsView
@@ -69,28 +68,29 @@ @implementation MGSwipeButtonsView
6968
MGSwipeExpansionLayout _expansionLayout;
7069
CGFloat _expansionOffset;
7170
CGFloat _buttonsDistance;
71+
CGFloat _safeInset;
7272
BOOL _autoHideExpansion;
7373
}
7474

7575
#pragma mark Layout
7676

77-
-(instancetype) initWithButtons:(NSArray*) buttonsArray direction:(MGSwipeDirection) direction differentWidth:(BOOL) differentWidth buttonsDistance:(CGFloat) buttonsDistance safeInset: (CGFloat) safeInset
77+
-(instancetype) initWithButtons:(NSArray*) buttonsArray direction:(MGSwipeDirection) direction differentWidth:(BOOL) differentWidth swipeSettings:(MGSwipeSettings*) settings safeInset: (CGFloat) safeInset
7878
{
7979
CGFloat containerWidth = 0;
8080
CGSize maxSize = CGSizeZero;
8181
UIView* lastButton = [buttonsArray lastObject];
8282
for (UIView * button in buttonsArray) {
83-
containerWidth += button.bounds.size.width + (lastButton == button ? 0 : buttonsDistance);
83+
containerWidth += button.bounds.size.width + (lastButton == button ? 0 : settings.buttonsDistance);
8484
maxSize.width = MAX(maxSize.width, button.bounds.size.width);
8585
maxSize.height = MAX(maxSize.height, button.bounds.size.height);
8686
}
8787
if (!differentWidth) {
88-
containerWidth = maxSize.width * buttonsArray.count + buttonsDistance * (buttonsArray.count - 1);
88+
containerWidth = maxSize.width * buttonsArray.count + settings.buttonsDistance * (buttonsArray.count - 1);
8989
}
9090

9191
if (self = [super initWithFrame:CGRectMake(0, 0, containerWidth + safeInset, maxSize.height)]) {
9292
_fromLeft = direction == MGSwipeDirectionLeftToRight;
93-
_buttonsDistance = buttonsDistance;
93+
_buttonsDistance = settings.buttonsDistance;
9494
_container = [[UIView alloc] initWithFrame:self.bounds];
9595
_container.clipsToBounds = YES;
9696
_container.backgroundColor = [UIColor clearColor];
@@ -111,7 +111,7 @@ -(instancetype) initWithButtons:(NSArray*) buttonsArray direction:(MGSwipeDirect
111111
[_container insertSubview:button atIndex: _fromLeft ? 0: _container.subviews.count];
112112
}
113113
// Expand last button to make it look good with a notch.
114-
if (safeInset > 0 && _buttons.count > 0) {
114+
if (safeInset > 0 && settings.expandLastButtonBySafeAreaInsets && _buttons.count > 0) {
115115
UIView * notchButton = _direction == MGSwipeDirectionRightToLeft ? [_buttons lastObject] : [_buttons firstObject];
116116
notchButton.frame = CGRectMake(0, 0, notchButton.frame.size.width + safeInset, notchButton.frame.size.height);
117117
[self adjustContentEdge:notchButton edgeDelta:safeInset];
@@ -141,22 +141,34 @@ -(void) resetButtons
141141
}
142142
}
143143

144-
-(void) setSafeInset:(CGFloat)safeInset {
144+
-(void) setSafeInset:(CGFloat)safeInset extendEdgeButton:(BOOL) extendEdgeButton {
145145
CGFloat diff = safeInset - _safeInset;
146146
if (diff != 0) {
147147
_safeInset = safeInset;
148148
// 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
149+
if (extendEdgeButton) {
150+
UIView * edgeButton = _direction == MGSwipeDirectionRightToLeft ? [_buttons lastObject] : [_buttons firstObject];
151+
edgeButton.frame = CGRectMake(0, 0, edgeButton.bounds.size.width + diff, edgeButton.frame.size.height);
152+
// Adjust last button content edge (to correctly align the text/icon)
153+
[self adjustContentEdge:edgeButton edgeDelta:diff];
154+
}
155+
154156
CGRect frame = self.frame;
157+
CGAffineTransform transform = self.transform;
158+
self.transform = CGAffineTransformIdentity;
159+
// Adjust container width
155160
frame.size.width += diff;
156-
if (_direction == MGSwipeDirectionRightToLeft) {
157-
frame.origin.x -= diff;
161+
// Adjust position to match width and safeInsets chages
162+
if (_direction == MGSwipeDirectionLeftToRight) {
163+
frame.origin.x = -frame.size.width -safeInset;
158164
}
165+
else {
166+
frame.origin.x = self.superview.bounds.size.width - safeInset;
167+
}
168+
159169
self.frame = frame;
170+
self.transform = transform;
171+
[self resetButtons];
160172
}
161173
}
162174

@@ -763,51 +775,29 @@ -(void) layoutSubviews
763775
if (_swipeView.image && !CGSizeEqualToSize(prevSize, _swipeOverlay.bounds.size)) {
764776
//refresh safeInsets in situations like layout change, orientation change, table resize, etc.
765777
UIEdgeInsets safeInsets = [self getSafeInsets];
766-
// Check last button safe insets
767-
if (_leftView && _leftSwipeSettings.expandLastButtonBySafeAreaInsets) {
778+
// Refresh safe insets
779+
if (_leftView) {
768780
CGFloat width = _leftView.bounds.size.width;
769-
_leftView.safeInset = safeInsets.left;
781+
[_leftView setSafeInset:safeInsets.left extendEdgeButton:_leftSwipeSettings.expandLastButtonBySafeAreaInsets];
770782
if (_swipeOffset > 0 && _leftView.bounds.size.width != width) {
771783
// Adapt offset to the view change size due to safeInsets
772784
_swipeOffset += _leftView.bounds.size.width - width;
773785
}
774786
}
775-
if (_rightView && _rightSwipeSettings.expandLastButtonBySafeAreaInsets) {
787+
if (_rightView) {
776788
CGFloat width = _rightView.bounds.size.width;
777-
_rightView.safeInset = safeInsets.right;
789+
[_rightView setSafeInset:safeInsets.right extendEdgeButton:_rightSwipeSettings.expandLastButtonBySafeAreaInsets];
778790
if (_swipeOffset < 0 && _rightView.bounds.size.width != width) {
779791
// Adapt offset to the view change size due to safeInsets
780792
_swipeOffset -= _rightView.bounds.size.width - width;
781793
}
782794
}
783-
// Check container safe insets
784-
if (safeInsets.left !=0 || safeInsets.right != 0) {
785-
if (_leftView) {
786-
[self changeFrameSafe:_leftView x: -_leftView.bounds.size.width - safeInsets.left];
787-
}
788-
if (_rightView) {
789-
[self changeFrameSafe:_rightView x: _swipeOverlay.bounds.size.width - safeInsets.right];
790-
}
791-
if (_swipeView) {
792-
[self changeFrameSafe:_swipeView x: -safeInsets.left];
793-
}
794-
}
795795
//refresh contentView in situations like layout change, orientation chage, table resize, etc.
796796
[self refreshContentView];
797797
}
798798
}
799799
}
800800

801-
802-
-(void) changeFrameSafe:(UIView *) view x:(CGFloat) x {
803-
CGRect frame = view.frame;
804-
CGAffineTransform transform = view.transform;
805-
view.transform = CGAffineTransformIdentity;
806-
frame.origin.x = x;
807-
view.frame = frame;
808-
view.transform = transform;
809-
}
810-
811801
-(void) fetchButtonsIfNeeded
812802
{
813803
if (_leftButtons.count == 0 && _delegate && [_delegate respondsToSelector:@selector(swipeTableCell:swipeButtonsForDirection:swipeSettings:expansionSettings:)]) {
@@ -827,8 +817,7 @@ -(void) createSwipeViewIfNeeded
827817
_swipeOverlay.hidden = YES;
828818
_swipeOverlay.backgroundColor = [self backgroundColorForSwipe];
829819
_swipeOverlay.layer.zPosition = 10; //force render on top of the contentView;
830-
CGRect bounds = _swipeOverlay.bounds;
831-
_swipeView = [[UIImageView alloc] initWithFrame:CGRectMake(-safeInsets.left, bounds.origin.y, bounds.size.width, bounds.size.height)];
820+
_swipeView = [[UIImageView alloc] initWithFrame:_swipeOverlay.bounds];
832821
_swipeView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
833822
_swipeView.contentMode = UIViewContentModeCenter;
834823
_swipeView.clipsToBounds = YES;
@@ -838,21 +827,28 @@ -(void) createSwipeViewIfNeeded
838827

839828
[self fetchButtonsIfNeeded];
840829
if (!_leftView && _leftButtons.count > 0) {
841-
CGFloat safeInset = _leftSwipeSettings.expandLastButtonBySafeAreaInsets ? safeInsets.left : 0;
842-
_leftView = [[MGSwipeButtonsView alloc] initWithButtons:_leftButtons direction:MGSwipeDirectionLeftToRight differentWidth:_allowsButtonsWithDifferentWidth buttonsDistance:_leftSwipeSettings.buttonsDistance safeInset:safeInset];
830+
_leftView = [[MGSwipeButtonsView alloc] initWithButtons:_leftButtons direction:MGSwipeDirectionLeftToRight differentWidth:_allowsButtonsWithDifferentWidth swipeSettings:_leftSwipeSettings safeInset:safeInsets.left];
843831
_leftView.cell = self;
844832
_leftView.frame = CGRectMake(-_leftView.bounds.size.width - safeInsets.left, _leftSwipeSettings.topMargin, _leftView.bounds.size.width, _swipeOverlay.bounds.size.height - _leftSwipeSettings.topMargin - _leftSwipeSettings.bottomMargin);
845833
_leftView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight;
846834
[_swipeOverlay addSubview:_leftView];
847835
}
848836
if (!_rightView && _rightButtons.count > 0) {
849-
CGFloat safeInset = _rightSwipeSettings.expandLastButtonBySafeAreaInsets ? safeInsets.right : 0;
850-
_rightView = [[MGSwipeButtonsView alloc] initWithButtons:_rightButtons direction:MGSwipeDirectionRightToLeft differentWidth:_allowsButtonsWithDifferentWidth buttonsDistance:_rightSwipeSettings.buttonsDistance safeInset:safeInset];
837+
_rightView = [[MGSwipeButtonsView alloc] initWithButtons:_rightButtons direction:MGSwipeDirectionRightToLeft differentWidth:_allowsButtonsWithDifferentWidth swipeSettings:_rightSwipeSettings safeInset:safeInsets.right];
851838
_rightView.cell = self;
852839
_rightView.frame = CGRectMake(_swipeOverlay.bounds.size.width - safeInsets.right, _rightSwipeSettings.topMargin, _rightView.bounds.size.width, _swipeOverlay.bounds.size.height - _rightSwipeSettings.topMargin - _rightSwipeSettings.bottomMargin);
853840
_rightView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
854841
[_swipeOverlay addSubview:_rightView];
855842
}
843+
844+
// Refresh safeInsets if required
845+
if (_leftView) {
846+
[_leftView setSafeInset:safeInsets.left extendEdgeButton:_leftSwipeSettings.expandLastButtonBySafeAreaInsets];
847+
}
848+
849+
if (_rightView) {
850+
[_rightView setSafeInset:safeInsets.right extendEdgeButton:_rightSwipeSettings.expandLastButtonBySafeAreaInsets];
851+
}
856852
}
857853

858854

@@ -1135,7 +1131,8 @@ - (void)setSwipeOffset:(CGFloat) newOffset;
11351131
}
11361132

11371133
BOOL onlyButtons = activeSettings.onlySwipeButtons;
1138-
_swipeView.transform = CGAffineTransformMakeTranslation(onlyButtons ? 0 : _swipeOffset, 0);
1134+
UIEdgeInsets safeInsets = [self getSafeInsets];
1135+
_swipeView.transform = CGAffineTransformMakeTranslation(onlyButtons ? 0 : _swipeOffset - safeInsets.left, 0);
11391136

11401137
//animate existing buttons
11411138
MGSwipeButtonsView* but[2] = {_leftView, _rightView};

0 commit comments

Comments
 (0)