Move some view functions out of Manager

This commit is contained in:
Gabriel Wong 2017-11-17 11:41:06 +07:00
parent f337cb0070
commit 74e2d8d8a7
6 changed files with 362 additions and 376 deletions

View file

@ -164,7 +164,7 @@ open class InputViewController: UIInputViewController, KeymanWebDelegate {
}
func insertText(_ keymanWeb: KeymanWebViewController, numCharsToDelete: Int, newText: String) {
if Manager.shared.isSubKeysMenuVisible {
if keymanWeb.isSubKeysMenuVisible {
return
}
@ -202,7 +202,7 @@ open class InputViewController: UIInputViewController, KeymanWebDelegate {
}
func menuKeyUp(_ keymanWeb: KeymanWebViewController) {
if Manager.shared.isKeyboardMenuVisible {
if keymanWeb.isKeyboardMenuVisible {
return
}
@ -222,7 +222,7 @@ open class InputViewController: UIInputViewController, KeymanWebDelegate {
switch menuBehaviour {
case .showAlways,
.showIfMultipleKeyboards where keyboardListCount > 1:
Manager.shared.showKeyboardMenu(self, closeButtonTitle: menuCloseButtonTitle)
keymanWeb.showKeyboardMenu(self, closeButtonTitle: menuCloseButtonTitle)
case .showIfMultipleKeyboards, // keyboardListCount() <= 1
.showNever:
break

View file

@ -239,7 +239,7 @@ class KeyboardMenuView: UIView, UITableViewDelegate, UITableViewDataSource, UIGe
}
@objc func tapAction(_ sender: UITapGestureRecognizer) {
Manager.shared.dismissKeyboardMenu()
Manager.shared.keymanWeb.dismissKeyboardMenu()
}
func numberOfSections(in tableView: UITableView) -> Int {
@ -297,7 +297,7 @@ class KeyboardMenuView: UIView, UITableViewDelegate, UITableViewDataSource, UIGe
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switchKeyboard(indexPath.row)
Manager.shared.dismissKeyboardMenu()
Manager.shared.keymanWeb.dismissKeyboardMenu()
}
func getMaxWidth() -> CGFloat {

View file

@ -9,10 +9,29 @@
import UIKit
import WebKit
private let keyboardChangeHelpText = "Tap here to change keyboard"
private let subKeyColor = #colorLiteral(red: 244.0 / 255.0, green: 244.0 / 255.0, blue: 244.0 / 255.0, alpha: 1.0)
private let subKeyColorHighlighted = #colorLiteral(red: 136.0 / 255.0, green: 136.0 / 255.0, blue: 1.0, alpha: 1.0)
// MARK: - UIViewController
class KeymanWebViewController: UIViewController {
weak var delegate: KeymanWebDelegate?
private var useSpecialFont = false
// Views
var webView: WKWebView!
private var helpBubbleView: PopoverView?
private var keyPreviewView: KeyPreviewView?
private var subKeysView: SubKeysView?
private var keyboardMenuView: KeyboardMenuView?
// Arrays
private var subKeyIDs: [String] = []
private var subKeyTexts: [String] = []
private var subKeys: [UIButton] = []
private var subKeyAnchor = CGRect.zero
var frame: CGRect? {
didSet(frame) {
@ -41,6 +60,11 @@ class KeymanWebViewController: UIViewController {
view = webView
// Set UILongPressGestureRecognizer to show sub keys
let hold = UILongPressGestureRecognizer(target: self, action: #selector(self.holdAction))
hold.minimumPressDuration = 0.5
hold.delegate = self
view.addGestureRecognizer(hold)
reloadKeyboard()
}
@ -269,9 +293,192 @@ extension KeymanWebViewController: WKNavigationDelegate {
// MARK: - KeymanWebDelegate
extension KeymanWebViewController: KeymanWebDelegate {
func insertText(_ view: KeymanWebViewController, numCharsToDelete: Int, newText: String) {
dismissHelpBubble()
Manager.shared.isKeymanHelpOn = false
}
func showKeyPreview(_ view: KeymanWebViewController, keyFrame: CGRect, preview: String) {
if UIDevice.current.userInterfaceIdiom == .pad
|| (Util.isSystemKeyboard && !Manager.shared.isSystemKeyboardTopBarEnabled)
|| isSubKeysMenuVisible {
return
}
dismissKeyPreview()
clearSubKeyArrays()
keyPreviewView = KeyPreviewView(frame: keyFrame)
keyPreviewView!.setLabelText(preview)
let keyboardID = Manager.shared.keyboardID!
let languageID = Manager.shared.languageID!
var oskFontName = Manager.shared.oskFontNameForKeyboard(withID: keyboardID, languageID: languageID)
oskFontName = oskFontName ?? Manager.shared.fontNameForKeyboard(withID: keyboardID, languageID: languageID)
keyPreviewView!.setLabelFont(oskFontName)
self.view.addSubview(keyPreviewView!)
}
func dismissKeyPreview(_ view: KeymanWebViewController) {
if UIDevice.current.userInterfaceIdiom == .pad || keyPreviewView == nil {
return
}
let dismissKeyPreview = #selector(self.dismissKeyPreview as () -> Void)
NSObject.cancelPreviousPerformRequests(withTarget: self, selector: dismissKeyPreview, object: nil)
perform(dismissKeyPreview, with: nil, afterDelay: 0.1)
clearSubKeyArrays()
}
func showSubkeys(_ view: KeymanWebViewController,
keyFrame: CGRect,
subkeyIDs: [String],
subkeyTexts: [String],
useSpecialFont: Bool) {
dismissHelpBubble()
Manager.shared.isKeymanHelpOn = false
dismissSubKeys()
dismissKeyboardMenu()
subKeyAnchor = keyFrame
subKeyIDs = subkeyIDs
subKeyTexts = subkeyTexts
self.useSpecialFont = useSpecialFont
}
func menuKeyUp(_ view: KeymanWebViewController) {
dismissHelpBubble()
Manager.shared.isKeymanHelpOn = false
if Util.isSystemKeyboard {
let userData = UserDefaults.standard
userData.set(true, forKey: Key.keyboardPickerDisplayed)
userData.synchronize()
}
}
func hideKeyboard(_ view: KeymanWebViewController) {
dismissHelpBubble()
dismissSubKeys()
dismissKeyboardMenu()
}
}
// MARK: - UIGestureRecognizerDelegate
extension KeymanWebViewController: UIGestureRecognizerDelegate {
// UILongPressGestureRecognizer implementation to show sub keys in a subview
@objc func holdAction(_ sender: UILongPressGestureRecognizer) {
switch sender.state {
case .ended:
// Touch Ended
if let subKeysView = subKeysView {
subKeysView.removeFromSuperview()
subKeysView.subviews.forEach { $0.removeFromSuperview() }
self.subKeysView = nil
setPopupVisible(false)
}
var buttonClicked = false
for button in subKeys where button.isHighlighted {
button.isHighlighted = false
button.backgroundColor = subKeyColor
button.isEnabled = false
button.sendActions(for: .touchUpInside)
buttonClicked = true
break
}
if !buttonClicked {
clearSubKeyArrays()
}
case .began:
// Touch & Hold Began
let touchPoint = sender.location(in: sender.view)
// Check if touch was for language menu button
languageMenuPosition { keyFrame in
if keyFrame.contains(touchPoint) {
self.delegate?.menuKeyHeld(self)
return
}
self.touchHoldBegan()
}
default:
// Hold & Move
guard let subKeysView = subKeysView else {
return
}
let touchPoint = sender.location(in: subKeysView.containerView)
for button in subKeys {
if button.frame.contains(touchPoint) {
button.isEnabled = true
button.isHighlighted = true
button.backgroundColor = subKeyColorHighlighted
} else {
button.isHighlighted = false
button.isEnabled = false
button.backgroundColor = subKeyColor
}
}
}
}
private func touchHoldBegan() {
let isPad = UIDevice.current.userInterfaceIdiom == .pad
let fontSize = isPad ? UIFont.buttonFontSize * 2 : UIFont.buttonFontSize
let keyboardID = Manager.shared.keyboardID!
let languageID = Manager.shared.languageID!
let oskFontName = Manager.shared.oskFontNameForKeyboard(withID: keyboardID, languageID: languageID)
?? Manager.shared.fontNameForKeyboard(withID: keyboardID, languageID: languageID)
if subKeyIDs.isEmpty {
subKeys = []
return
}
subKeys = subKeyTexts.enumerated().map { i, subKeyText in
let button = UIButton(type: .custom)
button.tag = i
button.backgroundColor = subKeyColor
button.setRoundedBorder(withRadius: 4.0, borderWidth: 1.0, color: .gray)
button.setTitleColor(.black, for: .disabled)
button.setTitleColor(.black, for: .highlighted)
if let oskFontName = oskFontName {
button.titleLabel?.font = UIFont(name: oskFontName, size: fontSize)
} else {
button.titleLabel?.font = UIFont.systemFont(ofSize: fontSize)
}
if useSpecialFont {
button.titleLabel?.font = UIFont(name: "KeymanwebOsk", size: fontSize)
button.setTitleColor(.gray, for: .disabled)
}
button.addTarget(self, action: #selector(subKeyButtonClick), for: .touchUpInside)
button.setTitle(subKeyText, for: .normal)
button.tintColor = UIColor(red: 181.0 / 255.0, green: 181.0 / 255.0, blue: 181.0 / 255.0, alpha: 1.0)
button.isEnabled = false
return button
}
dismissKeyPreview()
subKeysView = SubKeysView(keyFrame: subKeyAnchor, subKeys: subKeys)
view.addSubview(subKeysView!)
setPopupVisible(true)
}
@objc func subKeyButtonClick(_ sender: UIButton) {
let keyIndex = sender.tag
if keyIndex < subKeyIDs.count && keyIndex < subKeyTexts.count {
let subKeyID = subKeyIDs[keyIndex]
let subKeyText = subKeyTexts[keyIndex]
executePopupKey(id: subKeyID, text: subKeyText)
}
subKeys.removeAll()
subKeyIDs.removeAll()
subKeyTexts.removeAll()
}
}
// MARK: - Manage views
extension KeymanWebViewController {
func reloadKeyboard() {
if #available(iOS 9.0, *) {
@ -285,4 +492,135 @@ extension KeymanWebViewController {
}
}
@objc func showHelpBubble() {
// Help bubble is always disabled for system-wide keyboard
if Util.isSystemKeyboard || keyboardMenuView != nil {
return
}
languageMenuPosition { keyFrame in
self.showHelpBubble(at: keyFrame.origin)
}
}
// TODO: The bulk of this should be moved to PopoverView
private func showHelpBubble(at point: CGPoint) {
self.helpBubbleView?.removeFromSuperview()
let helpBubbleView = PopoverView(frame: CGRect.zero)
self.helpBubbleView = helpBubbleView
helpBubbleView.backgroundColor = UIColor(red: 253.0 / 255.0, green: 244.0 / 255.0,
blue: 196.0 / 255.0, alpha: 1.0)
helpBubbleView.backgroundColor2 = UIColor(red: 233.0 / 255.0, green: 224.0 / 255.0,
blue: 176.0 / 255.0, alpha: 1.0)
helpBubbleView.borderColor = UIColor(red: 0.5, green: 0.25, blue: 0.25, alpha: 1.0)
let isPad = UIDevice.current.userInterfaceIdiom == .pad
let sizeMultiplier = CGFloat(isPad ? 1.5 : 1.0)
let frameWidth = 90.0 * sizeMultiplier
let frameHeight = (40.0 + helpBubbleView.arrowHeight) * sizeMultiplier
let fontSize = 10.0 * sizeMultiplier
let inputViewFrame = view.frame
let screenWidth = inputViewFrame.size.width
// TODO: Refactor this out
let isPortrait = UIDevice.current.orientation.isPortrait
let adjY: CGFloat
if isPortrait {
adjY = Util.isSystemKeyboard ? 9.0 : 4.0
} else {
adjY = Util.isSystemKeyboard ? 3.0 : 4.0
}
let px = point.x
let py = point.y + adjY + (isPad ? 2.0 : 1.0)
var x = px - frameWidth / 2
let y = py - frameHeight
if x < 0 {
x = 0
} else if x + frameWidth > screenWidth {
x = screenWidth - frameWidth
}
helpBubbleView.frame = CGRect(x: x, y: y, width: frameWidth, height: frameHeight)
if x == 0 {
helpBubbleView.arrowPosX = px
} else if x == screenWidth - frameWidth {
helpBubbleView.arrowPosX = (px - x)
} else {
helpBubbleView.arrowPosX = frameWidth / 2
}
let helpText = UILabel(frame: CGRect(x: 5, y: 0,
width: frameWidth - 10, height: frameHeight - helpBubbleView.arrowHeight))
helpText.backgroundColor = UIColor.clear
helpText.font = helpText.font.withSize(fontSize)
helpText.textAlignment = .center
helpText.textColor = UIColor.darkText
helpText.lineBreakMode = .byWordWrapping
helpText.numberOfLines = 0
helpText.text = keyboardChangeHelpText
helpBubbleView.addSubview(helpText)
view.addSubview(helpBubbleView)
}
func dismissHelpBubble() {
helpBubbleView?.removeFromSuperview()
helpBubbleView = nil
}
@objc func dismissKeyPreview() {
keyPreviewView?.removeFromSuperview()
keyPreviewView = nil
}
var isSubKeysMenuVisible: Bool {
return subKeysView != nil
}
func dismissSubKeys() {
if let subKeysView = subKeysView {
subKeysView.removeFromSuperview()
subKeysView.subviews.forEach { $0.removeFromSuperview() }
self.subKeysView = nil
setPopupVisible(false)
}
clearSubKeyArrays()
}
func clearSubKeyArrays() {
if subKeysView == nil {
subKeys.removeAll()
subKeyIDs.removeAll()
subKeyTexts.removeAll()
}
}
func showHelpBubble(afterDelay delay: TimeInterval) {
helpBubbleView?.removeFromSuperview()
let showHelpBubble = #selector(self.showHelpBubble as () -> Void)
NSObject.cancelPreviousPerformRequests(withTarget: self, selector: showHelpBubble, object: nil)
perform(showHelpBubble, with: nil, afterDelay: delay)
}
func showKeyboardMenu(_ ic: InputViewController, closeButtonTitle: String?) {
let parentView = ic.view ?? view
languageMenuPosition { keyFrame in
if keyFrame != .zero {
self.keyboardMenuView?.removeFromSuperview()
self.keyboardMenuView = KeyboardMenuView(keyFrame: keyFrame, inputViewController: ic,
closeButtonTitle: closeButtonTitle)
parentView?.addSubview(self.keyboardMenuView!)
}
}
}
func dismissKeyboardMenu() {
keyboardMenuView?.removeFromSuperview()
keyboardMenuView = nil
}
var isKeyboardMenuVisible: Bool {
return keyboardMenuView != nil
}
}

View file

@ -22,12 +22,7 @@ public enum KeyboardState {
case none
}
// Strings
private let keyboardChangeHelpText = "Tap here to change keyboard"
// URLs
private let apiBaseURL = "https://r.keymanweb.com/api/4.0/"
private let apiRemoteURL = "https://r.keymanweb.com/api/2.0/remote?url="
private let keymanHostName = "r.keymanweb.com"
// UI In-App Keyboard Constants
@ -100,13 +95,6 @@ public class Manager: NSObject, HTTPDownloadDelegate, UIGestureRecognizerDelegat
let kmw = KeymanWebViewController(nibName: nil, bundle: nil)
kmw.frame = CGRect(origin: .zero, size: keyboardSize)
kmw.delegate = self
// Set UILongPressGestureRecognizer to show sub keys
// TODO: Move to KeymanWebViewController
let hold = UILongPressGestureRecognizer(target: self, action: #selector(self.holdAction))
hold.minimumPressDuration = 0.5
hold.delegate = self
kmw.view.addGestureRecognizer(hold)
return kmw
}()
@ -116,25 +104,6 @@ public class Manager: NSObject, HTTPDownloadDelegate, UIGestureRecognizerDelegat
private var didSynchronize = false
private var didResizeToOrientation = false
private var lastKeyboardSize: CGSize = .zero
private var specialOSKFont: String?
private let subKeyColor = #colorLiteral(red: 244.0 / 255.0, green: 244.0 / 255.0, blue: 244.0 / 255.0, alpha: 1.0)
private let subKeyColorHighlighted = #colorLiteral(red: 136.0 / 255.0, green: 136.0 / 255.0, blue: 1.0, alpha: 1.0)
// Views
private var helpBubbleView: PopoverView?
private var keyPreviewView: KeyPreviewView?
private var subKeysView: SubKeysView?
private var keyboardMenuView: KeyboardMenuView?
// Arrays
private var subKeyIDs: [String] = []
private var subKeyTexts: [String] = []
private var subKeys: [UIButton] = []
// Key frames
private var keyFrame = CGRect.zero
private var menuKeyFrame = CGRect.zero
// MARK: - Object Admin
deinit {
@ -263,10 +232,7 @@ public class Manager: NSObject, HTTPDownloadDelegate, UIGestureRecognizerDelegat
userData.synchronize()
if isKeymanHelpOn {
helpBubbleView?.removeFromSuperview()
let showHelpBubble = #selector(self.showHelpBubble as () -> Void)
NSObject.cancelPreviousPerformRequests(withTarget: self, selector: showHelpBubble, object: nil)
perform(showHelpBubble, with: nil, afterDelay: 1.5)
keymanWeb.showHelpBubble(afterDelay: 1.5)
}
NotificationCenter.default.post(name: Notifications.keyboardChanged,
@ -936,48 +902,6 @@ public class Manager: NSObject, HTTPDownloadDelegate, UIGestureRecognizerDelegat
keymanWeb.setOskHeight(oskHeight)
}
private var keymanScrollView: UIScrollView {
return keymanWeb.webView.scrollView
}
@objc func clearSubKeyArrays() {
if subKeysView == nil {
subKeys.removeAll()
subKeyIDs.removeAll()
subKeyTexts.removeAll()
}
}
@objc func dismissHelpBubble() {
if let view = helpBubbleView {
view.removeFromSuperview()
helpBubbleView = nil
}
}
@objc func dismissKeyPreview() {
if let view = keyPreviewView {
view.removeFromSuperview()
keyPreviewView = nil
}
}
var isSubKeysMenuVisible: Bool {
return subKeysView != nil
}
private func dismissSubKeys() {
if let subKeysView = subKeysView {
subKeysView.removeFromSuperview()
subKeysView.subviews.forEach { $0.removeFromSuperview() }
self.subKeysView = nil
keymanWeb.setPopupVisible(false)
}
subKeys.removeAll()
subKeyIDs.removeAll()
subKeyTexts.removeAll()
}
/// Displays a list of available keyboards and allows a user to add/download new keyboards
/// or remove existing ones.
///
@ -1025,83 +949,6 @@ public class Manager: NSObject, HTTPDownloadDelegate, UIGestureRecognizerDelegat
}
}
@objc func showHelpBubble() {
// Help bubble is always disabled for system-wide keyboard
if Util.isSystemKeyboard || keyboardMenuView != nil {
return
}
keymanWeb.languageMenuPosition { keyFrame in
self.showHelpBubble(at: keyFrame.origin)
}
}
// TODO: The bulk of this should be moved to PopoverView
func showHelpBubble(at point: CGPoint) {
self.helpBubbleView?.removeFromSuperview()
let helpBubbleView = PopoverView(frame: CGRect.zero)
self.helpBubbleView = helpBubbleView
helpBubbleView.backgroundColor = UIColor(red: 253.0 / 255.0, green: 244.0 / 255.0,
blue: 196.0 / 255.0, alpha: 1.0)
helpBubbleView.backgroundColor2 = UIColor(red: 233.0 / 255.0, green: 224.0 / 255.0,
blue: 176.0 / 255.0, alpha: 1.0)
helpBubbleView.borderColor = UIColor(red: 0.5, green: 0.25, blue: 0.25, alpha: 1.0)
let isPad = UIDevice.current.userInterfaceIdiom == .pad
let sizeMultiplier = CGFloat(isPad ? 1.5 : 1.0)
let frameWidth = 90.0 * sizeMultiplier
let frameHeight = (40.0 + helpBubbleView.arrowHeight) * sizeMultiplier
let fontSize = 10.0 * sizeMultiplier
let inputViewFrame = keymanWeb.view.frame
let screenWidth = inputViewFrame.size.width
// TODO: Refactor this out
let isPortrait: Bool
if Util.isSystemKeyboard {
isPortrait = InputViewController.isPortrait
} else {
isPortrait = UIDevice.current.orientation.isPortrait
}
let adjY: CGFloat
if isPortrait {
adjY = Util.isSystemKeyboard ? 9.0 : 4.0
} else {
adjY = Util.isSystemKeyboard ? 3.0 : 4.0
}
let px = point.x
let py = point.y + adjY + (isPad ? 2.0 : 1.0)
var x = px - frameWidth / 2
let y = py - frameHeight
if x < 0 {
x = 0
} else if x + frameWidth > screenWidth {
x = screenWidth - frameWidth
}
helpBubbleView.frame = CGRect(x: x, y: y, width: frameWidth, height: frameHeight)
if x == 0 {
helpBubbleView.arrowPosX = px
} else if x == screenWidth - frameWidth {
helpBubbleView.arrowPosX = (px - x)
} else {
helpBubbleView.arrowPosX = frameWidth / 2
}
let helpText = UILabel(frame: CGRect(x: 5, y: 0,
width: frameWidth - 10, height: frameHeight - helpBubbleView.arrowHeight))
helpText.backgroundColor = UIColor.clear
helpText.font = helpText.font.withSize(fontSize)
helpText.textAlignment = .center
helpText.textColor = UIColor.darkText
helpText.lineBreakMode = .byWordWrapping
helpText.numberOfLines = 0
helpText.text = keyboardChangeHelpText
helpBubbleView.addSubview(helpText)
keymanWeb.view.addSubview(helpBubbleView)
}
@objc func resizeDelay() {
// + 1000 to work around iOS bug with resizing on landscape orientation. Technically we only
// need this for landscape but it doesn't hurt to do it with both. 1000 is a big number that
@ -1155,22 +1002,19 @@ public class Manager: NSObject, HTTPDownloadDelegate, UIGestureRecognizerDelegat
// MARK: - Keyboard Notifications
@objc func keyboardWillShow(_ notification: Notification) {
dismissSubKeys()
dismissKeyPreview()
keymanWeb.dismissSubKeys()
keymanWeb.dismissKeyPreview()
resizeKeyboard()
if isKeymanHelpOn {
helpBubbleView?.removeFromSuperview()
let showHelpBubble = #selector(self.showHelpBubble as () -> Void)
NSObject.cancelPreviousPerformRequests(withTarget: self, selector: showHelpBubble, object: nil)
perform(showHelpBubble, with: nil, afterDelay: 1.5)
keymanWeb.showHelpBubble(afterDelay: 1.5)
}
}
@objc func keyboardWillHide(_ notification: Notification) {
dismissHelpBubble()
dismissSubKeys()
dismissKeyPreview()
keymanWeb.dismissHelpBubble()
keymanWeb.dismissSubKeys()
keymanWeb.dismissKeyPreview()
}
// MARK: - KeymanWebViewDelegate methods
@ -1206,43 +1050,14 @@ public class Manager: NSObject, HTTPDownloadDelegate, UIGestureRecognizerDelegat
func insertText(_ keymanWeb: KeymanWebViewController, numCharsToDelete: Int, newText: String) {
keymanWebDelegate?.insertText(keymanWeb, numCharsToDelete: numCharsToDelete, newText: newText)
dismissHelpBubble()
isKeymanHelpOn = false
}
func showKeyPreview(_ keymanWeb: KeymanWebViewController, keyFrame: CGRect, preview: String) {
keymanWebDelegate?.showKeyPreview(keymanWeb, keyFrame: keyFrame, preview: preview)
if UIDevice.current.userInterfaceIdiom == .pad
|| (Util.isSystemKeyboard && !isSystemKeyboardTopBarEnabled)
|| subKeysView != nil {
return
}
dismissKeyPreview()
clearSubKeyArrays()
keyPreviewView = KeyPreviewView(frame: keyFrame)
keyPreviewView!.setLabelText(preview)
var oskFontName = oskFontNameForKeyboard(withID: keyboardID!, languageID: languageID!)
oskFontName = oskFontName ?? fontNameForKeyboard(withID: keyboardID!, languageID: languageID!)
keyPreviewView!.setLabelFont(oskFontName)
keymanWeb.view.addSubview(keyPreviewView!)
}
func dismissKeyPreview(_ keymanWeb: KeymanWebViewController) {
keymanWebDelegate?.dismissKeyPreview(keymanWeb)
if UIDevice.current.userInterfaceIdiom == .pad || keyPreviewView == nil {
return
}
let dismissKeyPreview = #selector(self.dismissKeyPreview as () -> Void)
NSObject.cancelPreviousPerformRequests(withTarget: self, selector: dismissKeyPreview, object: nil)
perform(dismissKeyPreview, with: nil, afterDelay: 0.1)
clearSubKeyArrays()
}
func showSubkeys(_ keymanWeb: KeymanWebViewController,
@ -1255,15 +1070,6 @@ public class Manager: NSObject, HTTPDownloadDelegate, UIGestureRecognizerDelegat
subkeyIDs: subkeyIDs,
subkeyTexts: subkeyTexts,
useSpecialFont: useSpecialFont)
dismissHelpBubble()
isKeymanHelpOn = false
dismissSubKeys()
dismissKeyboardMenu()
self.keyFrame = keyFrame
subKeyIDs = subkeyIDs
subKeyTexts = subkeyTexts
}
func menuKeyDown(_ keymanWeb: KeymanWebViewController) {
@ -1272,156 +1078,25 @@ public class Manager: NSObject, HTTPDownloadDelegate, UIGestureRecognizerDelegat
func menuKeyUp(_ keymanWeb: KeymanWebViewController) {
keymanWebDelegate?.menuKeyUp(keymanWeb)
dismissHelpBubble()
isKeymanHelpOn = false
if Util.isSystemKeyboard {
let userData = UserDefaults.standard
userData.set(true, forKey: Key.keyboardPickerDisplayed)
userData.synchronize()
}
}
func hideKeyboard(_ keymanWeb: KeymanWebViewController) {
keymanWebDelegate?.hideKeyboard(keymanWeb)
dismissHelpBubble()
dismissSubKeys()
dismissKeyboardMenu()
}
// MARK: - UIGestureRecognizer
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
// UILongPressGestureRecognizer implementation to show sub keys in a subview
@objc func holdAction(_ sender: UILongPressGestureRecognizer) {
switch sender.state {
case .ended:
// Touch Ended
if let subKeysView = subKeysView {
subKeysView.removeFromSuperview()
subKeysView.subviews.forEach { $0.removeFromSuperview() }
self.subKeysView = nil
keymanWeb.setPopupVisible(false)
}
var buttonClicked = false
for button in subKeys where button.isHighlighted {
button.isHighlighted = false
button.backgroundColor = subKeyColor
button.isEnabled = false
button.sendActions(for: .touchUpInside)
buttonClicked = true
break
}
if !buttonClicked {
clearSubKeyArrays()
}
case .began:
// Touch & Hold Began
let touchPoint = sender.location(in: sender.view)
// Check if touch was for language menu button
keymanWeb.languageMenuPosition { keyFrame in
self.menuKeyFrame = keyFrame
if keyFrame.contains(touchPoint) {
self.keymanWebDelegate?.menuKeyHeld(self.keymanWeb)
return
}
self.touchHoldBegan()
}
default:
// Hold & Move
guard let subKeysView = subKeysView else {
return
}
let touchPoint = sender.location(in: subKeysView.containerView)
for button in subKeys {
if button.frame.contains(touchPoint) {
button.isEnabled = true
button.isHighlighted = true
button.backgroundColor = subKeyColorHighlighted
} else {
button.isHighlighted = false
button.isEnabled = false
button.backgroundColor = subKeyColor
}
}
}
}
private func touchHoldBegan() {
let isPad = UIDevice.current.userInterfaceIdiom == .pad
let fontSize = isPad ? UIFont.buttonFontSize * 2 : UIFont.buttonFontSize
var oskFontName = oskFontNameForKeyboard(withID: keyboardID!, languageID: languageID!)
if oskFontName == nil {
oskFontName = fontNameForKeyboard(withID: keyboardID!, languageID: languageID!)
}
if subKeyIDs.isEmpty {
subKeys = []
return
}
subKeys = subKeyTexts.enumerated().map { i, subKeyText in
let button = UIButton(type: .custom)
button.tag = i
button.backgroundColor = subKeyColor
button.setRoundedBorder(withRadius: 4.0, borderWidth: 1.0, color: .gray)
button.setTitleColor(.black, for: .disabled)
button.setTitleColor(.black, for: .highlighted)
if let oskFontName = oskFontName {
button.titleLabel?.font = UIFont(name: oskFontName, size: fontSize)
} else {
button.titleLabel?.font = UIFont.systemFont(ofSize: fontSize)
}
if specialOSKFont != nil {
button.titleLabel?.font = UIFont(name: "KeymanwebOsk", size: fontSize)
button.setTitleColor(.gray, for: .disabled)
}
button.addTarget(self, action: #selector(subKeyButtonClick), for: .touchUpInside)
button.setTitle(subKeyText, for: .normal)
button.tintColor = UIColor(red: 181.0 / 255.0, green: 181.0 / 255.0, blue: 181.0 / 255.0, alpha: 1.0)
button.isEnabled = false
return button
}
dismissKeyPreview()
subKeysView = SubKeysView(keyFrame: keyFrame, subKeys: subKeys)
keymanWeb.view.addSubview(subKeysView!)
keymanWeb.setPopupVisible(true)
}
@objc func subKeyButtonClick(_ sender: UIButton) {
let keyIndex = sender.tag
if keyIndex < subKeyIDs.count && keyIndex < subKeyTexts.count {
let subKeyID = subKeyIDs[keyIndex]
let subKeyText = subKeyTexts[keyIndex]
keymanWeb.executePopupKey(id: subKeyID, text: subKeyText)
}
subKeys.removeAll()
subKeyIDs.removeAll()
subKeyTexts.removeAll()
}
// MARK: - InputViewController methods
// TODO: Manager should not have InputViewController methods. Move this into InputViewController.
func updateViewConstraints() {
dismissSubKeys()
dismissKeyPreview()
dismissKeyboardMenu()
keymanWeb.dismissSubKeys()
keymanWeb.dismissKeyPreview()
keymanWeb.dismissKeyboardMenu()
resizeKeyboardIfNeeded()
}
func inputViewDidLoad() {
dismissSubKeys()
dismissKeyPreview()
dismissKeyboardMenu()
keymanWeb.dismissSubKeys()
keymanWeb.dismissKeyPreview()
keymanWeb.dismissKeyboardMenu()
resizeKeyboard()
let activeUserDef = Storage.active.userDefaults
@ -1454,43 +1129,16 @@ public class Manager: NSObject, HTTPDownloadDelegate, UIGestureRecognizerDelegat
// FIXME: This is deprecated. Use inputViewWillTransition()
func inputViewWillRotate(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval) {
dismissSubKeys()
dismissKeyPreview()
dismissKeyboardMenu()
keymanWeb.dismissSubKeys()
keymanWeb.dismissKeyPreview()
keymanWeb.dismissKeyboardMenu()
resizeKeyboard(with: toInterfaceOrientation)
if isKeymanHelpOn {
helpBubbleView?.removeFromSuperview()
let showHelpBubble = #selector(self.showHelpBubble as () -> Void)
NSObject.cancelPreviousPerformRequests(withTarget: self, selector: showHelpBubble, object: nil)
perform(showHelpBubble, with: nil, afterDelay: 1.5)
keymanWeb.showHelpBubble(afterDelay: 1.5)
}
didResizeToOrientation = true
}
func showKeyboardMenu(_ ic: InputViewController, closeButtonTitle: String?) {
let parentView = ic.view ?? keymanWeb.view
keymanWeb.languageMenuPosition { keyFrame in
self.menuKeyFrame = keyFrame
if keyFrame != .zero {
self.keyboardMenuView?.removeFromSuperview()
self.keyboardMenuView = KeyboardMenuView(keyFrame: self.menuKeyFrame, inputViewController: ic,
closeButtonTitle: closeButtonTitle)
parentView?.addSubview(self.keyboardMenuView!)
}
}
}
func dismissKeyboardMenu() {
if let keyboardMenuView = keyboardMenuView {
keyboardMenuView.removeFromSuperview()
self.keyboardMenuView = nil
}
}
var isKeyboardMenuVisible: Bool {
return keyboardMenuView != nil
}
var isSystemKeyboardTopBarEnabled: Bool {
return true
}

View file

@ -187,7 +187,7 @@ public class TextField: UITextField {
// MARK: - KeymanWebDelegate
extension TextField: KeymanWebDelegate {
func insertText(_ keymanWeb: KeymanWebViewController, numCharsToDelete: Int, newText: String) {
if Manager.shared.isSubKeysMenuVisible {
if keymanWeb.isSubKeysMenuVisible {
return
}

View file

@ -188,7 +188,7 @@ public class TextView: UITextView {
// MARK: - KeymanWebDelegate
extension TextView: KeymanWebDelegate {
func insertText(_ keymanWeb: KeymanWebViewController, numCharsToDelete: Int, newText: String) {
if Manager.shared.isSubKeysMenuVisible {
if keymanWeb.isSubKeysMenuVisible {
return
}