mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-07 08:18:41 +09:00
Dactyloidae iOS initial commit
This commit is contained in:
parent
daa6179d22
commit
7154a0497e
2123 changed files with 197052 additions and 0 deletions
126
mobile/ios/Shared/KeyboardHelper.swift
Normal file
126
mobile/ios/Shared/KeyboardHelper.swift
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import UIKit
|
||||
import Foundation
|
||||
|
||||
/**
|
||||
* The keyboard state at the time of notification.
|
||||
*/
|
||||
public struct KeyboardState {
|
||||
public let animationDuration: Double
|
||||
public let animationCurve: UIViewAnimationCurve
|
||||
private let userInfo: [AnyHashable: Any]
|
||||
|
||||
fileprivate init(_ userInfo: [AnyHashable: Any]) {
|
||||
self.userInfo = userInfo
|
||||
animationDuration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as! Double
|
||||
// HACK: UIViewAnimationCurve doesn't expose the keyboard animation used (curveValue = 7),
|
||||
// so UIViewAnimationCurve(rawValue: curveValue) returns nil. As a workaround, get a
|
||||
// reference to an EaseIn curve, then change the underlying pointer data with that ref.
|
||||
var curve = UIViewAnimationCurve.easeIn
|
||||
if let curveValue = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int {
|
||||
NSNumber(value: curveValue as Int).getValue(&curve)
|
||||
}
|
||||
self.animationCurve = curve
|
||||
}
|
||||
|
||||
/// Return the height of the keyboard that overlaps with the specified view. This is more
|
||||
/// accurate than simply using the height of UIKeyboardFrameBeginUserInfoKey since for example
|
||||
/// on iPad the overlap may be partial or if an external keyboard is attached, the intersection
|
||||
/// height will be zero. (Even if the height of the *invisible* keyboard will look normal!)
|
||||
public func intersectionHeightForView(_ view: UIView) -> CGFloat {
|
||||
if let keyboardFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue {
|
||||
let keyboardFrame = keyboardFrameValue.cgRectValue
|
||||
let convertedKeyboardFrame = view.convert(keyboardFrame, from: nil)
|
||||
let intersection = convertedKeyboardFrame.intersection(view.bounds)
|
||||
return intersection.size.height
|
||||
}
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
public protocol KeyboardHelperDelegate: class {
|
||||
func keyboardHelper(_ keyboardHelper: KeyboardHelper, keyboardWillShowWithState state: KeyboardState)
|
||||
func keyboardHelper(_ keyboardHelper: KeyboardHelper, keyboardDidShowWithState state: KeyboardState)
|
||||
func keyboardHelper(_ keyboardHelper: KeyboardHelper, keyboardWillHideWithState state: KeyboardState)
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience class for observing keyboard state.
|
||||
*/
|
||||
open class KeyboardHelper: NSObject {
|
||||
open var currentState: KeyboardState?
|
||||
|
||||
fileprivate var delegates = [WeakKeyboardDelegate]()
|
||||
|
||||
open class var defaultHelper: KeyboardHelper {
|
||||
struct Singleton {
|
||||
static let instance = KeyboardHelper()
|
||||
}
|
||||
return Singleton.instance
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts monitoring the keyboard state.
|
||||
*/
|
||||
open func startObserving() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(KeyboardHelper.SELkeyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(KeyboardHelper.SELkeyboardDidShow(_:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(KeyboardHelper.SELkeyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a delegate to the helper.
|
||||
* Delegates are weakly held.
|
||||
*/
|
||||
open func addDelegate(_ delegate: KeyboardHelperDelegate) {
|
||||
// Reuse any existing slots that have been deallocated.
|
||||
for weakDelegate in delegates where weakDelegate.delegate == nil {
|
||||
weakDelegate.delegate = delegate
|
||||
return
|
||||
}
|
||||
|
||||
delegates.append(WeakKeyboardDelegate(delegate))
|
||||
}
|
||||
|
||||
func SELkeyboardWillShow(_ notification: Notification) {
|
||||
if let userInfo = notification.userInfo {
|
||||
currentState = KeyboardState(userInfo)
|
||||
for weakDelegate in delegates {
|
||||
weakDelegate.delegate?.keyboardHelper(self, keyboardWillShowWithState: currentState!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SELkeyboardDidShow(_ notification: Notification) {
|
||||
if let userInfo = notification.userInfo {
|
||||
currentState = KeyboardState(userInfo)
|
||||
for weakDelegate in delegates {
|
||||
weakDelegate.delegate?.keyboardHelper(self, keyboardDidShowWithState: currentState!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SELkeyboardWillHide(_ notification: Notification) {
|
||||
if let userInfo = notification.userInfo {
|
||||
currentState = KeyboardState(userInfo)
|
||||
for weakDelegate in delegates {
|
||||
weakDelegate.delegate?.keyboardHelper(self, keyboardWillHideWithState: currentState!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class WeakKeyboardDelegate {
|
||||
weak var delegate: KeyboardHelperDelegate?
|
||||
|
||||
init(_ delegate: KeyboardHelperDelegate) {
|
||||
self.delegate = delegate
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue