Before this change, it was never possible to interact with the navigationController property in a pushed view controller's viewDidLoad property when using MDCAppBarNavigationController. This behavior is surprising for folks using UINavigationController, which does allow you to access navigationController from within viewDidLoad.
This expectation is an anti-pattern (e.g. viewDidLoad is never guaranteed to be invoked after a view controller has been pushed onto a navigationController stack), but the goal of MDCAppBarNavigationController is to provide a drop-in replacement for UINavigationController so our intent is to align behaviors, even if they're not necessarily for the right reasons.
All that being said, the change introduced in this CL simply swaps the ordering of pushing the view controller and injecting the AppBar, such that the injection now happens after the super implementation of pushViewController has been invoked. This allows the viewDidLoad logic to be invoked after navigationController has been initialized on the view controller.
The reason we were doing it the other way before was so that the AppBar could intercept the relevant status bar appearance events. We work around that requirement in this change by invoking setNeedsStatusBarAppearanceUpdate and setNeedsUpdateOfHomeIndicatorAutoHidden immediately after injecting the AppBar.
PiperOrigin-RevId: 313410464
Before this change, it was never possible to interact with the navigationController property in a pushed view controller's viewDidLoad property when using MDCAppBarNavigationController. This behavior is surprising for folks using UINavigationController, which does allow you to access navigationController from within viewDidLoad.
This expectation is an anti-pattern (e.g. viewDidLoad is never guaranteed to be invoked after a view controller has been pushed onto a navigationController stack), but the goal of MDCAppBarNavigationController is to provide a drop-in replacement for UINavigationController so our intent is to align behaviors, even if they're not necessarily for the right reasons.
All that being said, the change introduced in this CL simply swaps the ordering of pushing the view controller and injecting the AppBar, such that the injection now happens after the super implementation of pushViewController has been invoked. This allows the viewDidLoad logic to be invoked after navigationController has been initialized on the view controller.
The reason we were doing it the other way before was so that the AppBar could intercept the relevant status bar appearance events. We work around that requirement in this change by invoking setNeedsStatusBarAppearanceUpdate and setNeedsUpdateOfHomeIndicatorAutoHidden immediately after injecting the AppBar.
PiperOrigin-RevId: 311342757
## The bug
Repro steps:
1. Open MDCDragons on an iPhone with a notch.
2. Open App Bar -> Presented hidden.
3. Present the App Bar.
4. Observe.
Expected behavior:
- The AppBar is completely hidden.
Actual behavior:
- The AppBar is partially hidden.
## Root cause analysis
When the FlexibleHeader is hidden using shiftHeaderOffScreenAnimated:, the expectation is that the header will be shifted entirely off-screen. If this method is invoked before the FlexibleHeader is attached to a window hierarchy, then the offset applied to shift the header off-screen may not correctly include the necessary safe area insets to hide the header fully.
When flexibleHeaderSafeAreaTopSafeAreaInsetDidChange was being invoked after the safe area insets were made available to the FlexibleHeader, we were not taking into consideration whether the FlexibleHeader was supposed to be hidden which resulted in the FlexibleHeader getting stuck in a partially hidden state.
## The fix
In flexibleHeaderSafeAreaTopSafeAreaInsetDidChange, we now check whether the FlexibleHeader wants to be hidden and, if it does (and we're not already animating it), we immediately snap the FlexibleHeader to the new necessary offset.
PiperOrigin-RevId: 311104051
The example was reusing the same view controller instance after each presentation, which made it difficult to consistently test the same buggy behavior.
PiperOrigin-RevId: 310980123
This example demonstrates a bug where the AppBar does not appear to respect shiftHeaderOffScreenAnimated: when the shiftBehavior is set to hideable.
PiperOrigin-RevId: 310898136
This example doesn't actually manage its own app bar; it only presents one. This fixes a bug where the example did not show a navigation bar at all.
PiperOrigin-RevId: 310870101
The prior names of composed vs inherited didn't meaningfully translate to the intended purpose of the two view controllers, which is to provide harnesses within which the flexible header can be placed either as a child or as a sibling to its tracking scroll view. This distinction is important because the flexible header behaves differently when it is a child of its tracking scroll view, as is the case when using UITableViewController.
PiperOrigin-RevId: 310869953
The problem occurs because the transform of the flexible header view's Y positioning based on the contentOffset is not done in coordination with the scroll view animation.
Similarly to the jumping effect in https://github.com/material-components/material-components-ios/pull/9872 , we coordinate the transform when VoiceOver is on with the scroll view content offset change.
This was tested with the Expandable Cells example and the glitch is fixed.
PiperOrigin-RevId: 304352119
This example demonstrates a bug where the AppBar will "jump" with the following repro steps:
1. Open the example.
2. Tap any cell.
3. Scroll the tapped cell until it is above the AppBar.
4. Tap any other cell.
Expected behavior: the AppBar stays in place while the cell heights change.
Actual behavior: the AppBar "jumps" up and then animates back into place.
This is pre-work for https://github.com/material-components/material-components-ios/issues/9853
This new flag allows view controllers to control the visibility of their app bar via the standard UINavigationController setNavigationBarHidden: APIs. When enabled, calls to these APIs will result in the AppBar's visibility being adjusted.
Closes https://github.com/material-components/material-components-ios/issues/5185
Context:
Due to changes in the Swift runtime over the past years, methods that are considered "optional" in Objective-C need to have @objc annotations in order for Objective-C to be able to perform `respondsToSelector:` invocations.
Problem:
Many of our examples had not annotated their `catalogShouldHideNavigation` methods with the `@objc` annotation, causing the Catalog to wrap the examples in a container app bar view controller. The reason most of these examples would implement `catalogShouldHideNavigation` is because they are managing their own navigation (e.g. to demonstrate AppBar functionality), so this would often result in duplicate AppBars appearing in the example.
The fix:
All `catalogShouldHideNavigation` Swift methods have been annotated with `@objc`.
Fixes https://github.com/material-components/material-components-ios/issues/7576
Fixes https://github.com/material-components/material-components-ios/issues/7578
As part of #7510 we need to remove our usage of the typography themer and color themer within our examples. This removes the usages of both for all swift examples.
We need to add @objc annotations to colorScheme and typographyScheme instances in our Swift examples, because we moved to Swift 4.2, the respondsToSelector won't find `setColorScheme:` and `setTypographyScheme:` setters otherwise.
This is a follow up PR for #7166 adds @objc annotations to Swift catalogMetadata() methods, because the Swift 4 compiler no longer attempts to infer what methods should be visible to Objective-C. As a result of this change in the compiler, no Swift examples were showing up in Dragons after #7166. See this article: https://useyourloaf.com/blog/objc-warnings-upgrading-to-swift-4/ for additional context.
This refactors the "simple" example table view controllers used in a bunch of these examples into two types: a "composed" one which creates its own table view and an "inherited" one which subclasses UITableViewController. They behave differently, so this makes that explicit and also reduces some code duplication.
{MDC iOS} No longer using `-init` for Color Scheme.
Based on the discussions in go/mdc-ios-theming, we should not use the `-init` default initializer. Instead, we should use an explicit set of defaults.
Search regex: '\[\[MDCSemanticColorScheme alloc\] init\]'
Replacing all non-integral, single-precision floating point literals with double-precision values explicitly cast to CGFloat. For example, `0.1f` should become `(CGFloat)0.1`.
Regex used:
```
([0-9]*\.)([0-9]*?)([1-9]+)([0-9]*?)[fF]
```
PiperOrigin-RevId: 220683126
[MDC Swift] Add guards for Swift 4.2+
On Xcode 10, using Tulsi, the unit test target cannot be built because much of the Swift code does
not have the correct syntax for Swift 4.2+. Adding pragmas to allow continued support for Xcode
9.4.2 and Xcode 10.
PiperOrigin-RevId: 220399935
I did an audit of the Catalog app to track down screens with an incorrect status bar color and the ones that I found are:
* AppBar -> Presented (This example does not use the app theme so I was able to set the style directly)
* AppBar -> Wrapped
* BottomAppBar
Additionally, I found that changing the Catalog theme from black to another color (and vice-versa) resulted in the status bar being incorrect until the next page navigation. So I created a fix for this too.
Closes#3778