From b5c096009f604061fb10a2208a0445bffb5df2b9 Mon Sep 17 00:00:00 2001 From: Robert Moore Date: Fri, 14 Sep 2018 11:17:48 -0400 Subject: [PATCH] [BottomSheet] Use setter for sheet view height. (#5125) 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 --- .../MDCBottomSheetPresentationController.m | 21 ++++--- ...ationControllerPreferredSheetHeightTests.m | 63 ++++++++++--------- 2 files changed, 45 insertions(+), 39 deletions(-) diff --git a/components/BottomSheet/src/MDCBottomSheetPresentationController.m b/components/BottomSheet/src/MDCBottomSheetPresentationController.m index 2b1b2879c71..b18fd3e9aed 100644 --- a/components/BottomSheet/src/MDCBottomSheetPresentationController.m +++ b/components/BottomSheet/src/MDCBottomSheetPresentationController.m @@ -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 @@ -155,7 +155,7 @@ - (void)preferredContentSizeDidChangeForChildContentContainer:(id _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 { diff --git a/components/BottomSheet/tests/unit/MDCBottomSheetPresentationControllerPreferredSheetHeightTests.m b/components/BottomSheet/tests/unit/MDCBottomSheetPresentationControllerPreferredSheetHeightTests.m index 88afe988349..f5e20166ffa 100644 --- a/components/BottomSheet/tests/unit/MDCBottomSheetPresentationControllerPreferredSheetHeightTests.m +++ b/components/BottomSheet/tests/unit/MDCBottomSheetPresentationControllerPreferredSheetHeightTests.m @@ -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; } @@ -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);