Another attempt to fix empty URL bar
This commit is contained in:
@@ -98,6 +98,7 @@ class BrowserView: UIView
|
||||
}
|
||||
}(animationCurve)
|
||||
|
||||
toolbarView?.layoutLatch.deactivate()
|
||||
keyboardLayoutOffset = bounds.height - keyboardEndFrame.minY
|
||||
UIView.animate(withDuration: animationDuration, delay: 0.0, options: animationOptions, animations: { self.layoutIfNeeded() }, completion: nil)
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ class ReliefButton: UIButton
|
||||
}
|
||||
})
|
||||
|
||||
self.imageView?.contentMode = .scaleAspectFit
|
||||
|
||||
shadowView.alpha = 0.28
|
||||
shadowView.backgroundColor = UIColor(white: 0.0, alpha: 1.0)
|
||||
shadowView.isUserInteractionEnabled = false
|
||||
@@ -132,8 +134,6 @@ class ReliefButton: UIButton
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
self.imageView?.contentMode = .scaleAspectFit
|
||||
|
||||
super.layoutSubviews()
|
||||
|
||||
sendSubviewToBack(backgroundView)
|
||||
|
||||
@@ -9,9 +9,18 @@ import UIKit
|
||||
|
||||
class ToolbarView: UIView
|
||||
{
|
||||
var urlBar: URLBar? { didSet { containerView.addSubview(urlBar!) } }
|
||||
var urlBar: URLBar? {
|
||||
didSet {
|
||||
guard let urlBar else { return }
|
||||
containerView.addSubview(urlBar)
|
||||
|
||||
urlBar.textField.addAction(.init(handler: { [unowned self] _ in
|
||||
layoutLatch.activate()
|
||||
}), for: [ .editingDidBegin, .editingDidEnd ])
|
||||
}
|
||||
}
|
||||
|
||||
var cancelButtonVisible: Bool = false { didSet { layoutSubviews() } }
|
||||
var cancelButtonVisible: Bool = false { didSet { setNeedsLayout() } }
|
||||
|
||||
let containerView = UIView(frame: .zero)
|
||||
let backgroundView = GradientView(direction: .vertical, colors: [
|
||||
@@ -23,6 +32,9 @@ class ToolbarView: UIView
|
||||
let leadingButtonsView = ToolbarButtonContainerView(frame: .zero)
|
||||
let trailingButtonsView = ToolbarButtonContainerView(frame: .zero)
|
||||
|
||||
// Something I'm sure I'll regret: to ensure animation with the keyboard, latch layout until we get the right signal.
|
||||
lazy var layoutLatch = LayoutLatch(self)
|
||||
|
||||
convenience init()
|
||||
{
|
||||
self.init(frame: .zero)
|
||||
@@ -54,6 +66,7 @@ class ToolbarView: UIView
|
||||
|
||||
override func layoutSubviews()
|
||||
{
|
||||
guard !layoutLatch.latched else { return }
|
||||
super.layoutSubviews()
|
||||
|
||||
let shadowPath = UIBezierPath(rect: bounds)
|
||||
|
||||
@@ -153,20 +153,12 @@ class URLBar: ReliefButton
|
||||
textField.font = .systemFont(ofSize: 13.0)
|
||||
textField.clearButtonMode = .never
|
||||
textField.placeholder = "URL or search term"
|
||||
textField.addAction(UIAction(handler: { [unowned self] _ in
|
||||
// Mask view visibility is affected by editing state.
|
||||
self.layoutSubviews()
|
||||
}), for: [ .editingDidBegin, .editingDidEnd ])
|
||||
textField.keyCommands = [
|
||||
UIKeyCommand(action: #selector(Self.downKeyPressed), input: UIKeyCommand.inputDownArrow)
|
||||
.prioritizeOverSystem()
|
||||
]
|
||||
addSubview(textField)
|
||||
|
||||
textField.addAction(.init(handler: { [textField, refreshButton ] _ in
|
||||
refreshButton.isHidden = textField.isFirstResponder
|
||||
}), for: [ .editingDidBegin, .editingDidEnd ])
|
||||
|
||||
refreshButton.tintColor = .secondaryLabel
|
||||
refreshButton.setImage(refreshImage, for: .normal)
|
||||
refreshButton.isPointerInteractionEnabled = true
|
||||
@@ -189,6 +181,7 @@ class URLBar: ReliefButton
|
||||
documentSeparatorView.backgroundColor = .secondarySystemFill
|
||||
addSubview(documentSeparatorView)
|
||||
|
||||
controlsView.autoresizingMask = []
|
||||
controlsView.clearButton.addAction(.init(handler: { [textField] _ in
|
||||
textField.clearText()
|
||||
}), for: .primaryActionTriggered)
|
||||
@@ -346,7 +339,7 @@ class URLBar: ReliefButton
|
||||
documentSeparatorView.frame = documentSeparatorView.frame.insetBy(dx: 0.0, dy: 3.0)
|
||||
|
||||
// Text field controls
|
||||
controlsView.frame = CGRect(origin: .zero, size: controlsView.sizeThatFits(bounds.size))
|
||||
controlsView.frame = CGRect(origin: controlsView.frame.origin, size: controlsView.sizeThatFits(bounds.size))
|
||||
|
||||
// Text field
|
||||
let textFieldPadding: CGFloat = 6.0
|
||||
@@ -365,8 +358,18 @@ class URLBar: ReliefButton
|
||||
let refreshButtonSize = CGSize(width: textField.frame.height, height: textField.frame.height)
|
||||
refreshButton.frame = CGRect(origin: CGPoint(x: bounds.width - refreshButtonSize.width, y: 0), size: refreshButtonSize)
|
||||
|
||||
// Refresh vs. controls view visibility
|
||||
let isFocused = textField.isFirstResponder
|
||||
if isFocused {
|
||||
controlsView.alpha = 1.0
|
||||
refreshButton.alpha = 0.0
|
||||
} else {
|
||||
controlsView.alpha = 0.0
|
||||
refreshButton.alpha = 1.0
|
||||
}
|
||||
|
||||
// Error button
|
||||
if case .error(error: _) = loadProgress, !textField.isFirstResponder {
|
||||
if case .error(error: _) = loadProgress, !isFocused {
|
||||
errorButton.isHidden = false
|
||||
errorButton.sizeToFit()
|
||||
errorButton.frame = CGRect(
|
||||
@@ -384,7 +387,7 @@ class URLBar: ReliefButton
|
||||
// Fade mask
|
||||
fadeMaskView.frame = textField.bounds
|
||||
fadeMaskView.image = fadeBackgroundImageForSize(fadeMaskView.frame.size, cutoffLocation: fadeCutoffLocation)
|
||||
if !textField.isFirstResponder {
|
||||
if !isFocused {
|
||||
textField.mask = fadeMaskView
|
||||
} else {
|
||||
textField.mask = nil
|
||||
|
||||
30
App/Utilities/LayoutLatch.swift
Normal file
30
App/Utilities/LayoutLatch.swift
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// LayoutLatch.swift
|
||||
// App
|
||||
//
|
||||
// Created by James Magahern on 8/10/23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class LayoutLatch {
|
||||
public weak var view: UIView?
|
||||
public private(set) var latched: Bool = false
|
||||
|
||||
init(_ view: UIView) {
|
||||
self.view = view
|
||||
}
|
||||
|
||||
public func activate() {
|
||||
latched = true
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { [weak self] in
|
||||
self?.deactivate()
|
||||
}
|
||||
}
|
||||
|
||||
public func deactivate() {
|
||||
latched = false
|
||||
view?.setNeedsLayout()
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,7 @@
|
||||
CD853BCE24E7763900D2BDCC /* BrowserHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD853BCD24E7763900D2BDCC /* BrowserHistory.swift */; };
|
||||
CD853BD124E778B800D2BDCC /* History.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = CD853BCF24E778B800D2BDCC /* History.xcdatamodeld */; };
|
||||
CD853BD424E77BF900D2BDCC /* HistoryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD853BD324E77BF900D2BDCC /* HistoryItem.swift */; };
|
||||
CD8DBE7B2A85D892006A0FE0 /* LayoutLatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD8DBE7A2A85D892006A0FE0 /* LayoutLatch.swift */; };
|
||||
CD936A3B289DB3380093A1AC /* TabInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD936A3A289DB3380093A1AC /* TabInfo.swift */; };
|
||||
CD936A3D289DB88B0093A1AC /* UIView+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD936A3C289DB88B0093A1AC /* UIView+Utils.swift */; };
|
||||
CD97CF9225D5BE6F00288FEE /* NavigationControlsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD97CF9125D5BE6F00288FEE /* NavigationControlsView.swift */; };
|
||||
@@ -172,6 +173,7 @@
|
||||
CD853BCD24E7763900D2BDCC /* BrowserHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserHistory.swift; sourceTree = "<group>"; };
|
||||
CD853BD024E778B800D2BDCC /* History.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = History.xcdatamodel; sourceTree = "<group>"; };
|
||||
CD853BD324E77BF900D2BDCC /* HistoryItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryItem.swift; sourceTree = "<group>"; };
|
||||
CD8DBE7A2A85D892006A0FE0 /* LayoutLatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutLatch.swift; sourceTree = "<group>"; };
|
||||
CD936A3A289DB3380093A1AC /* TabInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabInfo.swift; sourceTree = "<group>"; };
|
||||
CD936A3C289DB88B0093A1AC /* UIView+Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Utils.swift"; sourceTree = "<group>"; };
|
||||
CD97CF9125D5BE6F00288FEE /* NavigationControlsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationControlsView.swift; sourceTree = "<group>"; };
|
||||
@@ -396,6 +398,7 @@
|
||||
1AB88F0524D4D3A90006F850 /* UIGestureRecognizer+Actions.swift */,
|
||||
CDEDD8A925D62ADB00862605 /* UITraitCollection+MacLike.swift */,
|
||||
CD936A3C289DB88B0093A1AC /* UIView+Utils.swift */,
|
||||
CD8DBE7A2A85D892006A0FE0 /* LayoutLatch.swift */,
|
||||
);
|
||||
path = Utilities;
|
||||
sourceTree = "<group>";
|
||||
@@ -656,6 +659,7 @@
|
||||
CD16844D269E709400B8F8A5 /* Box.swift in Sources */,
|
||||
CD853BCE24E7763900D2BDCC /* BrowserHistory.swift in Sources */,
|
||||
1A03810B24E71C5600826501 /* ToolbarButtonContainerView.swift in Sources */,
|
||||
CD8DBE7B2A85D892006A0FE0 /* LayoutLatch.swift in Sources */,
|
||||
CD7A7EA12686B2E600E20BA3 /* RedirectRulesSettingsViewController.swift in Sources */,
|
||||
1ADFF4CB24CB8278006DC7AE /* ScriptControllerIconView.swift in Sources */,
|
||||
CD7A8915251975B70075991E /* AutocompleteViewController.swift in Sources */,
|
||||
|
||||
Reference in New Issue
Block a user