Another attempt to fix empty URL bar
This commit is contained in:
@@ -98,6 +98,7 @@ class BrowserView: UIView
|
|||||||
}
|
}
|
||||||
}(animationCurve)
|
}(animationCurve)
|
||||||
|
|
||||||
|
toolbarView?.layoutLatch.deactivate()
|
||||||
keyboardLayoutOffset = bounds.height - keyboardEndFrame.minY
|
keyboardLayoutOffset = bounds.height - keyboardEndFrame.minY
|
||||||
UIView.animate(withDuration: animationDuration, delay: 0.0, options: animationOptions, animations: { self.layoutIfNeeded() }, completion: nil)
|
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.alpha = 0.28
|
||||||
shadowView.backgroundColor = UIColor(white: 0.0, alpha: 1.0)
|
shadowView.backgroundColor = UIColor(white: 0.0, alpha: 1.0)
|
||||||
shadowView.isUserInteractionEnabled = false
|
shadowView.isUserInteractionEnabled = false
|
||||||
@@ -132,8 +134,6 @@ class ReliefButton: UIButton
|
|||||||
}
|
}
|
||||||
|
|
||||||
override func layoutSubviews() {
|
override func layoutSubviews() {
|
||||||
self.imageView?.contentMode = .scaleAspectFit
|
|
||||||
|
|
||||||
super.layoutSubviews()
|
super.layoutSubviews()
|
||||||
|
|
||||||
sendSubviewToBack(backgroundView)
|
sendSubviewToBack(backgroundView)
|
||||||
|
|||||||
@@ -9,9 +9,18 @@ import UIKit
|
|||||||
|
|
||||||
class ToolbarView: UIView
|
class ToolbarView: UIView
|
||||||
{
|
{
|
||||||
var urlBar: URLBar? { didSet { containerView.addSubview(urlBar!) } }
|
var urlBar: URLBar? {
|
||||||
|
didSet {
|
||||||
|
guard let urlBar else { return }
|
||||||
|
containerView.addSubview(urlBar)
|
||||||
|
|
||||||
var cancelButtonVisible: Bool = false { didSet { layoutSubviews() } }
|
urlBar.textField.addAction(.init(handler: { [unowned self] _ in
|
||||||
|
layoutLatch.activate()
|
||||||
|
}), for: [ .editingDidBegin, .editingDidEnd ])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var cancelButtonVisible: Bool = false { didSet { setNeedsLayout() } }
|
||||||
|
|
||||||
let containerView = UIView(frame: .zero)
|
let containerView = UIView(frame: .zero)
|
||||||
let backgroundView = GradientView(direction: .vertical, colors: [
|
let backgroundView = GradientView(direction: .vertical, colors: [
|
||||||
@@ -23,6 +32,9 @@ class ToolbarView: UIView
|
|||||||
let leadingButtonsView = ToolbarButtonContainerView(frame: .zero)
|
let leadingButtonsView = ToolbarButtonContainerView(frame: .zero)
|
||||||
let trailingButtonsView = 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()
|
convenience init()
|
||||||
{
|
{
|
||||||
self.init(frame: .zero)
|
self.init(frame: .zero)
|
||||||
@@ -54,6 +66,7 @@ class ToolbarView: UIView
|
|||||||
|
|
||||||
override func layoutSubviews()
|
override func layoutSubviews()
|
||||||
{
|
{
|
||||||
|
guard !layoutLatch.latched else { return }
|
||||||
super.layoutSubviews()
|
super.layoutSubviews()
|
||||||
|
|
||||||
let shadowPath = UIBezierPath(rect: bounds)
|
let shadowPath = UIBezierPath(rect: bounds)
|
||||||
|
|||||||
@@ -153,20 +153,12 @@ class URLBar: ReliefButton
|
|||||||
textField.font = .systemFont(ofSize: 13.0)
|
textField.font = .systemFont(ofSize: 13.0)
|
||||||
textField.clearButtonMode = .never
|
textField.clearButtonMode = .never
|
||||||
textField.placeholder = "URL or search term"
|
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 = [
|
textField.keyCommands = [
|
||||||
UIKeyCommand(action: #selector(Self.downKeyPressed), input: UIKeyCommand.inputDownArrow)
|
UIKeyCommand(action: #selector(Self.downKeyPressed), input: UIKeyCommand.inputDownArrow)
|
||||||
.prioritizeOverSystem()
|
.prioritizeOverSystem()
|
||||||
]
|
]
|
||||||
addSubview(textField)
|
addSubview(textField)
|
||||||
|
|
||||||
textField.addAction(.init(handler: { [textField, refreshButton ] _ in
|
|
||||||
refreshButton.isHidden = textField.isFirstResponder
|
|
||||||
}), for: [ .editingDidBegin, .editingDidEnd ])
|
|
||||||
|
|
||||||
refreshButton.tintColor = .secondaryLabel
|
refreshButton.tintColor = .secondaryLabel
|
||||||
refreshButton.setImage(refreshImage, for: .normal)
|
refreshButton.setImage(refreshImage, for: .normal)
|
||||||
refreshButton.isPointerInteractionEnabled = true
|
refreshButton.isPointerInteractionEnabled = true
|
||||||
@@ -189,6 +181,7 @@ class URLBar: ReliefButton
|
|||||||
documentSeparatorView.backgroundColor = .secondarySystemFill
|
documentSeparatorView.backgroundColor = .secondarySystemFill
|
||||||
addSubview(documentSeparatorView)
|
addSubview(documentSeparatorView)
|
||||||
|
|
||||||
|
controlsView.autoresizingMask = []
|
||||||
controlsView.clearButton.addAction(.init(handler: { [textField] _ in
|
controlsView.clearButton.addAction(.init(handler: { [textField] _ in
|
||||||
textField.clearText()
|
textField.clearText()
|
||||||
}), for: .primaryActionTriggered)
|
}), for: .primaryActionTriggered)
|
||||||
@@ -346,7 +339,7 @@ class URLBar: ReliefButton
|
|||||||
documentSeparatorView.frame = documentSeparatorView.frame.insetBy(dx: 0.0, dy: 3.0)
|
documentSeparatorView.frame = documentSeparatorView.frame.insetBy(dx: 0.0, dy: 3.0)
|
||||||
|
|
||||||
// Text field controls
|
// 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
|
// Text field
|
||||||
let textFieldPadding: CGFloat = 6.0
|
let textFieldPadding: CGFloat = 6.0
|
||||||
@@ -365,8 +358,18 @@ class URLBar: ReliefButton
|
|||||||
let refreshButtonSize = CGSize(width: textField.frame.height, height: textField.frame.height)
|
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)
|
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
|
// Error button
|
||||||
if case .error(error: _) = loadProgress, !textField.isFirstResponder {
|
if case .error(error: _) = loadProgress, !isFocused {
|
||||||
errorButton.isHidden = false
|
errorButton.isHidden = false
|
||||||
errorButton.sizeToFit()
|
errorButton.sizeToFit()
|
||||||
errorButton.frame = CGRect(
|
errorButton.frame = CGRect(
|
||||||
@@ -384,7 +387,7 @@ class URLBar: ReliefButton
|
|||||||
// Fade mask
|
// Fade mask
|
||||||
fadeMaskView.frame = textField.bounds
|
fadeMaskView.frame = textField.bounds
|
||||||
fadeMaskView.image = fadeBackgroundImageForSize(fadeMaskView.frame.size, cutoffLocation: fadeCutoffLocation)
|
fadeMaskView.image = fadeBackgroundImageForSize(fadeMaskView.frame.size, cutoffLocation: fadeCutoffLocation)
|
||||||
if !textField.isFirstResponder {
|
if !isFocused {
|
||||||
textField.mask = fadeMaskView
|
textField.mask = fadeMaskView
|
||||||
} else {
|
} else {
|
||||||
textField.mask = nil
|
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 */; };
|
CD853BCE24E7763900D2BDCC /* BrowserHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD853BCD24E7763900D2BDCC /* BrowserHistory.swift */; };
|
||||||
CD853BD124E778B800D2BDCC /* History.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = CD853BCF24E778B800D2BDCC /* History.xcdatamodeld */; };
|
CD853BD124E778B800D2BDCC /* History.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = CD853BCF24E778B800D2BDCC /* History.xcdatamodeld */; };
|
||||||
CD853BD424E77BF900D2BDCC /* HistoryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD853BD324E77BF900D2BDCC /* HistoryItem.swift */; };
|
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 */; };
|
CD936A3B289DB3380093A1AC /* TabInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD936A3A289DB3380093A1AC /* TabInfo.swift */; };
|
||||||
CD936A3D289DB88B0093A1AC /* UIView+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD936A3C289DB88B0093A1AC /* UIView+Utils.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 */; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
CD97CF9125D5BE6F00288FEE /* NavigationControlsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationControlsView.swift; sourceTree = "<group>"; };
|
||||||
@@ -396,6 +398,7 @@
|
|||||||
1AB88F0524D4D3A90006F850 /* UIGestureRecognizer+Actions.swift */,
|
1AB88F0524D4D3A90006F850 /* UIGestureRecognizer+Actions.swift */,
|
||||||
CDEDD8A925D62ADB00862605 /* UITraitCollection+MacLike.swift */,
|
CDEDD8A925D62ADB00862605 /* UITraitCollection+MacLike.swift */,
|
||||||
CD936A3C289DB88B0093A1AC /* UIView+Utils.swift */,
|
CD936A3C289DB88B0093A1AC /* UIView+Utils.swift */,
|
||||||
|
CD8DBE7A2A85D892006A0FE0 /* LayoutLatch.swift */,
|
||||||
);
|
);
|
||||||
path = Utilities;
|
path = Utilities;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -656,6 +659,7 @@
|
|||||||
CD16844D269E709400B8F8A5 /* Box.swift in Sources */,
|
CD16844D269E709400B8F8A5 /* Box.swift in Sources */,
|
||||||
CD853BCE24E7763900D2BDCC /* BrowserHistory.swift in Sources */,
|
CD853BCE24E7763900D2BDCC /* BrowserHistory.swift in Sources */,
|
||||||
1A03810B24E71C5600826501 /* ToolbarButtonContainerView.swift in Sources */,
|
1A03810B24E71C5600826501 /* ToolbarButtonContainerView.swift in Sources */,
|
||||||
|
CD8DBE7B2A85D892006A0FE0 /* LayoutLatch.swift in Sources */,
|
||||||
CD7A7EA12686B2E600E20BA3 /* RedirectRulesSettingsViewController.swift in Sources */,
|
CD7A7EA12686B2E600E20BA3 /* RedirectRulesSettingsViewController.swift in Sources */,
|
||||||
1ADFF4CB24CB8278006DC7AE /* ScriptControllerIconView.swift in Sources */,
|
1ADFF4CB24CB8278006DC7AE /* ScriptControllerIconView.swift in Sources */,
|
||||||
CD7A8915251975B70075991E /* AutocompleteViewController.swift in Sources */,
|
CD7A8915251975B70075991E /* AutocompleteViewController.swift in Sources */,
|
||||||
|
|||||||
Reference in New Issue
Block a user