Skip to content

Commit

Permalink
[BottomSheet] Use setter for sheet view height. (#5125)
Browse files Browse the repository at this point in the history
The method `updateSheetViewHeight` had no inputs and no outputs. Since
its purpose it to assign a new value to
`sheetView.preferredSheetHeight`, it should accept a new value and use
fall-back/defaulting behavior if that value is 0.

Part of #4945
  • Loading branch information
Robert Moore committed Sep 14, 2018
1 parent c906e41 commit b5c0960
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 39 deletions.
21 changes: 13 additions & 8 deletions components/BottomSheet/src/MDCBottomSheetPresentationController.m
Expand Up @@ -108,7 +108,7 @@ - (void)presentationTransitionWillBegin {
[containerView addSubview:_dimmingView];
[containerView addSubview:self.sheetView];

[self updatePreferredSheetHeight];
[self setPreferredSheetHeight:self.presentedViewController.preferredContentSize.height];

// Add tap handler to dismiss the sheet.
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self
Expand Down Expand Up @@ -155,7 +155,7 @@ - (void)preferredContentSizeDidChangeForChildContentContainer:(id<UIContentConta
[super preferredContentSizeDidChangeForChildContentContainer:container];
self.sheetView.frame = [self frameOfPresentedViewInContainerView];
[self.sheetView layoutIfNeeded];
[self updatePreferredSheetHeight];
[self setPreferredSheetHeight:self.presentedViewController.preferredContentSize.height];
}

- (void)viewWillTransitionToSize:(CGSize)size
Expand All @@ -167,19 +167,24 @@ - (void)viewWillTransitionToSize:(CGSize)size
__unused id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
self.sheetView.frame = [self frameOfPresentedViewInContainerView];
[self.sheetView layoutIfNeeded];
[self updatePreferredSheetHeight];
[self setPreferredSheetHeight:self.presentedViewController.preferredContentSize.height];
}
completion:nil];
}

