MDCFlexibleHeaderView

@interface MDCFlexibleHeaderView : UIView

MDCFlexibleHeaderView tracks the content offset of a scroll view and adjusts its size and position according to a configurable set of behaviors.

UIScrollViewDelegate forwarding

This view relies on you informing it of certain UIScrollViewDelegate events as they happen. These events are listed in the UIScrollViewDelegate events section.

  • Informs the receiver that the tracking scroll view’s contentOffset has changed.

    Must be called from the trackingScrollView delegate’s UIScrollViewDelegate::scrollViewDidScroll: implementor.

    Note

    Do not invoke this method if self.observesTrackingScrollViewScrollEvents is YES.

    Declaration

    Objective-C

    - (void)trackingScrollViewDidScroll;
  • Informs the receiver that the tracking scroll view’s adjustedContentInset has changed.

    Must be called from the trackingScrollView delegate’s UIScrollViewDelegate::scrollViewDidChangeAdjustedContentInset: implementor.

    Note

    Do not invoke this method if self.observesTrackingScrollViewScrollEvents is YES.

    Declaration

    Objective-C

    - (void)trackingScrollViewDidChangeAdjustedContentInset:
        (nullable UIScrollView *)trackingScrollView;
  • Informs the receiver that the tracking scroll view might be about to change to a new tracking scroll view.

    Declaration

    Objective-C

    - (void)trackingScrollWillChangeToScrollView:
        (nullable UIScrollView *)scrollView;
  • Returns a Boolean value indicating whether the status bar should be visible.

    Must be called by the owning UIViewController’s -prefersStatusBarHidden.

    Declaration

    Objective-C

    @property (readonly, nonatomic) BOOL prefersStatusBarHidden;
  • Informs the receiver that the interface orientation is about to change.

    Must be called from UIViewController::willRotateToInterfaceOrientation:duration:.

    Declaration

    Objective-C

    - (void)interfaceOrientationWillChange;
  • Informs the receiver that the interface orientation is in the process of changing.

    Must be called from UIViewController::willAnimateRotationToInterfaceOrientation:duration:.

    Declaration

    Objective-C

    - (void)interfaceOrientationIsChanging;
  • Informs the receiver that the interface orientation has changed.

    Must be called from UIViewController::didRotateFromInterfaceOrientation:.

    Declaration

    Objective-C

    - (void)interfaceOrientationDidChange;
  • Informs the receiver that the owning view controller’s size will change.

    Must be called from UIViewController::viewWillTransitionToSize:withTransitionCoordinator: on apps targeting iOS 8 and onward.

    Declaration

    Objective-C

    - (void)viewWillTransitionToSize:(CGSize)size
           withTransitionCoordinator:
               (nonnull id<UIViewControllerTransitionCoordinator>)coordinator;
  • Must be called by a client that wishes to update the content insets of the tracking scroll view.

    Not using this method can lead to undefined behavior due to the flexible header view assuming that a certain amount of additional content insets have been provided to the tracking scroll view.

    The provided block will be executed after the flexible header has removed its modifications to the tracking scroll view. Upon completion of the block, the flexible header will re-inject these modifications into the new content insets and ensure that the content offset doesn’t change due to the new content insets.

    Declaration

    Objective-C

    - (void)changeContentInsets:
        (nonnull MDCFlexibleHeaderChangeContentInsetsBlock)block;
  • Forwards any tap events made to the provided view on to the tracking scroll view.

    Views will only forward their taps if they are a subview of this header view and are interactive.

    Touch forwarding does not apply to subviews of the provided view.

    Declaration

    Objective-C

    - (void)forwardTouchEventsForView:(nonnull UIView *)view;
  • Stops forwarding tap events on the given view to the tracking scroll view.

    Declaration

    Objective-C

    - (void)stopForwardingTouchEventsForView:(nonnull UIView *)view;
  • Returns the current scroll phase of the flexible header.

    There are three mutually-exclusive scroll phases: shifting, collapsing, and over-extending. Whichever phase the header view is in governs what scrollPhaseValue and scrollPhasePercentage represent.

    This and the related scrollPhase properties are only valid immediately after a call to -trackingScrollViewDidScroll.

    Declaration

    Objective-C

    @property (readonly, nonatomic) MDCFlexibleHeaderScrollPhase scrollPhase;
  • A value in screen points denoting the absolute position within the current scroll phase.

    The range for each phase follows:

    • Shifting: [0, minimumHeight)
    • Collapsing: [minimumHeight, maximumHeight)
    • Over-extending: [maximumHeight, +inf)

    Declaration

    Objective-C

    @property (readonly, nonatomic) CGFloat scrollPhaseValue;
  • A normalized value denoting the position within the current scroll phase.

    The meaning of the percentage for each phase follows:

    • Shifting: 0 is unshifted, 1.0 is fully shifted off-screen
    • Collapsing: 0 == minimumHeight, 1.0 == maximumHeight
    • Over-extending: 1.0 height == maximumHeight, every additional 1.0 is one maximumHeight unit

    Note that a single percentage does not necessarily have equal weight between the three phases, so you should not use this value for any behavior that is active across any two phases; use scrollPhaseValue instead.

    Declaration

    Objective-C

    @property (readonly, nonatomic) CGFloat scrollPhasePercentage;
  • The minimum height that this header can shrink to.

    See minMaxHeightIncludesSafeArea to learn how this number is used when the Safe Area changes.

    If you change the value of this property and the maximumHeight of the receiver is below the new minimumHeight, maximumHeight will be adjusted to match the new minimum value.

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic) CGFloat minimumHeight;
  • The maximum height that this header can expand to.

    See minMaxHeightIncludesSafeArea to learn how this number is used when the Safe Area changes.

    If you change the value of this property and the minimumHeight of the receiver is above the new maximumHeight, minimumHeight will be adjusted to match the new maximumHeight.

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic) CGFloat maximumHeight;
  • When this is enabled, the flexible header will assume that minimumHeight and maximumHeight both include the Safe Area top inset. For example, a header whose maximum content height should be 200 might set 220 (200 + 20) as the maximumHeight. Notice that if this is enabled and you’re setting minimumHeight and or maximumHeight, the flexible header won’t automatically adjust its size to account for changes to the Safe Area, as the values provided already include a hardcoded inset.

    When this is disabled, the flexible header will assume that the provided minimumHeight and maximumHeight do not include the Safe Area top inset. For example, a header whose maximum content height should be 200 would set 200 as the maximumHeight, and the flexible header will take care of adjusting itself to account for Safe Area changes internally.

    Clients are recommended to set this to NO, and set the min and max heights to values that don’t include the status bar or Safe Area insets.

    Default is YES.

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic) BOOL minMaxHeightIncludesSafeArea;
  • A layout guide that equates to the top safe area inset of the flexible header view.

    Use this layout guide to position subviews in the flexible header in relation to the top safe area insets.

    This object is intended to be used as a constraint item.

    Declaration

    Objective-C

    @property (readonly, nonatomic, nonnull) id topSafeAreaGuide;
  • Whether or not the header view is allowed to expand past its maximum height when the tracking scroll view has been dragged past its top edge.

    Default: YES

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic) BOOL canOverExtend;
  • < The visible shadow opacity. Default: 0.4

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic) float visibleShadowOpacity;
  • Whether or not shadow opacity (if using the default shadow layer) should be reset to 0 when trackingScrollView is set to nil. If the flexible header view is created without ever setting trackingScrollView, it always has 0 opacity for the default shadow layer regardless of the value of this flag. If trackingScrollView is ever set, then this flag enables resetting the shadow opacity back to 0 when trackingScrollView is set to nil.

    Default: NO, but we are planning to change it to YES very soon, so all clients should set this property to YES.

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic)
        BOOL resetShadowAfterTrackingScrollViewIsReset;
  • The scroll view whose content offset affects the height/offset of the flexible header view.

    The receiver will inject the maximum height of the header view into the top component of the tracking scroll view’s content insets. This ensures that there is enough space in the top insets to fit the header. This should be taken into account when working with the tracking scroll view’s content insets.

    Importantly, if you wish to make changes to the tracking scroll view’s content insets after it has been registered to a flexible header view, you must do so from within a -changeContentInsets: invocation on the flexible header view.

    The tracking scroll view is weakly held so that we don’t unintentionally keep the scroll view around any longer than it needs to be. Doing so could get into tricky situations where the view controller didn’t nil out the scroll view’s delegate in dealloc and UIScrollView’s non-weak delegate points to a dead object.

    Declaration

    Objective-C

    @property (readwrite, nonatomic, nullable) UIScrollView *trackingScrollView;
  • Whether to automatically observe the trackingScrollView’s content offset changes.

    When enabled, the header view will observe the contentOffset property of the tracking scroll view and react to changes accordingly.

    You must not forward any scroll view events to the header view if this property is enabled. Any attempts to do so will result in an assertion.

    If you attempt to enable this property when shiftBehavior is set to anything other than MDCFlexibleHeaderShiftBehaviorDisabled, an assertion will be thrown. If you intend to use any shifting behavior you must manually forward the necessary scroll view events.

    Note

    If you enable this property and you support iOS 10.3 or below, you are responsible for explicitly nilling out the tracking scroll view before it is deallocated. This is not required if your minimum OS is iOS 11 or above. Failure to nil out the tracking scroll view may lead to runtime crashes due to dangling observers on the tracking scroll view. Most commonly, the tracking scroll view can be nil’d out in the view controller’s dealloc method. An example of the error you might see is: An instance of class UITableView was deallocated while key value observers were still registered with it.

    Default: NO

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic)
        BOOL observesTrackingScrollViewScrollEvents;
  • Whether or not the header is floating in front of an infinite stream of content.

    Enabling this behavior will cause the header to always appear to be floating in front of the content in Material space. This behavior should only be enabled for content that has no top edge, e.g. an infinite stream of vertical content.

    Default: NO

    Declaration

    Objective-C

    @property (getter=isInFrontOfInfiniteContent, assign, readwrite, nonatomic)
        BOOL inFrontOfInfiniteContent;
  • Whether or not the receiver is shared by many scroll views, such as in a tabbed interface with many columns of content.

    Default: NO

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic) BOOL sharedWithManyScrollViews;
  • If enabled, the trackingScrollView doesn’t adjust the content inset when its contentInsetAdjustmentBehavior is set to be UIScrollViewContentInsetAdjustmentNever.

    Default: NO

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic)
        BOOL disableContentInsetAdjustmentWhenContentInsetAdjustmentBehaviorIsNever;
  • The behavior of the header in response to the user interacting with the tracking scroll view.

    Note

    If self.observesTrackingScrollViewScrollEvents is YES, then this property can only be MDCFlexibleHeaderShiftBehaviorDisabled. Attempts to set shiftBehavior to any other value if self.observesTrackingScrollViewScrollEvents is YES will result in an assertion being thrown.
    See more

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic)
        MDCFlexibleHeaderShiftBehavior shiftBehavior;
  • If shiftBehavior is enabled, this property affects the manner in which the Header reappears when pulling content down in the tracking scroll view.

    Ignored if shiftBehavior == MDCFlexibleHeaderShiftBehaviorDisabled.

    Default: MDCFlexibleHeaderContentImportanceDefault

    See more

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic)
        MDCFlexibleHeaderContentImportance headerContentImportance;
  • When enabled, the header view will prioritize shifting off-screen and collapsing over shifting on-screen and expanding.

    This should only be enabled when the user is scrubbing the tracking scroll view, i.e. they’re able to jump large distances using a scrubber control.

    See more

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic) BOOL trackingScrollViewIsBeingScrubbed;
  • Whether this header view’s content is translucent/transparent. Provides a hint to status bar rendering, to correctly display contents scrolling under the status bar as it shifts on/off screen.

    Default: NO

    See more

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic) BOOL contentIsTranslucent;
  • A hint stating whether or not the operating system’s status bar frame can ever overlap the header’s frame.

    This property is enabled by default with the expectation that the flexible header will primarily be used in full-screen settings on the phone.

    Disabling this property informs the flexible header that it should not concern itself with the status bar in any manner. shiftBehavior .EnabledWithStatusBar will be treated simply as .Enabled in this case.

    Default: YES

    See more

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic) BOOL statusBarHintCanOverlapHeader;
  • Hides the view by changing its alpha when the header shifts. Note that this only happens when the header shifting behavior is set to MDCFlexibleHeaderShiftBehaviorEnabled.

    Declaration

    Objective-C

    - (void)hideViewWhenShifted:(nonnull UIView *)view;
  • Stops hiding the view when the header shifts.

    Declaration

    Objective-C

    - (void)stopHidingViewWhenShifted:(nonnull UIView *)view;
  • Asks the receiver to bring the header on-screen if it’s currently off-screen.

    Declaration

    Objective-C

    - (void)shiftHeaderOnScreenAnimated:(BOOL)animated;
  • Asks the receiver to take the header off-screen if it’s currently on-screen.

    Declaration

    Objective-C

    - (void)shiftHeaderOffScreenAnimated:(BOOL)animated;
  • Informs the receiver that the tracking scroll view has finished dragging.

    Must be called from the trackingScrollView delegate’s UIScrollViewDelegate::scrollViewDidEndDragging:willDecelerate: implementor.

    Note

    Do not invoke this method if self.observesTrackingScrollViewScrollEvents is YES.

    Declaration

    Objective-C

    - (void)trackingScrollViewDidEndDraggingWillDecelerate:(BOOL)willDecelerate;
  • Informs the receiver that the tracking scroll view has finished decelerating.

    Must be called from the trackingScrollView delegate’s UIScrollViewDelegate::scrollViewDidEndDecelerating: implementor.

    Note

    Do not invoke this method if self.observesTrackingScrollViewScrollEvents is YES.

    Declaration

    Objective-C

    - (void)trackingScrollViewDidEndDecelerating;
  • Potentially modifies the target content offset in order to ensure that the header view is either visible or hidden depending on its current position.

    Must be called from the trackingScrollView delegate’s -scrollViewWillEndDragging:withVelocity:targetContentOffset: implementor.

    If your scroll view is vertically paging then this method will do nothing. You should also disable hidesStatusBarWhenCollapsed.

    Note

    Do not invoke this method if self.observesTrackingScrollViewScrollEvents is YES.

    Declaration

    Objective-C

    - (BOOL)trackingScrollViewWillEndDraggingWithVelocity:(CGPoint)velocity
                                      targetContentOffset:(inout nonnull CGPoint *)
                                                              targetContentOffset;

    Return Value

    A Boolean value indicating whether the target content offset was modified.

  • Deprecated. Please register views directly to the flexible header.

    See more

    Declaration

    Objective-C

    @property (readwrite, strong, nonatomic, nonnull) UIView *contentView;