We recommend using `initWithDefaults` and we should follow the recommendation. This change removes all usage of `init` within MDC components in order to let us remove that initializer from the public surface.
PiperOrigin-RevId: 302958447
MDCAppBarViewController has a new delegate property with an optional method, `-appBarViewControllerAccessibilityPerformEscape:`. This method can be implemented to override the default behavior of MDCAppBarViewController when an accessibilityPerformEscape event is received.
Closes https://github.com/material-components/material-components-ios/issues/9576
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
Part of https://github.com/material-components/material-components-ios/issues/8677.
This API helps to reduce the complexity of calculating minimumHeight and maximumHeight on FlexibleHeader when user wants to update the app bar height based on header stack view.
This flag is required to be set during configuration stage. The reset behavior (turning back to NO) was not implemented because it would require adding API to minMaxHeight class and all configuration needs be to be set before flexible header is used. This feature can be added if needed.
closes https://github.com/material-components/material-components-ios/issues/8252
## Context
Error occurs when testing using Bazel.
```
Test Case '-[components_AppBar_unit_test_swift_sources.MDCAppBarNavigationControllerTests testSettingAViewControllerInjectsAnAppBar]' started.
Child process terminated with signal 11: Segmentation fault
```
The Flexible needs an API so clients can hook-in to trait collection changes. This additionally passes the flexibleHeader as a parameter so clients can modify the flexible header within the block.
When AppBars are injected into other view controllers, there should be a mechanism by which clients can respond to trait collections changes in those app bars.
Part of #7849
Because `MDCAppBarViewController` is often injected into other view controllers, setting these blocks on the injector (*e.g.*, `MDCAppBarNavigationController`) means that the eventual app bar view controller object isn't actually available when the block is written. Instead of assuming access to the object receiving a trait collection change, the block can receive that object directly as a parameter.
Part of #7849
Follow-up to #7851
## Context
As part of our work to move away from themer objects and onto theming extension we need to graduate all of our components theming extensions to the MaterialComponents pod.
## The fix
This PR updates the AppBar theming extension to the MaterialComponents pod, as well as updating examples and unit test.
## Context
In working on #7159 I noticed that the umbrella header for the _theming extension_ for [`MDCAppBar`](https://github.com/material-components/material-components-ios/tree/develop/components/AppBar) does not match our convention which is `Material<#componentName>+Theming.h`.
## The fix
Rename this file to use the convention outlined in the design doc. This was a replace of `MaterialTheming.h` -> `Theming.h`. This was done as a move operation and then the unit test were updated.
## Why breaking
This is a breaking change since we are renaming the umbrella header. This will break clients using swift and ObjectiveC.
#### Swift
```diff
- import MaterialComponents.MaterialAppBar_MaterialTheming
+ import MaterialComponents.MaterialAppBar_Theming
```
#### ObjC
```diff
- #import "MaterialAppBar+MaterialTheming.h"
+ #import "MaterialAppBar+Theming.h"
```
MDCAppBarNavigationController's tracking scroll view detection uses a depth-first view traversal algorithm to find a tracking scroll view candidate. This logic works most of the time, but there are cases where this algorithm picks up the wrong tracking scroll view. For example, if a horizontally scrollable tab bar has been added to the view controller's view and there is no other scroll view then the tab bar will be picked as the tracking scroll view.
Prior to this change, our recommendation to clients that encountered cases like this was to opt out of the MDCAppBarNavigationController app bar injection logic by creating and managing a custom app bar instance.
After this change, clients will be able to customize the tracking scroll view detection logic. This will reduce the need to opt out of the app bar navigation controller's injection behavior.
This change helps mitigate https://github.com/material-components/material-components-ios/issues/5344
Googlers: this change was instigated by a client integration in [cl/241070130](http://cl/241070130).
[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
Removes the need to copy-paste stanzas from other files anymore as we'll rely on #4478 to generate the correct stanza for us instead.
This was an automated change generated by running a find-and-replace regular expression:
```
/\*
Copyright ([0-9]+)-present the Material Components for iOS authors\. All Rights Reserved\.
Licensed under the Apache License, Version 2\.0 \(the "License"\);
you may not use this file except in compliance with the License\.
You may obtain a copy of the License at
http://www\.apache\.org/licenses/LICENSE-2\.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.
See the License for the specific language governing permissions and
limitations under the License\.
\*/
```
```
/\*
Copyright ([0-9]+)-present the Material Components for iOS authors\. All Rights Reserved\.
Licensed under the Apache License, Version 2\.0 \(the "License"\);
you may not use this file except in compliance with the License\.
You may obtain a copy of the License at
http://www\.apache\.org/licenses/LICENSE-2\.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.
See the License for the specific language governing permissions and
limitations under the License\.
\*/
```
```
/\*
Copyright ([0-9]+)-present the Material Components for iOS authors\. All Rights Reserved\.
Licensed under the Apache License, Version 2\.0 \(the "License"\);
you may not use this file except in compliance with the License\.
You may obtain a copy of the License at
http://www\.apache\.org/licenses/LICENSE-2\.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.
See the License for the specific language governing permissions and
limitations under the License\.
\*/
```
```
// Copyright $1-present the Material Components for iOS authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
```
2645cc539f6a17e8ecb729a1b5b7997be24f07fa changed the app bar initialization such that it would no longer touch self.view during initialization. This means that viewDidLoad now only gets called when the client adds the app bar view controller's view to the view hierarchy.
A client was depending on the header stack view's `topBar` property being set to the navigation bar immediately after initialization, so the above change broke this contract for them.
This change moves this logic into the app bar view controller's initialization phase so that the header stack view is fully configured upon initialization, renewing the contract that the client team expected.
Added a unit test to ensure that we maintain this contract into the future.
Prior to this change, view controllers that were provided to an MDCAppBarNavigationController via the setViewControllers:animated: API would not have an app bar injected.
After this change, MDCAppBarNavigationController will properly inject an app bar into the set view controllers, as expected.
Closes https://github.com/material-components/material-components-ios/issues/4735
This includes two changes that increase the likelihood of us detecting existing App Bars in a pushed view controller:
1. Some clients manage view controllers in viewDidLoad. We're already accessing .view in the injection logic, but we were not doing so until after the check for an App Bar. We now fetch the view before we check the view controller hierarchy, giving the pushed view controller an opportunity to configure itself before we check for an existing App Bar.
2. There are cases within our own catalog where we have a "nested dolls" of view controllers, i.e. an App Bar in a container inside another view controller. We were not recursing our pre-existing flexible header view controller check, meaning we would miss these deeply-nested view controller cases. This change adds a recursive step to the view controller check.
I verified that the added test fails prior to this change and succeeds after this change.
## Screenshots
Before:

After:

This new API provides a dead-simple integration path for adding an App Bar to an app. I expect this API to be the dominant way for clients to integrate with the App Bar component.
The existing mechanisms of creating an App Bar (injection and wrapping with a container) are still feasible, and both methods can be used interchangeably with the navigation controller. If the navigation controller detects that a flexible header is already present in a pushed view controller it will not add an App Bar.
As part of this change I also explored simply providing a UINavigationControllerDelegate that responded to the willShow event. This approach had the following limitations:
- I did not see a clear path to properly supporting status bar styles. Properly supporting status bar styles requires that somebody, at some point in the hierarchy, is able to route status bar style queries to the flexible header view controller. A delegate lacks this facility.
- The willShow event is fired after the viewWillAppear: event fires, meaning we had to simulate the invocation of this on the injected view controllers. This required that we recursively traverse the App Bar's flexible header view controller and its children (in order to also notify the app bar's internal view controller of the viewWillAppear event). I was concerned that the requirement for this patch would lead to unexpected behavior down the road.
As a result of encountering the above limitations, I pivoted to providing a concrete UINavigationController subclass. I have been hesitant to provide this class for some time because of a very colorful history of supporting similar APIs over the last half decade. At this point, however, I feel that the number of behavioral APIs we've landed allow us to implement the navigation controller with minimal logic, keeping the implementation as simple as possible.
Notably, users of the new app bar navigation controller API will benefit from all injected App Bars having all of the most "modern" APIs enabled because this is a new API. This means that the scroll view's content offset is observed, it respects safe area insets based on the context, and the content view controller's top layout guide / safe area insets accurately reflect the space consumed by the flexible header.
Example usage:
```swift
let navigationController = MDCAppBarNavigationController()
navigationController.pushViewController(viewController, animated: true)
```
If you want to be able to theme the injected App Bar then you'll need to implement the navigation controller's delegate and respond to the willAdd events, like so:
```swift
// MARK: MDCAppBarNavigationControllerInjectorDelegate
func appBarNavigationController(_ navigationController: MDCAppBarNavigationController,
willAdd appBar: MDCAppBar,
asChildOf viewController: UIViewController) {
MDCAppBarColorThemer.applySemanticColorScheme(AppTheme.globalTheme.colorScheme, to: appBar)
MDCAppBarTypographyThemer.applyTypographyScheme(AppTheme.globalTheme.typographyScheme,
to: appBar)
}
```
Closes https://github.com/material-components/material-components-ios/issues/268
This behavior enables the similarly-named behavior added to the Flexible Header in bb245597d8895a78c346c76f7d0986d7a993ad12. In addition to allowing the flexible header's min/max height to use the contextual safe area insets, the App Bar will use the flexible header view's top safe area guide to position its header view (rather than using MDCDeviceSafeAreaInsets(), which we want to remove).
This change enables the new behavior in the App Bar examples and in the MDCCatalog node list view controller.
Closes https://github.com/material-components/material-components-ios/issues/4104
This ensures that we're not duplicating the sub-component themer logic.
Also added a unit test to ensure that the desired mappings do take effect.
Closes pivotal story: https://www.pivotaltracker.com/story/show/156438987
* Support NSSecureCoding for App bar.
* subclasses should be have secure encoding as well.
* Adding NSSecureCoding to objects under MDCAppBar.
* added more tests for encoding MDCAppBar
* MDC_#702 - Start to implement accessibility configurator
* MDC_#702 - Implemented configurator method to modify accessibility colors to app bar and implemented example use
* MDC_#702 - Updated examples
* MDC_#702 - Updated naming convention
* MDC_#702 - Readability
* MDC_#702 - Updated pod spec to include new class MDCAppBarAccessibilityEnforcer, started adding tests, updated examples to new use class
* MDC_#702 - Stubbed out tests
* MDC_#702 - Re-implemented MDCAppBarAccessibilityEnforcer as object within AppBar component
* Filled in additional tests
* MDC_#702 - Updated method name
* MDC_#702 - Updated test cases
* MDC_#702 - Update added test to Swift 3.0
* [AppBar] - Update accessibility mutator class
* [AppBar] - Updated text selection in mutator method
* [AppBar] - Removed init method per comment
* [AppBar] - Updated colors in AppBar demo examples