diff --git a/Example/Example tvOS/Assets.xcassets/baseline-account_circle-24px.imageset/Contents.json b/Example/Example tvOS/Assets.xcassets/baseline-account_circle-24px.imageset/Contents.json
new file mode 100644
index 0000000..fb94720
--- /dev/null
+++ b/Example/Example tvOS/Assets.xcassets/baseline-account_circle-24px.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "baseline-account_circle-24px.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Example/Example tvOS/Assets.xcassets/baseline-account_circle-24px.imageset/baseline-account_circle-24px.pdf b/Example/Example tvOS/Assets.xcassets/baseline-account_circle-24px.imageset/baseline-account_circle-24px.pdf
new file mode 100644
index 0000000..f3508d1
Binary files /dev/null and b/Example/Example tvOS/Assets.xcassets/baseline-account_circle-24px.imageset/baseline-account_circle-24px.pdf differ
diff --git a/Example/Example tvOS/Assets.xcassets/baseline-folder-24px.imageset/Contents.json b/Example/Example tvOS/Assets.xcassets/baseline-folder-24px.imageset/Contents.json
new file mode 100644
index 0000000..5334833
--- /dev/null
+++ b/Example/Example tvOS/Assets.xcassets/baseline-folder-24px.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "baseline-folder-24px.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Example/Example tvOS/Assets.xcassets/baseline-folder-24px.imageset/baseline-folder-24px.pdf b/Example/Example tvOS/Assets.xcassets/baseline-folder-24px.imageset/baseline-folder-24px.pdf
new file mode 100644
index 0000000..5fc32f5
Binary files /dev/null and b/Example/Example tvOS/Assets.xcassets/baseline-folder-24px.imageset/baseline-folder-24px.pdf differ
diff --git a/Example/Example tvOS/Assets.xcassets/baseline-home-24px.imageset/Contents.json b/Example/Example tvOS/Assets.xcassets/baseline-home-24px.imageset/Contents.json
new file mode 100644
index 0000000..fa3189a
--- /dev/null
+++ b/Example/Example tvOS/Assets.xcassets/baseline-home-24px.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "baseline-home-24px.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Example/Example tvOS/Assets.xcassets/baseline-home-24px.imageset/baseline-home-24px.pdf b/Example/Example tvOS/Assets.xcassets/baseline-home-24px.imageset/baseline-home-24px.pdf
new file mode 100644
index 0000000..0b16a4d
Binary files /dev/null and b/Example/Example tvOS/Assets.xcassets/baseline-home-24px.imageset/baseline-home-24px.pdf differ
diff --git a/Example/Example tvOS/Assets.xcassets/baseline-search-24px.imageset/Contents.json b/Example/Example tvOS/Assets.xcassets/baseline-search-24px.imageset/Contents.json
new file mode 100644
index 0000000..627e7fe
--- /dev/null
+++ b/Example/Example tvOS/Assets.xcassets/baseline-search-24px.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "baseline-search-24px.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Example/Example tvOS/Assets.xcassets/baseline-search-24px.imageset/baseline-search-24px.pdf b/Example/Example tvOS/Assets.xcassets/baseline-search-24px.imageset/baseline-search-24px.pdf
new file mode 100644
index 0000000..e304379
Binary files /dev/null and b/Example/Example tvOS/Assets.xcassets/baseline-search-24px.imageset/baseline-search-24px.pdf differ
diff --git a/Example/Example tvOS/Assets.xcassets/baseline-settings-20px.imageset/Contents.json b/Example/Example tvOS/Assets.xcassets/baseline-settings-20px.imageset/Contents.json
new file mode 100644
index 0000000..89dc1fb
--- /dev/null
+++ b/Example/Example tvOS/Assets.xcassets/baseline-settings-20px.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "baseline-settings-20px.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Example/Example tvOS/Assets.xcassets/baseline-settings-20px.imageset/baseline-settings-20px.pdf b/Example/Example tvOS/Assets.xcassets/baseline-settings-20px.imageset/baseline-settings-20px.pdf
new file mode 100644
index 0000000..9045087
Binary files /dev/null and b/Example/Example tvOS/Assets.xcassets/baseline-settings-20px.imageset/baseline-settings-20px.pdf differ
diff --git a/Example/Example tvOS/Assets.xcassets/baseline-video_library-24px.imageset/Contents.json b/Example/Example tvOS/Assets.xcassets/baseline-video_library-24px.imageset/Contents.json
new file mode 100644
index 0000000..e159376
--- /dev/null
+++ b/Example/Example tvOS/Assets.xcassets/baseline-video_library-24px.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "baseline-video_library-24px.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/Example/Example tvOS/Assets.xcassets/baseline-video_library-24px.imageset/baseline-video_library-24px.pdf b/Example/Example tvOS/Assets.xcassets/baseline-video_library-24px.imageset/baseline-video_library-24px.pdf
new file mode 100644
index 0000000..7b18b12
Binary files /dev/null and b/Example/Example tvOS/Assets.xcassets/baseline-video_library-24px.imageset/baseline-video_library-24px.pdf differ
diff --git a/Example/Example tvOS/Assets.xcassets/yt_icon_rgb.imageset/Contents.json b/Example/Example tvOS/Assets.xcassets/yt_icon_rgb.imageset/Contents.json
new file mode 100644
index 0000000..39c16bc
--- /dev/null
+++ b/Example/Example tvOS/Assets.xcassets/yt_icon_rgb.imageset/Contents.json
@@ -0,0 +1,17 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "filename" : "yt_icon_rgb.png",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/Example/Example tvOS/Assets.xcassets/yt_icon_rgb.imageset/yt_icon_rgb.png b/Example/Example tvOS/Assets.xcassets/yt_icon_rgb.imageset/yt_icon_rgb.png
new file mode 100644
index 0000000..7f0b343
Binary files /dev/null and b/Example/Example tvOS/Assets.xcassets/yt_icon_rgb.imageset/yt_icon_rgb.png differ
diff --git a/Example/Example tvOS/Base.lproj/Main.storyboard b/Example/Example tvOS/Base.lproj/Main.storyboard
index 431028b..413b05d 100644
--- a/Example/Example tvOS/Base.lproj/Main.storyboard
+++ b/Example/Example tvOS/Base.lproj/Main.storyboard
@@ -4,16 +4,16 @@
-
+
-
+
-
+
@@ -21,53 +21,174 @@
-
+
-
-
-
-
+
+
-
+
-
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -85,553 +206,29 @@
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Example/Example tvOS/Colors.xcassets/Background.colorset/Contents.json b/Example/Example tvOS/Colors.xcassets/Background.colorset/Contents.json
new file mode 100644
index 0000000..744d440
--- /dev/null
+++ b/Example/Example tvOS/Colors.xcassets/Background.colorset/Contents.json
@@ -0,0 +1,20 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "colors" : [
+ {
+ "idiom" : "universal",
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0.184",
+ "alpha" : "1.000",
+ "blue" : "0.184",
+ "green" : "0.180"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Example/Example tvOS/Colors.xcassets/Contents.json b/Example/Example tvOS/Colors.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/Example/Example tvOS/Colors.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/Example/Example tvOS/Colors.xcassets/Theme.colorset/Contents.json b/Example/Example tvOS/Colors.xcassets/Theme.colorset/Contents.json
new file mode 100644
index 0000000..d2be700
--- /dev/null
+++ b/Example/Example tvOS/Colors.xcassets/Theme.colorset/Contents.json
@@ -0,0 +1,20 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "colors" : [
+ {
+ "idiom" : "universal",
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0.157",
+ "alpha" : "1.000",
+ "blue" : "0.157",
+ "green" : "0.157"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Example/Example tvOS/Info.plist b/Example/Example tvOS/Info.plist
index 02942a3..bf610cf 100644
--- a/Example/Example tvOS/Info.plist
+++ b/Example/Example tvOS/Info.plist
@@ -27,6 +27,6 @@
arm64
UIUserInterfaceStyle
- Automatic
+ Dark
diff --git a/Example/Example tvOS/YoutubeTabBar.swift b/Example/Example tvOS/YoutubeTabBar.swift
new file mode 100644
index 0000000..5bc3f8b
--- /dev/null
+++ b/Example/Example tvOS/YoutubeTabBar.swift
@@ -0,0 +1,258 @@
+//
+// YoutubeTabBar.swift
+// TabBarController_Example tvOS
+//
+// Created by Arnaud Dorgans on 11/09/2018.
+// Copyright © 2018 CocoaPods. All rights reserved.
+//
+
+import UIKit
+import TabBarController
+
+@objc enum YoutubeAction: Int {
+ case search
+
+ var image: UIImage? {
+ switch self {
+ case .search:
+ return UIImage(named: "baseline-search-24px", in: Bundle(for: YoutubeTabBar.self), compatibleWith: nil)
+ }
+ }
+}
+
+class YoutubeTabBarItem: UITabBarItem {
+
+ @IBInspectable var isAccessory: Bool = false
+ var action: YoutubeAction?
+
+ var isAction: Bool {
+ return action != nil
+ }
+
+ convenience init(image: UIImage?, isAccessory: Bool) {
+ self.init()
+ self.isAccessory = isAccessory
+ self.image = image
+ }
+
+ convenience init(action: YoutubeAction, isAccessory: Bool) {
+ self.init()
+ self.action = action
+ self.isAccessory = isAccessory
+ self.image = action.image
+ }
+}
+
+@objc protocol YoutubeTabBarDelegate: class {
+
+ @objc func youtubeTabBar(_ youtubeTabBar: YoutubeTabBar, didTriggerAction action: YoutubeAction)
+}
+
+@IBDesignable class YoutubeTabBar: UIView, TabBarProtocol {
+
+ private let logoImageView = UIImageView()
+ private let contentView = UIView()
+ private let stackView = UIStackView()
+ private let accessoryStackView = UIStackView()
+
+ private let youtubeAnimator = YoutubeTabBarAnimator()
+
+ weak var delegate: TabBarDelegate?
+ @IBOutlet weak var youtubeDelegate: YoutubeTabBarDelegate?
+
+ override var preferredFocusEnvironments: [UIFocusEnvironment] {
+ return [stackView.arrangedSubviews, accessoryStackView.arrangedSubviews]
+ .flatMap { $0 }
+ .sorted(by: { lhs, _ in (lhs as? YoutubeTabBarButton)?.isSelected == true })
+ }
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ sharedInit()
+ }
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+ sharedInit()
+ }
+
+ private func sharedInit() {
+ self.layer.shadowColor = UIColor.black.cgColor
+ self.layer.shadowOffset = CGSize(width: 8, height: 0)
+ self.layer.shadowOpacity = 0.3
+
+ contentView.translatesAutoresizingMaskIntoConstraints = false
+ contentView.backgroundColor = UIColor(named: "Theme", in: Bundle(for: YoutubeTabBar.self), compatibleWith: nil)
+ self.addSubview(contentView)
+ contentView.widthAnchor.constraint(equalToConstant: 200).isActive = true
+ contentView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
+ contentView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
+ contentView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
+ contentView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
+
+ logoImageView.image = UIImage(named: "yt_icon_rgb", in: Bundle(for: YoutubeTabBar.self), compatibleWith: nil)
+ logoImageView.translatesAutoresizingMaskIntoConstraints = false
+ logoImageView.contentMode = .center
+ self.addSubview(logoImageView)
+ logoImageView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
+ logoImageView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
+ logoImageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
+ logoImageView.heightAnchor.constraint(equalTo: logoImageView.widthAnchor).isActive = true
+
+ stackView.translatesAutoresizingMaskIntoConstraints = false
+ self.addSubview(stackView)
+ stackView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
+ stackView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
+ stackView.topAnchor.constraint(equalTo: logoImageView.bottomAnchor).isActive = true
+
+ accessoryStackView.translatesAutoresizingMaskIntoConstraints = false
+ self.addSubview(accessoryStackView)
+ accessoryStackView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
+ accessoryStackView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
+ accessoryStackView.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor).isActive = true
+
+ [stackView, accessoryStackView].forEach {
+ $0.axis = .vertical
+ $0.distribution = .fillEqually
+ }
+ }
+
+ func setSelectedItem(_ item: UITabBarItem?, animated: Bool) {
+ [stackView.arrangedSubviews, accessoryStackView.arrangedSubviews]
+ .flatMap { $0 }
+ .forEach {
+ guard let button = $0 as? YoutubeTabBarButton else {
+ return
+ }
+ button.isSelected = button.item == item
+ }
+ }
+
+ func setItems(_ items: [UITabBarItem]?, animated: Bool) {
+ [stackView.arrangedSubviews, accessoryStackView.arrangedSubviews]
+ .flatMap { $0 }
+ .forEach { $0.removeFromSuperview() }
+ let items = [[YoutubeTabBarItem(action: .search, isAccessory: false)], items ?? []].flatMap { $0 }
+ items.forEach {
+ guard let button = YoutubeTabBarButton(item: $0) else {
+ return
+ }
+ button.addTarget(self, action: #selector(self.didTapButton(_:)), for: .primaryActionTriggered)
+ if button.item.isAccessory {
+ accessoryStackView.addArrangedSubview(button)
+ } else {
+ stackView.addArrangedSubview(button)
+ }
+ }
+ }
+
+ @objc func didTapButton(_ sender: Any) {
+ guard let button = sender as? YoutubeTabBarButton,
+ let action = button.item.action else {
+ return
+ }
+ self.youtubeDelegate?.youtubeTabBar(self, didTriggerAction: action)
+ }
+
+ override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
+ guard let button = context.nextFocusedView as? YoutubeTabBarButton else {
+ return
+ }
+ self.delegate?.tabBar(self, didSelect: button.item)
+ }
+
+ func animator() -> TabBarAnimator? {
+ return youtubeAnimator
+ }
+
+ override func prepareForInterfaceBuilder() {
+ let items = [YoutubeTabBarItem(image: UIImage(named: "baseline-home-24px", in: Bundle(for: YoutubeTabBar.self), compatibleWith: nil), isAccessory: false),
+ YoutubeTabBarItem(image: UIImage(named: "baseline-video_library-24px", in: Bundle(for: YoutubeTabBar.self), compatibleWith: nil), isAccessory: false),
+ YoutubeTabBarItem(image: UIImage(named: "baseline-folder-24px", in: Bundle(for: YoutubeTabBar.self), compatibleWith: nil), isAccessory: false),
+ YoutubeTabBarItem(image: UIImage(named: "baseline-account_circle-24px", in: Bundle(for: YoutubeTabBar.self), compatibleWith: nil), isAccessory: true),
+ YoutubeTabBarItem(image: UIImage(named: "baseline-settings-20px", in: Bundle(for: YoutubeTabBar.self), compatibleWith: nil), isAccessory: true)]
+ self.setItems(items, animated: false)
+ self.setSelectedItem(items.first, animated: false)
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ }
+}
+
+private class YoutubeTabBarButton: UIButton {
+
+ private let logoView = UIImageView()
+ private let backgroundView = UIView()
+ private let roundedBackgroundView = UIView()
+
+ let item: YoutubeTabBarItem
+
+ init?(item: UITabBarItem) {
+ guard let item = item as? YoutubeTabBarItem else {
+ return nil
+ }
+ self.item = item
+ super.init(frame: .zero)
+
+ roundedBackgroundView.layer.shadowOffset = CGSize(width: 0, height: 5)
+ roundedBackgroundView.layer.shadowColor = UIColor.black.cgColor
+ roundedBackgroundView.layer.shadowOpacity = 1
+ roundedBackgroundView.isUserInteractionEnabled = false
+ roundedBackgroundView.translatesAutoresizingMaskIntoConstraints = false
+ self.addSubview(roundedBackgroundView)
+ roundedBackgroundView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
+ roundedBackgroundView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
+ roundedBackgroundView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.9).isActive = true
+ roundedBackgroundView.widthAnchor.constraint(equalTo: roundedBackgroundView.heightAnchor).isActive = true
+
+ backgroundView.isUserInteractionEnabled = false
+ backgroundView.translatesAutoresizingMaskIntoConstraints = false
+ self.addSubview(backgroundView)
+ backgroundView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
+ backgroundView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
+ backgroundView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
+ backgroundView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
+
+ logoView.image = item.image
+ logoView.contentMode = .center
+ logoView.translatesAutoresizingMaskIntoConstraints = false
+ self.addSubview(logoView)
+ logoView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
+ logoView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
+ logoView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
+ logoView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
+ logoView.heightAnchor.constraint(equalTo: logoView.widthAnchor, multiplier: 0.6).isActive = true
+
+ update()
+ }
+
+ private func update() {
+ logoView.tintColor = {
+ guard !self.isFocused else {
+ return UIColor(named: "Theme", in: Bundle(for: YoutubeTabBar.self), compatibleWith: nil)
+ }
+ return self.isSelected ? UIColor.white : UIColor.white.withAlphaComponent(0.4)
+ }()
+ backgroundView.backgroundColor = self.isFocused ? .white : .clear
+ roundedBackgroundView.backgroundColor = backgroundView.backgroundColor
+ backgroundView.isHidden = self.item.isAction
+ roundedBackgroundView.isHidden = !backgroundView.isHidden
+ }
+
+ override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
+ coordinator.addCoordinatedAnimations({
+ self.update()
+ }, completion: nil)
+ }
+
+ override func layoutSubviews() {
+ super.layoutSubviews()
+
+ roundedBackgroundView.layer.cornerRadius = roundedBackgroundView.frame.height / 2
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
diff --git a/Example/Example tvOS/YoutubeTabBarAnimator.swift b/Example/Example tvOS/YoutubeTabBarAnimator.swift
new file mode 100644
index 0000000..f57f285
--- /dev/null
+++ b/Example/Example tvOS/YoutubeTabBarAnimator.swift
@@ -0,0 +1,30 @@
+//
+// YoutubeTabBarAnimator.swift
+// TabBarController_Example tvOS
+//
+// Created by Arnaud Dorgans on 11/09/2018.
+// Copyright © 2018 CocoaPods. All rights reserved.
+//
+
+import UIKit
+import TabBarController
+
+class YoutubeTabBarAnimator: TabBarAnimator {
+
+ private var tabBarConstraints = [NSLayoutConstraint]()
+
+ func tabBarInsets(withContext context: TabBarAnimatorContext) -> UIEdgeInsets {
+ return UIEdgeInsets(top: 0, left: context.tabBar.frame.width, bottom: 0, right: 0)
+ }
+
+ func animateTabBar(using context: TabBarAnimatorContext) {
+ if tabBarConstraints.isEmpty {
+ context.tabBar.translatesAutoresizingMaskIntoConstraints = false
+ context.containerView.addSubview(context.tabBar)
+ tabBarConstraints.append(context.tabBar.leadingAnchor.constraint(equalTo: context.containerView.leadingAnchor))
+ tabBarConstraints.append(context.tabBar.topAnchor.constraint(equalTo: context.containerView.topAnchor))
+ tabBarConstraints.append(context.tabBar.bottomAnchor.constraint(equalTo: context.containerView.bottomAnchor))
+ NSLayoutConstraint.activate(tabBarConstraints)
+ }
+ }
+}
diff --git a/Example/Example tvOS/YoutubeTabBarController.swift b/Example/Example tvOS/YoutubeTabBarController.swift
new file mode 100644
index 0000000..e1dd3f6
--- /dev/null
+++ b/Example/Example tvOS/YoutubeTabBarController.swift
@@ -0,0 +1,42 @@
+//
+// YoutubeTabBarController.swift
+// TabBarController_Example tvOS
+//
+// Created by Arnaud Dorgans on 11/09/2018.
+// Copyright © 2018 CocoaPods. All rights reserved.
+//
+
+import UIKit
+import TabBarController
+
+class YoutubeTabBarController: TabBarController {
+
+ let tabBarFocusGuide = UIFocusGuide()
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ self.view.addLayoutGuide(tabBarFocusGuide)
+ tabBarFocusGuide.topAnchor.constraint(equalTo: tabBar.topAnchor).isActive = true
+ tabBarFocusGuide.bottomAnchor.constraint(equalTo: tabBar.bottomAnchor).isActive = true
+ tabBarFocusGuide.leftAnchor.constraint(equalTo: tabBar.rightAnchor).isActive = true
+ tabBarFocusGuide.widthAnchor.constraint(equalToConstant: 1).isActive = true
+ }
+
+ override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
+ super.didUpdateFocus(in: context, with: coordinator)
+
+ guard let item = context.nextFocusedItem else {
+ return
+ }
+ tabBarFocusGuide.preferredFocusEnvironments = [self.tabBar.contains(item) ? containerView : tabBar]
+ }
+}
+
+extension YoutubeTabBarController: YoutubeTabBarDelegate {
+
+ func youtubeTabBar(_ youtubeTabBar: YoutubeTabBar, didTriggerAction action: YoutubeAction) {
+ let searchController = UISearchController(searchResultsController: nil)
+ self.present(searchController, animated: true, completion: nil)
+ }
+}
diff --git a/Example/Podfile.lock b/Example/Podfile.lock
index e8442ec..9bbef99 100644
--- a/Example/Podfile.lock
+++ b/Example/Podfile.lock
@@ -1,5 +1,5 @@
PODS:
- - TabBarController (0.1.0)
+ - TabBarController (1.0)
DEPENDENCIES:
- TabBarController (from `../`)
@@ -9,7 +9,7 @@ EXTERNAL SOURCES:
:path: "../"
SPEC CHECKSUMS:
- TabBarController: c2e762e8898f5d3af42beb108a639771baf4fae3
+ TabBarController: afe4560c4934f25088b0f13129e95d0d76410ad8
PODFILE CHECKSUM: 8947fba8d959d70de552e8e03041ad5648b8e41c
diff --git a/Example/TabBarController.xcodeproj/project.pbxproj b/Example/TabBarController.xcodeproj/project.pbxproj
index f568c80..395aac6 100644
--- a/Example/TabBarController.xcodeproj/project.pbxproj
+++ b/Example/TabBarController.xcodeproj/project.pbxproj
@@ -24,6 +24,10 @@
D486CDC121284B380015BE9A /* iOS9TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D486CDC021284B380015BE9A /* iOS9TableViewController.swift */; };
D49561132129AF08008363D2 /* SpringboardTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49561122129AF08008363D2 /* SpringboardTabBar.swift */; };
D4EDE0A721270D7900B5346A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
+ D4EEEE022147EF580082FB08 /* YoutubeTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4EEEE012147EF580082FB08 /* YoutubeTabBar.swift */; };
+ D4EEEE042147F1DB0082FB08 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D4EEEE032147F1DB0082FB08 /* Colors.xcassets */; };
+ D4EEEE0621480AEF0082FB08 /* YoutubeTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4EEEE0521480AEF0082FB08 /* YoutubeTabBarController.swift */; };
+ D4EEEE082148364B0082FB08 /* YoutubeTabBarAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4EEEE072148364B0082FB08 /* YoutubeTabBarAnimator.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -64,6 +68,10 @@
D45C21C02126EFA4004D21C2 /* SpringboardTabBarTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpringboardTabBarTransition.swift; sourceTree = ""; };
D486CDC021284B380015BE9A /* iOS9TableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOS9TableViewController.swift; sourceTree = ""; };
D49561122129AF08008363D2 /* SpringboardTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpringboardTabBar.swift; sourceTree = ""; };
+ D4EEEE012147EF580082FB08 /* YoutubeTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YoutubeTabBar.swift; sourceTree = ""; };
+ D4EEEE032147F1DB0082FB08 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = ""; };
+ D4EEEE0521480AEF0082FB08 /* YoutubeTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YoutubeTabBarController.swift; sourceTree = ""; };
+ D4EEEE072148364B0082FB08 /* YoutubeTabBarAnimator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YoutubeTabBarAnimator.swift; sourceTree = ""; };
DDC31CB3904783CBD80ADB30 /* Pods-TabBarController_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TabBarController_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TabBarController_Example/Pods-TabBarController_Example.debug.xcconfig"; sourceTree = ""; };
E6D42CFDD2DF28A3B3C61818 /* Pods_TabBarController_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TabBarController_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EB8401B9CBC7D663C150F67D /* Pods-TabBarController_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TabBarController_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-TabBarController_Example/Pods-TabBarController_Example.release.xcconfig"; sourceTree = ""; };
@@ -188,9 +196,11 @@
D45C21AD2126B7AF004D21C2 /* Example tvOS */ = {
isa = PBXGroup;
children = (
+ D4EEEE002147EF350082FB08 /* Youtube */,
D45C21AE2126B7AF004D21C2 /* AppDelegate.swift */,
D45C21B22126B7AF004D21C2 /* Main.storyboard */,
D45C21B52126B7B0004D21C2 /* Assets.xcassets */,
+ D4EEEE032147F1DB0082FB08 /* Colors.xcassets */,
D45C21B72126B7B0004D21C2 /* Info.plist */,
);
path = "Example tvOS";
@@ -206,6 +216,16 @@
name = Springboard;
sourceTree = "";
};
+ D4EEEE002147EF350082FB08 /* Youtube */ = {
+ isa = PBXGroup;
+ children = (
+ D4EEEE012147EF580082FB08 /* YoutubeTabBar.swift */,
+ D4EEEE0521480AEF0082FB08 /* YoutubeTabBarController.swift */,
+ D4EEEE072148364B0082FB08 /* YoutubeTabBarAnimator.swift */,
+ );
+ name = Youtube;
+ sourceTree = "";
+ };
D7136837F9A4A10D451C19B0 /* Frameworks */ = {
isa = PBXGroup;
children = (
@@ -346,6 +366,7 @@
buildActionMask = 2147483647;
files = (
D4EDE0A721270D7900B5346A /* Images.xcassets in Resources */,
+ D4EEEE042147F1DB0082FB08 /* Colors.xcassets in Resources */,
D45C21B62126B7B0004D21C2 /* Assets.xcassets in Resources */,
D45C21B42126B7AF004D21C2 /* Main.storyboard in Resources */,
);
@@ -472,7 +493,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ D4EEEE0621480AEF0082FB08 /* YoutubeTabBarController.swift in Sources */,
D45C21AF2126B7AF004D21C2 /* AppDelegate.swift in Sources */,
+ D4EEEE082148364B0082FB08 /* YoutubeTabBarAnimator.swift in Sources */,
+ D4EEEE022147EF580082FB08 /* YoutubeTabBar.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -714,7 +738,7 @@
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = 3;
- TVOS_DEPLOYMENT_TARGET = 9.0;
+ TVOS_DEPLOYMENT_TARGET = 11.0;
};
name = Debug;
};
@@ -741,7 +765,7 @@
SDKROOT = appletvos;
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = 3;
- TVOS_DEPLOYMENT_TARGET = 9.0;
+ TVOS_DEPLOYMENT_TARGET = 11.0;
};
name = Release;
};
diff --git a/Images/004.gif b/Images/004.gif
index dd78ee6..f73ad40 100644
Binary files a/Images/004.gif and b/Images/004.gif differ
diff --git a/TabBarController/Classes/TabBarController.swift b/TabBarController/Classes/TabBarController.swift
index 713e4fa..e0f4b38 100644
--- a/TabBarController/Classes/TabBarController.swift
+++ b/TabBarController/Classes/TabBarController.swift
@@ -56,6 +56,10 @@ open class TabBarController: UIViewController {
}
#endif
+ public var containerView: UIView {
+ return containerController.view
+ }
+
private var _tabBarAnchor: TabBarAnchor = .default
public var tabBarAnchor: TabBarAnchor {
get { return _tabBarAnchor }