- (void)updatePreferredSheetHeight {
CGFloat preferredContentHeight = self.presentedViewController.preferredContentSize.height;
/**
Sets the new value of @c sheetView.preferredSheetHeight.
If @c preferredContentHeight is non-positive, it will set it to half of sheetView's
frame's height.
@param preferredSheetHeight If positive, the new value for @sheetView.preferredSheetHeight.
*/
- (void)setPreferredSheetHeight:(CGFloat)preferredSheetHeight {
// If |preferredSheetHeight| has not been specified, use half of the current height.
if (MDCCGFloatEqual(preferredContentHeight, 0)) {
preferredContentHeight = MDCRound(CGRectGetHeight(self.sheetView.frame) / 2);
if (MDCCGFloatEqual(preferredSheetHeight, 0)) {
preferredSheetHeight = MDCRound(CGRectGetHeight(self.sheetView.frame) / 2);
}
self.sheetView.preferredSheetHeight = preferredContentHeight;
self.sheetView.preferredSheetHeight = preferredSheetHeight;
}

- (void)dismissPresentedControllerIfNecessary:(UITapGestureRecognizer *)tapRecognizer {
Expand Down
Expand Up @@ -22,21 +22,22 @@
// Exposing internal methods for unit testing
@interface MDCBottomSheetPresentationController (Testing)
@property(nonatomic, strong) MDCSheetContainerView *sheetView;
- (void)updatePreferredSheetHeight;
- (void)setPreferredSheetHeight:(CGFloat)preferredSheetHeight;
@end

/**
A testing double for @c MDCSheetContainerView that allows inspecting the `preferredSheetHeight`
property directly within the test.
A testing double for @c MDCSheetContainerView that allows setting an explicitly-nonstandardized
@c frame value.
@note Although it is possible to retrieve a non-standardized frame or bounds from a UIView object,
UIView will standardize the CGRect passed to @c setFrame:. To aid in testing, we turn
@c frame into a simple get/set property. We still call up to the super implementation of
@c setFrame: in case there are side-effects in UIView.
*/
@interface FakeSheetView : MDCSheetContainerView
@end

@implementation FakeSheetView {
// Although it is possible to retrieve a non-standardized frame or bounds from a UIView object,
// UIView will standardize the CGRect passed to `setFrame`. To aid in testing, we turn `frame`
// into a simple get/set property. We still call up to the super implementation of `setFrame`
// in case there are side-effects in UIView.
CGRect _frame;
}

Expand All @@ -61,67 +62,67 @@ @implementation MDCBottomSheetPresentationControllerPreferredSheetHeightTests
- (void)setUp {
[super setUp];

// The `_sheetView` is both an input and an output to `updatePreferredSheetHeight`. Its frame is
// used to guess the preferredContentHeight of the sheet. Once calculated, it receives an updated
// value for `preferredSheetHeight`.
// The `sheetView` property is both an input and an output to `setPreferredSheetHeight:`. Its
// frame may be used to guess the preferredContentHeight of the sheet. Once calculated, it
// receives an updated value for `preferredSheetHeight`.
self.sheetView = [[FakeSheetView alloc] initWithFrame:CGRectZero
contentView:[[UIView alloc] init]
scrollView:[[UIScrollView alloc] init]];

// Only used as a required `-init` parameter for MDCBottomSheetPresentationController
// Only used as a required `-init` parameters for MDCBottomSheetPresentationController
UIViewController *stubPresentingViewController = [[UIViewController alloc] init];
UIViewController *stubPresentedViewController = [[UIViewController alloc] init];

// Used as an input to `-updatePreferredSheetHeight`. In this test, the value of
// `preferredContentSize` will remain CGSizeZero (the default) and trigger inspection of the sheet
// view's frame instead.
UIViewController *presentedViewController = [[UIViewController alloc] init];

// Although we are testing MDCBottomSheetPresentationController, we only care about the behavior
// of `-updatePreferredSheetHeight` in this test. Because `_sheetView` is an iVar and not a
// property that can be exposed in a testing category, we have to write a subclass that employs
// KVC to allow setting the value of `_sheetView` to our test double.
self.presentationController = [[MDCBottomSheetPresentationController alloc]
initWithPresentedViewController:presentedViewController
initWithPresentedViewController:stubPresentedViewController
presentingViewController:stubPresentingViewController];
self.presentationController.sheetView = self.sheetView;
}

- (void)testUpdatePreferredSheetHeightWhenPresentedVCHasZeroPreferredContentSize {
- (void)testSetPreferredSheetHeightZeroWhenSheetViewHasStandardizedFrame {
// Given
CGFloat sheetFrameHeight = 80;
self.presentationController.presentedViewController.preferredContentSize = CGSizeZero;
self.sheetView.frame = CGRectMake(0, 0, 75, sheetFrameHeight);

// When
[self.presentationController updatePreferredSheetHeight];
[self.presentationController setPreferredSheetHeight:0];

// Then
XCTAssertEqualWithAccuracy(self.sheetView.preferredSheetHeight, sheetFrameHeight / 2, 0.001);
}

- (void)testUpdatePreferredSheetHeightWhenPresentedVCHasZeroPreferredContentSizeUnstandardFrame {
- (void)testSetPreferredSheetHeightZeroWhenSheetViewHasUnstandardizedFrame {
// Given
CGFloat sheetFrameHeight = -80;
self.presentationController.presentedViewController.preferredContentSize = CGSizeZero;
self.sheetView.frame = CGRectMake(75, 80, -75, sheetFrameHeight);

// When
[self.presentationController updatePreferredSheetHeight];
[self.presentationController setPreferredSheetHeight:0];

// Then
XCTAssertEqualWithAccuracy(self.sheetView.preferredSheetHeight,
(CGFloat)fabs(sheetFrameHeight / 2), 0.001);
}

- (void)testUpdatePreferredSheetHeightWhenPresentedVCHasPositivePreferredContentSize {
- (void)testSetPreferredSheetHeightPositiveValue {
// Given
CGFloat preferredSheetHeight = 120;
self.presentationController.presentedViewController.preferredContentSize =
CGSizeMake(100, preferredSheetHeight);
self.sheetView.frame = CGRectMake(0, 0, 75, 80);

// When
[self.presentationController updatePreferredSheetHeight];
[self.presentationController setPreferredSheetHeight:preferredSheetHeight];

// Then
XCTAssertEqualWithAccuracy(self.sheetView.preferredSheetHeight, preferredSheetHeight, 0.001);
}

- (void)testSetPreferredSheetHeightNegativeValue {
// Given
CGFloat preferredSheetHeight = -120;
self.sheetView.frame = CGRectMake(0, 0, 75, -80);

// When
[self.presentationController setPreferredSheetHeight:preferredSheetHeight];

// Then
XCTAssertEqualWithAccuracy(self.sheetView.preferredSheetHeight, preferredSheetHeight, 0.001);
Expand Down

0 comments on commit b5c0960

Please sign in to comment.