Re-add navigation bar
This commit is contained in:
parent
256cb0958e
commit
d3c196949e
|
@ -19,17 +19,33 @@ class BrowserNavigationController: UIViewController {
|
|||
private var currentBrowserVC: BrowserWebViewController!
|
||||
|
||||
private var browserContainer: UIView!
|
||||
private var navBarView: NavigationBarView!
|
||||
private var toolbarView: ToolbarView!
|
||||
|
||||
private var gestureState: GestureState?
|
||||
private var trackingScroll = false
|
||||
private var scrollStartedBelowEnd = false
|
||||
private var prevScrollViewContentOffset: CGPoint?
|
||||
private var toolbarOffset: CGFloat = 0 {
|
||||
didSet {
|
||||
toolbarView.transform = CGAffineTransform(translationX: 0, y: toolbarOffset)
|
||||
let realOffset = toolbarOffset * max(toolbarView.bounds.height, navBarView.bounds.height)
|
||||
toolbarView.transform = CGAffineTransform(translationX: 0, y: realOffset)
|
||||
navBarView.transform = CGAffineTransform(translationX: 0, y: -realOffset)
|
||||
|
||||
if (oldValue <= 0.5 && toolbarOffset > 0.5) || (oldValue > 0.5 && toolbarOffset <= 0.5) {
|
||||
setNeedsStatusBarAppearanceUpdate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override var prefersStatusBarHidden: Bool {
|
||||
toolbarOffset > 0.5
|
||||
}
|
||||
|
||||
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
|
||||
.slide
|
||||
}
|
||||
|
||||
private var cancellables = [AnyCancellable]()
|
||||
|
||||
init(navigator: NavigationManager) {
|
||||
|
@ -55,6 +71,15 @@ class BrowserNavigationController: UIViewController {
|
|||
currentBrowserVC.scrollViewDelegate = self
|
||||
embedChild(currentBrowserVC, in: browserContainer)
|
||||
|
||||
navBarView = NavigationBarView(navigator: navigator)
|
||||
navBarView.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(navBarView)
|
||||
NSLayoutConstraint.activate([
|
||||
navBarView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
navBarView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
navBarView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
])
|
||||
|
||||
toolbarView = ToolbarView(navigator: navigator)
|
||||
toolbarView.showShareSheet = self.showShareSheet
|
||||
toolbarView.showPreferences = self.showPreferences
|
||||
|
@ -86,8 +111,14 @@ class BrowserNavigationController: UIViewController {
|
|||
}
|
||||
|
||||
private func setBrowserVCSafeAreaInsets(_ vc: BrowserWebViewController) {
|
||||
guard let toolbarView = toolbarView else { return }
|
||||
vc.additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: toolbarView.bounds.height - view.safeAreaInsets.bottom - toolbarOffset, right: 0)
|
||||
guard let toolbarView = toolbarView,
|
||||
let navBarView = navBarView else { return }
|
||||
vc.additionalSafeAreaInsets = UIEdgeInsets(
|
||||
top: navBarView.bounds.height - view.safeAreaInsets.top,
|
||||
left: 0,
|
||||
bottom: toolbarView.bounds.height - view.safeAreaInsets.bottom,
|
||||
right: 0
|
||||
)
|
||||
}
|
||||
|
||||
private func onNavigate(_ operation: NavigationManager.Operation) {
|
||||
|
@ -118,6 +149,11 @@ class BrowserNavigationController: UIViewController {
|
|||
currentBrowserVC = newVC
|
||||
currentBrowserVC.scrollViewDelegate = self
|
||||
embedChild(newVC, in: browserContainer)
|
||||
|
||||
UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseInOut) {
|
||||
self.toolbarOffset = 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private let startEdgeNavigationSwipeDistance: CGFloat = 75
|
||||
|
@ -253,6 +289,7 @@ extension BrowserNavigationController: UIScrollViewDelegate {
|
|||
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
|
||||
trackingScroll = true
|
||||
prevScrollViewContentOffset = scrollView.contentOffset
|
||||
scrollStartedBelowEnd = scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.bounds.height + scrollView.safeAreaInsets.bottom)
|
||||
}
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
|
@ -262,19 +299,18 @@ extension BrowserNavigationController: UIScrollViewDelegate {
|
|||
|
||||
let delta = scrollView.contentOffset.y - prevOffset.y
|
||||
|
||||
let belowEnd = scrollView.contentOffset.y > scrollView.contentSize.height - scrollView.bounds.height + scrollView.safeAreaInsets.bottom
|
||||
let belowEnd = scrollView.contentOffset.y > (scrollView.contentSize.height - scrollView.bounds.height + scrollView.safeAreaInsets.bottom)
|
||||
|
||||
if belowEnd {
|
||||
UIView.animate(withDuration: 0.15, delay: 0, options: .curveEaseInOut) {
|
||||
self.toolbarOffset = 0
|
||||
} completion: { (_) in
|
||||
self.setBrowserVCSafeAreaInsets(self.currentBrowserVC)
|
||||
if scrollStartedBelowEnd {
|
||||
UIView.animate(withDuration: 0.15, delay: 0, options: .curveEaseInOut) {
|
||||
self.toolbarOffset = 0
|
||||
}
|
||||
trackingScroll = false
|
||||
}
|
||||
trackingScroll = false
|
||||
} else if delta > 0 || (delta < 0 && toolbarOffset < toolbarView.bounds.height) {
|
||||
toolbarOffset = max(0, min(toolbarView.bounds.height, toolbarOffset + delta))
|
||||
|
||||
setBrowserVCSafeAreaInsets(currentBrowserVC)
|
||||
} else if delta > 0 || (delta < 0 && toolbarOffset < 1) {
|
||||
let normalizedDelta = delta / max(toolbarView.bounds.height, navBarView.bounds.height)
|
||||
toolbarOffset = max(0, min(1, toolbarOffset + normalizedDelta))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,7 +322,7 @@ extension BrowserNavigationController: UIScrollViewDelegate {
|
|||
if velocity.y < 0 {
|
||||
finalOffset = 0
|
||||
} else {
|
||||
finalOffset = toolbarView.bounds.height
|
||||
finalOffset = 1
|
||||
}
|
||||
|
||||
UIView.animate(withDuration: 0.15, delay: 0, options: .curveEaseOut) {
|
||||
|
|
|
@ -6,15 +6,80 @@
|
|||
//
|
||||
|
||||
import UIKit
|
||||
import BrowserCore
|
||||
import Combine
|
||||
|
||||
class NavigationBarView: UIView {
|
||||
|
||||
/*
|
||||
// Only override draw() if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
override func draw(_ rect: CGRect) {
|
||||
// Drawing code
|
||||
let navigator: NavigationManager
|
||||
|
||||
private var border: UIView!
|
||||
private var textField: UITextField!
|
||||
|
||||
private var cancellables = [AnyCancellable]()
|
||||
|
||||
init(navigator: NavigationManager) {
|
||||
self.navigator = navigator
|
||||
|
||||
super.init(frame: .zero)
|
||||
|
||||
backgroundColor = .systemBackground
|
||||
|
||||
border = UIView()
|
||||
border.backgroundColor = UIColor(white: traitCollection.userInterfaceStyle == .dark ? 0.25 : 0.75, alpha: 1)
|
||||
border.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(border)
|
||||
NSLayoutConstraint.activate([
|
||||
border.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
border.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
border.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
border.heightAnchor.constraint(equalToConstant: 1),
|
||||
])
|
||||
|
||||
textField = UITextField()
|
||||
textField.text = navigator.displayURL
|
||||
textField.borderStyle = .roundedRect
|
||||
textField.keyboardType = .URL
|
||||
textField.autocapitalizationType = .none
|
||||
textField.autocorrectionType = .no
|
||||
textField.addTarget(self, action: #selector(commitURL), for: .editingDidEnd)
|
||||
textField.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(textField)
|
||||
NSLayoutConstraint.activate([
|
||||
textField.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8),
|
||||
textField.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8),
|
||||
textField.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
|
||||
textField.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -9),
|
||||
])
|
||||
|
||||
navigator.$currentURL
|
||||
.sink { (newURL) in
|
||||
// can't use navigator.displayURL because the publisher fires before the underlying value is updated, so the displayURL getter returns the old value
|
||||
var components = URLComponents(url: newURL, resolvingAgainstBaseURL: false)!
|
||||
if components.port == 1965 {
|
||||
components.port = nil
|
||||
}
|
||||
self.textField.text = components.string!
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
border.backgroundColor = UIColor(white: traitCollection.userInterfaceStyle == .dark ? 0.25 : 0.75, alpha: 1)
|
||||
}
|
||||
|
||||
@objc private func commitURL() {
|
||||
if let text = textField.text, let url = URL(string: text) {
|
||||
navigator.changeURL(url)
|
||||
} else {
|
||||
textField.text = navigator.displayURL
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
D69F00AC24BE9DD300E37622 /* GeminiDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69F00AB24BE9DD300E37622 /* GeminiDataTask.swift */; };
|
||||
D69F00AE24BEA29100E37622 /* GeminiResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69F00AD24BEA29100E37622 /* GeminiResponse.swift */; };
|
||||
D6BC9AB3258E8E13008652BC /* ToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BC9AB2258E8E13008652BC /* ToolbarView.swift */; };
|
||||
D6BC9ABC258E9862008652BC /* NavigationBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BC9ABB258E9862008652BC /* NavigationBarView.swift */; };
|
||||
D6DA5783252396030048B65A /* View+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DA5782252396030048B65A /* View+Extensions.swift */; };
|
||||
D6E1529824BFAAA400FDF9D3 /* BrowserWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E1529624BFAAA400FDF9D3 /* BrowserWindowController.swift */; };
|
||||
D6E1529924BFAAA400FDF9D3 /* BrowserWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6E1529724BFAAA400FDF9D3 /* BrowserWindowController.xib */; };
|
||||
|
@ -323,6 +324,7 @@
|
|||
D69F00AD24BEA29100E37622 /* GeminiResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiResponse.swift; sourceTree = "<group>"; };
|
||||
D69F00AF24BEA84D00E37622 /* NavigationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationManager.swift; sourceTree = "<group>"; };
|
||||
D6BC9AB2258E8E13008652BC /* ToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolbarView.swift; sourceTree = "<group>"; };
|
||||
D6BC9ABB258E9862008652BC /* NavigationBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarView.swift; sourceTree = "<group>"; };
|
||||
D6DA5782252396030048B65A /* View+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Extensions.swift"; sourceTree = "<group>"; };
|
||||
D6E1529624BFAAA400FDF9D3 /* BrowserWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserWindowController.swift; sourceTree = "<group>"; };
|
||||
D6E1529724BFAAA400FDF9D3 /* BrowserWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BrowserWindowController.xib; sourceTree = "<group>"; };
|
||||
|
@ -588,6 +590,7 @@
|
|||
D688F632258B09BB003A0A73 /* TrackpadScrollGestureRecognizer.swift */,
|
||||
D688F662258C2479003A0A73 /* UIViewController+Children.swift */,
|
||||
D6BC9AB2258E8E13008652BC /* ToolbarView.swift */,
|
||||
D6BC9ABB258E9862008652BC /* NavigationBarView.swift */,
|
||||
D691A6762522382E00348C4B /* BrowserViewController.swift */,
|
||||
D6E152A824BFFDF500FDF9D3 /* ContentView.swift */,
|
||||
D691A68625223A4600348C4B /* NavigationBar.swift */,
|
||||
|
@ -1120,6 +1123,7 @@
|
|||
D688F663258C2479003A0A73 /* UIViewController+Children.swift in Sources */,
|
||||
D691A64E25217C6F00348C4B /* Preferences.swift in Sources */,
|
||||
D6E152A924BFFDF500FDF9D3 /* ContentView.swift in Sources */,
|
||||
D6BC9ABC258E9862008652BC /* NavigationBarView.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue