From b9157af2b28e8d9c7e4f7b22ef1e57fa8cc78f77 Mon Sep 17 00:00:00 2001 From: James Magahern Date: Fri, 18 Feb 2022 19:05:12 -0800 Subject: [PATCH] URLBar: Adds autocorrect toggle button for url bar --- App/Titlebar and URL Bar/URLBar.swift | 75 ++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/App/Titlebar and URL Bar/URLBar.swift b/App/Titlebar and URL Bar/URLBar.swift index f7ab655..e087b6e 100644 --- a/App/Titlebar and URL Bar/URLBar.swift +++ b/App/Titlebar and URL Bar/URLBar.swift @@ -21,6 +21,59 @@ class TextFieldWithKeyCommands: UITextField } } +class TextFieldControlsView: UIView +{ + let clearButton = UIButton(frame: .zero) + let autocorrectButton = UIButton(frame: .zero) + + static let padding = CGFloat(4.0) + static let spacing = CGFloat(2.0) + + init() { + super.init(frame: .zero) + + var clearButtonConfig = UIButton.Configuration.borderless() + clearButtonConfig.image = .init(systemName: "xmark.circle.fill") + clearButtonConfig.preferredSymbolConfigurationForImage = UIImage.SymbolConfiguration.init(pointSize: 12.0) + clearButton.configuration = clearButtonConfig + clearButton.tintColor = .secondaryLabel + clearButton.translatesAutoresizingMaskIntoConstraints = false + addSubview(clearButton) + + var autocorrectButtonConfig = UIButton.Configuration.borderedTinted() + autocorrectButtonConfig.image = .init(systemName: "textformat") + autocorrectButton.changesSelectionAsPrimaryAction = true + autocorrectButton.configuration = autocorrectButtonConfig + autocorrectButton.translatesAutoresizingMaskIntoConstraints = false + addSubview(autocorrectButton) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func sizeThatFits(_ size: CGSize) -> CGSize { + CGSize(width: (size.height * 2) + Self.spacing, height: size.height) + } + + override func layoutSubviews() { + super.layoutSubviews() + + let size = bounds.height + autocorrectButton.frame = CGRect( + x: bounds.width - size, + y: 0.0, + width: size, height: size + ).insetBy(dx: Self.padding, dy: Self.padding) + + clearButton.frame = CGRect( + x: autocorrectButton.frame.minX - size - Self.spacing, + y: 0.0, + width: size, height: size + ).insetBy(dx: Self.padding, dy: Self.padding) + } +} + class URLBar: ReliefButton { let textField = TextFieldWithKeyCommands(frame: .zero) @@ -28,6 +81,8 @@ class URLBar: ReliefButton let errorButton = UIButton(frame: .zero) let documentButton = UIButton(frame: .zero) + let controlsView = TextFieldControlsView() + weak var delegate: URLBarDelegate? public enum LoadProgress: Equatable { @@ -96,7 +151,7 @@ class URLBar: ReliefButton textField.autocorrectionType = .no textField.autocapitalizationType = .none textField.font = .systemFont(ofSize: 13.0) - textField.clearButtonMode = .whileEditing + textField.clearButtonMode = .never textField.placeholder = "URL or search term" textField.addAction(UIAction(handler: { [unowned self] _ in // Mask view visibility is affected by editing state. @@ -108,7 +163,7 @@ class URLBar: ReliefButton ] addSubview(textField) - textField.addAction(.init(handler: { [textField, refreshButton] _ in + textField.addAction(.init(handler: { [textField, refreshButton ] _ in refreshButton.isHidden = textField.isFirstResponder }), for: [ .editingDidBegin, .editingDidEnd ]) @@ -134,6 +189,17 @@ class URLBar: ReliefButton documentSeparatorView.backgroundColor = .secondarySystemFill addSubview(documentSeparatorView) + controlsView.clearButton.addAction(.init(handler: { [textField] _ in + textField.clearText() + }), for: .primaryActionTriggered) + + controlsView.autocorrectButton.addAction(.init(handler: { [unowned self] _ in + self.setAutocorrectEnabled(controlsView.autocorrectButton.isSelected) + }), for: .touchUpInside) + + textField.rightView = controlsView + textField.rightViewMode = .whileEditing + setErrorButtonAnimating(false) } @@ -146,6 +212,11 @@ class URLBar: ReliefButton self.delegate?.urlBarRequestedFocusEscape(self) } + private func setAutocorrectEnabled(_ enabled: Bool) { + textField.autocorrectionType = enabled ? .yes : .no + textField.reloadInputViews() + } + private func updateProgressIndicator() { setErrorButtonAnimating(false)