TabView: Animations when closing tabs as well
This commit is contained in:
@@ -257,6 +257,9 @@ class BrowserViewController: UIViewController, WKNavigationDelegate, WKUIDelegat
|
|||||||
self.tab = tab
|
self.tab = tab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show tab bar view?
|
||||||
|
browserView.tabBarViewVisible = tabController.tabs.count > 1
|
||||||
})
|
})
|
||||||
|
|
||||||
self.view = browserView
|
self.view = browserView
|
||||||
@@ -307,9 +310,6 @@ class BrowserViewController: UIViewController, WKNavigationDelegate, WKUIDelegat
|
|||||||
// Autocomplete view
|
// Autocomplete view
|
||||||
browserView.autocompleteView = autocompleteViewController.view
|
browserView.autocompleteView = autocompleteViewController.view
|
||||||
|
|
||||||
// Show tab bar view?
|
|
||||||
browserView.tabBarViewVisible = tabController.tabs.count > 1
|
|
||||||
|
|
||||||
// Color theme
|
// Color theme
|
||||||
browserView.titlebarView.setColorTheme(tab.colorTheme)
|
browserView.titlebarView.setColorTheme(tab.colorTheme)
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ class TabView: UIControl
|
|||||||
{
|
{
|
||||||
var active: Bool = false { didSet { setNeedsLayout() } }
|
var active: Bool = false { didSet { setNeedsLayout() } }
|
||||||
var collapsed: Bool = false
|
var collapsed: Bool = false
|
||||||
|
var identifier: UUID?
|
||||||
|
|
||||||
let label = UILabel(frame: .zero)
|
let label = UILabel(frame: .zero)
|
||||||
let closeButton = UIButton(frame: .zero)
|
let closeButton = UIButton(frame: .zero)
|
||||||
let imageView = UIImageView(image: nil)
|
let imageView = UIImageView(image: nil)
|
||||||
@@ -104,6 +106,7 @@ protocol TabBarViewDataSource: AnyObject {
|
|||||||
func numberOfTabs(forTabBarView: TabBarView) -> Int
|
func numberOfTabs(forTabBarView: TabBarView) -> Int
|
||||||
func tabBarView(_ tabBarView: TabBarView, titleForTabAtIndex: Int) -> String
|
func tabBarView(_ tabBarView: TabBarView, titleForTabAtIndex: Int) -> String
|
||||||
func tabBarView(_ tabBarView: TabBarView, imageForTabAtIndex: Int) -> UIImage?
|
func tabBarView(_ tabBarView: TabBarView, imageForTabAtIndex: Int) -> UIImage?
|
||||||
|
func tabBarView(_ tabBarView: TabBarView, uniqueIdentifierForTabAtIndex: Int) -> UUID
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol TabBarViewDelegate: AnyObject {
|
protocol TabBarViewDelegate: AnyObject {
|
||||||
@@ -143,29 +146,36 @@ class TabBarView: UIView
|
|||||||
public func reloadTabs(animated: Bool = true) {
|
public func reloadTabs(animated: Bool = true) {
|
||||||
guard let dataSource = self.dataSource else { return }
|
guard let dataSource = self.dataSource else { return }
|
||||||
|
|
||||||
let numberOfTabs = dataSource.numberOfTabs(forTabBarView: self)
|
var tabViewsRemoved = Set<TabView>(tabViews)
|
||||||
while numberOfTabs < tabViews.count {
|
|
||||||
let tabView = tabViews.removeLast()
|
|
||||||
tabView.removeFromSuperview()
|
|
||||||
}
|
|
||||||
|
|
||||||
while numberOfTabs > tabViews.count {
|
let numberOfTabs = dataSource.numberOfTabs(forTabBarView: self)
|
||||||
let newTabView = makeTabView()
|
for i in 0..<numberOfTabs {
|
||||||
|
let identifier = dataSource.tabBarView(self, uniqueIdentifierForTabAtIndex: i)
|
||||||
|
if let tabView = tabViewsRemoved.first(where: { $0.identifier == identifier }) {
|
||||||
|
tabViewsRemoved.remove(tabView)
|
||||||
|
self.reloadTab(atIndex: i)
|
||||||
|
} else {
|
||||||
|
let newTabView = makeTabView(withIdentifier: identifier)
|
||||||
if animated { newTabView.collapsed = true }
|
if animated { newTabView.collapsed = true }
|
||||||
tabViews.append(newTabView)
|
tabViews.append(newTabView)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, _) in tabViews.enumerated() {
|
|
||||||
self.reloadTab(atIndex: i)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
layoutSubviews()
|
layoutSubviews()
|
||||||
|
|
||||||
if animated {
|
if animated {
|
||||||
|
// Incoming tabs uncollapse
|
||||||
tabViews.forEach { $0.collapsed = false }
|
tabViews.forEach { $0.collapsed = false }
|
||||||
UIView.animate(withDuration: 0.3) { [unowned self] in
|
|
||||||
|
// Outgoing tabs collapse
|
||||||
|
tabViewsRemoved.forEach { $0.collapsed = true }
|
||||||
|
|
||||||
|
UIView.animate(withDuration: 0.22, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 1.0, options: [], animations: { [unowned self] in
|
||||||
layoutSubviews()
|
layoutSubviews()
|
||||||
}
|
}, completion: { [unowned self] finished in
|
||||||
|
tabViewsRemoved.forEach { $0.removeFromSuperview() }
|
||||||
|
tabViews.removeAll { tabViewsRemoved.contains($0) }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust scroll offset
|
// Adjust scroll offset
|
||||||
@@ -190,8 +200,10 @@ class TabBarView: UIView
|
|||||||
setNeedsLayout()
|
setNeedsLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func makeTabView() -> TabView {
|
private func makeTabView(withIdentifier identifier: UUID) -> TabView {
|
||||||
let tabView = TabView()
|
let tabView = TabView()
|
||||||
|
tabView.identifier = identifier
|
||||||
|
|
||||||
tabView.addAction(UIAction(handler: { [unowned self, tabView] _ in
|
tabView.addAction(UIAction(handler: { [unowned self, tabView] _ in
|
||||||
guard let delegate = self.delegate else { return }
|
guard let delegate = self.delegate else { return }
|
||||||
guard let tabIndex = self.tabViews.firstIndex(of: tabView) else { return }
|
guard let tabIndex = self.tabViews.firstIndex(of: tabView) else { return }
|
||||||
@@ -244,6 +256,8 @@ class TabBarView: UIView
|
|||||||
for (i, tabView) in tabViews.enumerated() {
|
for (i, tabView) in tabViews.enumerated() {
|
||||||
tabContainerView.addSubview(tabView)
|
tabContainerView.addSubview(tabView)
|
||||||
|
|
||||||
|
tabView.alpha = tabView.collapsed ? 0.0 : 1.0
|
||||||
|
|
||||||
tabView.frame = CGRect(
|
tabView.frame = CGRect(
|
||||||
x: xOffset,
|
x: xOffset,
|
||||||
y: tabContainerBounds.minY,
|
y: tabContainerBounds.minY,
|
||||||
|
|||||||
@@ -71,4 +71,8 @@ class TabBarViewController: UIViewController, TabBarViewDataSource, TabBarViewDe
|
|||||||
tabController.tabs[index].favicon
|
tabController.tabs[index].favicon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tabBarView(_ tabBarView: TabBarView, uniqueIdentifierForTabAtIndex index: Int) -> UUID {
|
||||||
|
tabController.tabs[index].identifier
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user