mirror of
https://github.com/material-components/material-components-ios.git
synced 2026-02-20 08:27:32 +08:00
This PR makes it so that Tabs examples use the theming extension instead of the themer. Related to #9061. Related to #9063. Related to #9062.
165 lines
5.8 KiB
Swift
165 lines
5.8 KiB
Swift
// Copyright 2017-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.
|
|
|
|
import UIKit
|
|
import CoreGraphics
|
|
|
|
import MaterialComponents.MaterialAppBar_ColorThemer
|
|
import MaterialComponents.MaterialAppBar_TypographyThemer
|
|
import MaterialComponents.MaterialButtons
|
|
import MaterialComponents.MaterialContainerScheme
|
|
import MaterialComponents.MaterialTabs
|
|
import MaterialComponents.MaterialTabs_Theming
|
|
|
|
class TabBarIndicatorTemplateExample: UIViewController {
|
|
|
|
// MARK: Properties
|
|
var alignment: MDCTabBarAlignment {
|
|
get {
|
|
return tabBar.alignment
|
|
}
|
|
set(newAlignment) {
|
|
tabBar.setAlignment(newAlignment, animated: true)
|
|
}
|
|
}
|
|
|
|
var itemAppearance: MDCTabBarItemAppearance {
|
|
get {
|
|
return tabBar.itemAppearance
|
|
}
|
|
set {
|
|
tabBar.itemAppearance = newValue
|
|
|
|
// itemAppearance affects the height of the tab bar.
|
|
appBarViewController.headerStackView.setNeedsLayout()
|
|
}
|
|
}
|
|
|
|
lazy var alignmentButton: MDCButton = self.makeAlignmentButton()
|
|
lazy var appearanceButton: MDCButton = self.makeAppearanceButton()
|
|
lazy var appBarViewController: MDCAppBarViewController = self.makeAppBar()
|
|
@objc var containerScheme = MDCContainerScheme()
|
|
|
|
lazy var tabBar: MDCTabBar = {
|
|
let tabBar = MDCTabBar()
|
|
tabBar.alignment = .justified
|
|
|
|
tabBar.applyPrimaryTheme(withScheme: containerScheme)
|
|
|
|
let bundle = Bundle(for: TabBarIndicatorTemplateExample.self)
|
|
let info = UIImage.init(named: "TabBarDemo_ic_info", in: bundle, compatibleWith:nil)
|
|
let star = UIImage.init(named: "TabBarDemo_ic_star", in: bundle, compatibleWith:nil)
|
|
tabBar.items = [
|
|
UITabBarItem(title: "Fly", image: info, tag:0),
|
|
UITabBarItem(title: "Sleep", image: star, tag:0),
|
|
UITabBarItem(title: "Eat", image: info, tag:0),
|
|
]
|
|
|
|
// Set lighter ink so the indicator animation is more visible.
|
|
tabBar.inkColor = UIColor.white.withAlphaComponent(0.15)
|
|
|
|
tabBar.itemAppearance = .titles
|
|
|
|
// Configure custom title fonts
|
|
tabBar.selectedItemTitleFont = UIFont.boldSystemFont(ofSize: 12)
|
|
tabBar.unselectedItemTitleFont = UIFont.systemFont(ofSize: 12)
|
|
|
|
// Configure custom indicator template
|
|
tabBar.selectionIndicatorTemplate = IndicatorTemplate()
|
|
return tabBar
|
|
}()
|
|
|
|
// MARK: Methods
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
setupExampleViews()
|
|
|
|
alignmentButton.addTarget(
|
|
self,
|
|
action:#selector(changeAlignmentDidTouch(sender:)),
|
|
for: .touchUpInside)
|
|
appearanceButton.addTarget(
|
|
self,
|
|
action: #selector(changeAppearance),
|
|
for: .touchUpInside)
|
|
|
|
MDCAppBarColorThemer.applyColorScheme(containerScheme.colorScheme, to: self.appBarViewController)
|
|
MDCAppBarTypographyThemer.applyTypographyScheme(containerScheme.typographyScheme,
|
|
to: self.appBarViewController)
|
|
}
|
|
|
|
@objc func changeAlignmentDidTouch(sender: UIButton) {
|
|
let sheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
|
sheet.popoverPresentationController?.sourceView = self.alignmentButton
|
|
sheet.popoverPresentationController?.sourceRect = self.alignmentButton.bounds
|
|
sheet.addAction(UIAlertAction(title: "Leading", style: .default, handler: { _ in
|
|
self.alignment = .leading
|
|
}))
|
|
sheet.addAction(UIAlertAction(title: "Center", style: .default, handler: { _ in
|
|
self.alignment = .center
|
|
}))
|
|
sheet.addAction(UIAlertAction(title: "Justified", style: .default, handler: { _ in
|
|
self.alignment = .justified
|
|
}))
|
|
sheet.addAction(UIAlertAction(title: "Selected Center", style: .default, handler: { _ in
|
|
self.alignment = .centerSelected
|
|
}))
|
|
present(sheet, animated: true, completion:nil)
|
|
}
|
|
|
|
@objc func changeAppearance(fromSender sender: UIButton) {
|
|
let sheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
|
sheet.popoverPresentationController?.sourceView = self.appearanceButton
|
|
sheet.popoverPresentationController?.sourceRect = self.appearanceButton.bounds
|
|
sheet.addAction(UIAlertAction(title: "Titles", style: .default, handler: { _ in
|
|
self.itemAppearance = .titles
|
|
}))
|
|
sheet.addAction(UIAlertAction(title: "Images", style: .default, handler: { _ in
|
|
self.itemAppearance = .images
|
|
}))
|
|
sheet.addAction(UIAlertAction(title: "Titled Images", style: .default, handler: { _ in
|
|
self.itemAppearance = .titledImages
|
|
}))
|
|
present(sheet, animated: true, completion:nil)
|
|
}
|
|
|
|
// MARK: Private
|
|
|
|
class IndicatorTemplate: NSObject, MDCTabBarIndicatorTemplate {
|
|
func indicatorAttributes(
|
|
for context: MDCTabBarIndicatorContext
|
|
) -> MDCTabBarIndicatorAttributes {
|
|
let attributes = MDCTabBarIndicatorAttributes()
|
|
// Outset frame, round corners, and stroke.
|
|
let indicatorFrame = context.contentFrame.insetBy(dx: -8, dy: -4)
|
|
let path = UIBezierPath(roundedRect: indicatorFrame, cornerRadius: 4)
|
|
attributes.path = path.stroked(withWidth: 2)
|
|
return attributes
|
|
}
|
|
}
|
|
}
|
|
|
|
extension UIBezierPath {
|
|
/// Returns a copy of the path, stroked with the given line width.
|
|
func stroked(withWidth width: CGFloat) -> UIBezierPath {
|
|
let strokedPath = cgPath.copy(
|
|
strokingWithWidth: width,
|
|
lineCap: .butt,
|
|
lineJoin: .miter,
|
|
miterLimit: 0)
|
|
return UIBezierPath(cgPath: strokedPath)
|
|
}
|
|
}
|