完善任务流程、键盘适配与页面交互
This commit is contained in:
14
Pods/IQKeyboardNotification/IQKeyboardNotification/Assets/PrivacyInfo.xcprivacy
generated
Normal file
14
Pods/IQKeyboardNotification/IQKeyboardNotification/Assets/PrivacyInfo.xcprivacy
generated
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyTrackingDomains</key>
|
||||
<array/>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
243
Pods/IQKeyboardNotification/IQKeyboardNotification/Classes/IQKeyboardInfo.swift
generated
Normal file
243
Pods/IQKeyboardNotification/IQKeyboardNotification/Classes/IQKeyboardInfo.swift
generated
Normal file
@ -0,0 +1,243 @@
|
||||
//
|
||||
// IQKeyboardInfo.swift
|
||||
// https://github.com/hackiftekhar/IQKeyboardNotification
|
||||
// Copyright (c) 2013-24 Iftekhar Qurashi.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
import UIKit
|
||||
|
||||
@available(iOSApplicationExtension, unavailable)
|
||||
public struct IQKeyboardInfo: Equatable {
|
||||
nonisolated public static func == (lhs: Self, rhs: Self) -> Bool {
|
||||
lhs.event == rhs.event &&
|
||||
lhs.endFrame.equalTo(rhs.endFrame)
|
||||
}
|
||||
|
||||
@objc public enum Event: Int, CaseIterable {
|
||||
case willShow
|
||||
case didShow
|
||||
case willChangeFrame
|
||||
case didChangeFrame
|
||||
case willHide
|
||||
case didHide
|
||||
|
||||
@MainActor
|
||||
public var notification: Notification.Name {
|
||||
switch self {
|
||||
case .willShow:
|
||||
return UIResponder.keyboardWillShowNotification
|
||||
case .didShow:
|
||||
return UIResponder.keyboardDidShowNotification
|
||||
case .willChangeFrame:
|
||||
return UIResponder.keyboardWillChangeFrameNotification
|
||||
case .didChangeFrame:
|
||||
return UIResponder.keyboardDidChangeFrameNotification
|
||||
case .willHide:
|
||||
return UIResponder.keyboardWillHideNotification
|
||||
case .didHide:
|
||||
return UIResponder.keyboardDidHideNotification
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public let event: Event
|
||||
|
||||
/// `keyboardIsLocalUserInfoKey`.
|
||||
public let isLocal: Bool
|
||||
|
||||
/// `UIKeyboardFrameBeginUserInfoKey`.
|
||||
public let beginFrame: CGRect
|
||||
|
||||
/// `UIKeyboardFrameEndUserInfoKey`.
|
||||
public let endFrame: CGRect
|
||||
|
||||
/// `UIKeyboardAnimationDurationUserInfoKey`.
|
||||
public let animationDuration: TimeInterval
|
||||
|
||||
/// `UIKeyboardAnimationCurveUserInfoKey`.
|
||||
public let animationCurve: UIView.AnimationCurve
|
||||
|
||||
public var animationOptions: UIView.AnimationOptions {
|
||||
return UIView.AnimationOptions(rawValue: UInt(animationCurve.rawValue << 16))
|
||||
}
|
||||
|
||||
public var isVisible: Bool {
|
||||
endFrame.height > 0
|
||||
}
|
||||
|
||||
internal init(notification: Notification?, event: Event) {
|
||||
self.event = event
|
||||
|
||||
let screenBounds: CGRect
|
||||
if let screen: UIScreen = notification?.object as? UIScreen {
|
||||
screenBounds = screen.bounds
|
||||
} else {
|
||||
screenBounds = UIScreen.main.bounds
|
||||
}
|
||||
|
||||
if let info: [AnyHashable: Any] = notification?.userInfo {
|
||||
|
||||
if let value = info[UIResponder.keyboardIsLocalUserInfoKey] as? Bool {
|
||||
isLocal = value
|
||||
} else {
|
||||
isLocal = true
|
||||
}
|
||||
|
||||
// Getting keyboard animation.
|
||||
if let curveValue: Int = info[UIResponder.keyboardAnimationCurveUserInfoKey] as? Int,
|
||||
let curve: UIView.AnimationCurve = UIView.AnimationCurve(rawValue: curveValue) {
|
||||
animationCurve = curve
|
||||
} else {
|
||||
animationCurve = .easeOut
|
||||
}
|
||||
|
||||
// Getting keyboard animation duration
|
||||
if let duration: TimeInterval = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval,
|
||||
duration != 0.0 {
|
||||
animationDuration = duration
|
||||
} else {
|
||||
animationDuration = 0.25
|
||||
}
|
||||
|
||||
if let beginKeyboardFrame: CGRect = info[UIResponder.keyboardFrameBeginUserInfoKey] as? CGRect {
|
||||
beginFrame = Self.getKeyboardFrame(of: beginKeyboardFrame, inScreenBounds: screenBounds)
|
||||
} else {
|
||||
beginFrame = CGRect(x: 0, y: screenBounds.height, width: screenBounds.width, height: 0)
|
||||
}
|
||||
|
||||
var endFrame: CGRect
|
||||
if let endKeyboardFrame: CGRect = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect {
|
||||
endFrame = Self.getKeyboardFrame(of: endKeyboardFrame, inScreenBounds: screenBounds)
|
||||
} else {
|
||||
endFrame = CGRect(x: 0, y: screenBounds.height, width: screenBounds.width, height: 0)
|
||||
}
|
||||
|
||||
// With iOS 26, the endFrame returns height equal to the input accessory view height even when keyboard is dismissed.
|
||||
// Unfortunately we have to assume this hack for iOS 26.
|
||||
#if compiler(>=6.2) // Xcode 26
|
||||
if #available(iOS 26.0, *) {
|
||||
switch event {
|
||||
case .willHide, .didHide:
|
||||
endFrame.origin.y += endFrame.size.height
|
||||
endFrame.size.height = 0
|
||||
case .willShow, .didShow, .willChangeFrame, .didChangeFrame:
|
||||
break
|
||||
}
|
||||
}
|
||||
#endif
|
||||
self.endFrame = endFrame
|
||||
} else {
|
||||
isLocal = true
|
||||
animationCurve = .easeOut
|
||||
animationDuration = 0.25
|
||||
beginFrame = CGRect(x: 0, y: screenBounds.height, width: screenBounds.width, height: 0)
|
||||
endFrame = CGRect(x: 0, y: screenBounds.height, width: screenBounds.width, height: 0)
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public func animate(alongsideTransition transition: @escaping () -> Void, completion: (() -> Void)? = nil) {
|
||||
|
||||
// if let timing = UIView.AnimationCurve.RawValue(exactly: animationCurve.rawValue),
|
||||
// let curve = UIView.AnimationCurve(rawValue: timing) {
|
||||
// let animator = UIViewPropertyAnimator(duration: animationDuration, curve: curve) {
|
||||
// transition()
|
||||
// }
|
||||
// animator.addCompletion { _ in
|
||||
// completion?()
|
||||
// }
|
||||
// animator.isUserInteractionEnabled = true
|
||||
// animator.startAnimation()
|
||||
// } else {
|
||||
var animationOptions: UIView.AnimationOptions = self.animationOptions
|
||||
animationOptions.formUnion(.allowUserInteraction)
|
||||
animationOptions.formUnion(.beginFromCurrentState)
|
||||
UIView.animate(withDuration: animationDuration, delay: 0,
|
||||
options: animationOptions,
|
||||
animations: transition,
|
||||
completion: { _ in
|
||||
completion?()
|
||||
})
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOSApplicationExtension, unavailable)
|
||||
private extension IQKeyboardInfo {
|
||||
|
||||
static func getKeyboardFrame(of rect: CGRect, inScreenBounds screenBounds: CGRect) -> CGRect {
|
||||
var finalFrame: CGRect = rect
|
||||
// If this is floating keyboard
|
||||
if finalFrame.width < screenBounds.width,
|
||||
finalFrame.maxY < screenBounds.height {
|
||||
finalFrame.size = CGSize(width: finalFrame.size.width, height: 0)
|
||||
} else {
|
||||
// (Bug ID: #469) (Bug ID: #381) (Bug ID: #1506)
|
||||
// Calculating actual keyboard covered size respect to window,
|
||||
// keyboard frame may be different when hardware keyboard is attached
|
||||
let keyboardHeight = CGFloat.maximum(screenBounds.height - finalFrame.minY, 0)
|
||||
finalFrame.size = CGSize(width: finalFrame.size.width, height: keyboardHeight)
|
||||
}
|
||||
|
||||
return finalFrame
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOSApplicationExtension, unavailable)
|
||||
@objcMembers public class IQKeyboardInfoObjC: NSObject {
|
||||
private let wrappedValue: IQKeyboardInfo
|
||||
|
||||
public var event: IQKeyboardInfo.Event { wrappedValue.event }
|
||||
|
||||
public var isLocal: Bool { wrappedValue.isLocal }
|
||||
|
||||
public var beginFrame: CGRect { wrappedValue.beginFrame }
|
||||
|
||||
public var endFrame: CGRect { wrappedValue.endFrame }
|
||||
|
||||
public var animationDuration: TimeInterval { wrappedValue.animationDuration }
|
||||
|
||||
public var animationCurve: UIView.AnimationCurve { wrappedValue.animationCurve }
|
||||
|
||||
public var animationOptions: UIView.AnimationOptions { wrappedValue.animationOptions }
|
||||
|
||||
public var isVisible: Bool { wrappedValue.isVisible }
|
||||
|
||||
init(wrappedValue: IQKeyboardInfo){
|
||||
self.wrappedValue = wrappedValue
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public func animate(alongsideTransition transition: @escaping () -> Void, completion: (() -> Void)? = nil) {
|
||||
wrappedValue.animate(alongsideTransition: transition, completion: completion)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Deprecated
|
||||
@available(iOSApplicationExtension, unavailable)
|
||||
public extension IQKeyboardInfo {
|
||||
|
||||
@available(*, unavailable, renamed: "event")
|
||||
var name: Event { event }
|
||||
|
||||
@available(*, unavailable, renamed: "isVisible")
|
||||
var keyboardShowing: Bool { isVisible }
|
||||
}
|
||||
|
||||
172
Pods/IQKeyboardNotification/IQKeyboardNotification/Classes/IQKeyboardNotification.swift
generated
Normal file
172
Pods/IQKeyboardNotification/IQKeyboardNotification/Classes/IQKeyboardNotification.swift
generated
Normal file
@ -0,0 +1,172 @@
|
||||
//
|
||||
// IQKeyboardNotification.swift
|
||||
// https://github.com/hackiftekhar/IQKeyboardNotification
|
||||
// Copyright (c) 2013-24 Iftekhar Qurashi.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
import UIKit
|
||||
import Combine
|
||||
|
||||
@available(iOSApplicationExtension, unavailable)
|
||||
@MainActor
|
||||
@objcMembers public final class IQKeyboardNotification: NSObject {
|
||||
|
||||
private var storage: Set<AnyCancellable> = []
|
||||
|
||||
private var eventObservers: [IQKeyboardInfo.Event: [AnyHashable: SizeCompletion]] = [:]
|
||||
|
||||
public private(set) var oldKeyboardInfo: IQKeyboardInfo
|
||||
|
||||
public private(set) var keyboardInfo: IQKeyboardInfo {
|
||||
didSet {
|
||||
guard keyboardInfo != oldValue else { return }
|
||||
oldKeyboardInfo = oldValue
|
||||
sendKeyboardInfo(info: keyboardInfo)
|
||||
}
|
||||
}
|
||||
|
||||
public var isVisible: Bool {
|
||||
keyboardInfo.isVisible
|
||||
}
|
||||
|
||||
public var frame: CGRect {
|
||||
keyboardInfo.endFrame
|
||||
}
|
||||
|
||||
public override init() {
|
||||
keyboardInfo = IQKeyboardInfo(notification: nil, event: .didHide)
|
||||
oldKeyboardInfo = keyboardInfo
|
||||
super.init()
|
||||
|
||||
// Registering for keyboard notification.
|
||||
for event in IQKeyboardInfo.Event.allCases {
|
||||
NotificationCenter.default.publisher(for: event.notification)
|
||||
.map({ IQKeyboardInfo(notification: $0, event: event) })
|
||||
.sink(receiveValue: { [weak self] keyboardInfo in
|
||||
self?.keyboardInfo = keyboardInfo
|
||||
})
|
||||
.store(in: &storage)
|
||||
}
|
||||
}
|
||||
|
||||
public func animate(alongsideTransition transition: @escaping () -> Void, completion: (() -> Void)? = nil) {
|
||||
keyboardInfo.animate(alongsideTransition: transition, completion: completion)
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOSApplicationExtension, unavailable)
|
||||
@MainActor
|
||||
public extension IQKeyboardNotification {
|
||||
|
||||
typealias SizeCompletion = (_ event: IQKeyboardInfo.Event, _ endFrame: CGRect) -> Void
|
||||
|
||||
func subscribe(for events: [IQKeyboardInfo.Event],
|
||||
identifier: AnyHashable, changeHandler: @escaping SizeCompletion) {
|
||||
|
||||
for event in events {
|
||||
var existingObservers: [AnyHashable: SizeCompletion] = eventObservers[event] ?? [:]
|
||||
existingObservers[identifier] = changeHandler
|
||||
eventObservers[event] = existingObservers
|
||||
}
|
||||
|
||||
// If current event is the one user is subscribed to, then call changeHandler immediately for the first time.
|
||||
if events.contains(keyboardInfo.event) {
|
||||
changeHandler(keyboardInfo.event, keyboardInfo.endFrame)
|
||||
}
|
||||
}
|
||||
|
||||
func unsubscribe(for events: [IQKeyboardInfo.Event], identifier: AnyHashable) {
|
||||
|
||||
for event in events {
|
||||
var existingObservers: [AnyHashable: SizeCompletion] = eventObservers[event] ?? [:]
|
||||
existingObservers[identifier] = nil
|
||||
eventObservers[event] = existingObservers
|
||||
}
|
||||
}
|
||||
|
||||
func isSubscribed(for event: IQKeyboardInfo.Event? = nil, identifier: AnyHashable) -> Bool {
|
||||
if let event = event {
|
||||
guard let observers = eventObservers[event], !observers.isEmpty else { return false }
|
||||
return observers[identifier] != nil
|
||||
} else {
|
||||
|
||||
for event in IQKeyboardInfo.Event.allCases {
|
||||
let observers = eventObservers[event] ?? [:]
|
||||
if observers[identifier] != nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private func sendKeyboardInfo(info: IQKeyboardInfo) {
|
||||
|
||||
guard let observers = eventObservers[info.event], !observers.isEmpty else { return }
|
||||
|
||||
let endFrame: CGRect = info.endFrame
|
||||
|
||||
for block in observers.values {
|
||||
block(info.event, endFrame)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOSApplicationExtension, unavailable)
|
||||
@MainActor
|
||||
@objc public extension IQKeyboardNotification {
|
||||
|
||||
var oldKeyboardInfoObjc: IQKeyboardInfoObjC { IQKeyboardInfoObjC(wrappedValue: oldKeyboardInfo) }
|
||||
|
||||
var keyboardInfoObjc: IQKeyboardInfoObjC { IQKeyboardInfoObjC(wrappedValue: keyboardInfo) }
|
||||
|
||||
func subscribe(identifier: AnyHashable, changeHandler: @escaping SizeCompletion) {
|
||||
subscribe(for: IQKeyboardInfo.Event.allCases, identifier: identifier, changeHandler: changeHandler)
|
||||
}
|
||||
|
||||
func unsubscribe(identifier: AnyHashable) {
|
||||
unsubscribe(for: IQKeyboardInfo.Event.allCases, identifier: identifier)
|
||||
}
|
||||
|
||||
func isSubscribed(identifier: AnyHashable) -> Bool {
|
||||
isSubscribed(for: nil, identifier: identifier)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Deprecated
|
||||
@available(iOSApplicationExtension, unavailable)
|
||||
@objc public extension IQKeyboardNotification {
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, unavailable, renamed: "isVisible")
|
||||
var keyboardShowing: Bool { isVisible }
|
||||
|
||||
@available(*, unavailable, renamed: "subscribe(identifier:changeHandler:)")
|
||||
func registerSizeChange(identifier: AnyHashable, changeHandler: @escaping SizeCompletion) {
|
||||
subscribe(identifier: identifier, changeHandler: changeHandler)
|
||||
}
|
||||
|
||||
@available(*, unavailable, renamed: "unsubscribe(identifier:)")
|
||||
func unregisterSizeChange(identifier: AnyHashable) {
|
||||
unsubscribe(identifier: identifier)
|
||||
}
|
||||
}
|
||||
|
||||
21
Pods/IQKeyboardNotification/LICENSE
generated
Normal file
21
Pods/IQKeyboardNotification/LICENSE
generated
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Mohd Iftekhar Qurashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
66
Pods/IQKeyboardNotification/README.md
generated
Normal file
66
Pods/IQKeyboardNotification/README.md
generated
Normal file
@ -0,0 +1,66 @@
|
||||
# IQKeyboardNotification
|
||||
Lightweight library to observe keyboard events with ease.
|
||||
|
||||
[](https://travis-ci.org/hackiftekhar/IQKeyboardNotification)
|
||||
[](https://cocoapods.org/pods/IQKeyboardNotification)
|
||||
[](https://cocoapods.org/pods/IQKeyboardNotification)
|
||||
[](https://cocoapods.org/pods/IQKeyboardNotification)
|
||||
|
||||

|
||||
|
||||
## Example
|
||||
|
||||
To run the example project, clone the repo, and run `pod install` from the Example directory first.
|
||||
|
||||
## Requirements
|
||||
|
||||
## Installation
|
||||
|
||||
IQKeyboardNotification is available through [CocoaPods](https://cocoapods.org). To install
|
||||
it, simply add the following line to your Podfile:
|
||||
|
||||
```ruby
|
||||
pod 'IQKeyboardNotification'
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
To observe keyboard events, subscribe to the keyboard events:-
|
||||
|
||||
```swift
|
||||
import IQKeyboardNotification
|
||||
|
||||
class ViewController: UIViewController {
|
||||
|
||||
private let keyboard: IQKeyboardNotification = .init()
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
// Subscribe
|
||||
keyboard.subscribe(identifier: "YOUR_UNIQUE_IDENTIFIER") { event, frame in
|
||||
print(frame)
|
||||
// Write your own logic here based on event and keyboard frame
|
||||
}
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
super.viewWillDisappear(animated)
|
||||
|
||||
// Unsubscribe
|
||||
keyboard.unsubscribe(identifier: "YOUR_UNIQUE_IDENTIFIER")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
Iftekhar Qurashi hack.iftekhar@gmail.com
|
||||
|
||||
## Flow
|
||||
|
||||

|
||||
|
||||
## License
|
||||
|
||||
IQKeyboardNotification is available under the MIT license. See the LICENSE file for more info.
|
||||
Reference in New Issue
Block a user