feat: update placeholders interactions with opend keyboard

This commit is contained in:
Nikita Semenov 2023-03-17 11:10:07 +03:00
parent 318fd40f0b
commit 1374c4df1f
4 changed files with 77 additions and 50 deletions

View File

@ -115,17 +115,6 @@ open class PlaceholderFactory {
return view
}
open func createCustomPlaceholder<V: UIView,
P: BasePlaceholderView<V>,
GA: WrappedViewAppearance,
A: BasePlaceholderView<V>.BaseAppearance<GA> & ViewAppearance>(_ style: BasePlaceholderStyle<A>) -> P {
let view = P()
view.applyBaseStyle(style: style)
return view
}
}
// MARK: - Private configurations

View File

@ -34,7 +34,10 @@ open class BasePlaceholderView<ImageView: UIView>: BaseInitializableView {
public var textViewConstraints: SubviewConstraints?
public var controlsViewConstraints: SubviewConstraints?
public var keyboardObserver: NSObjectProtocol?
public var keyboardDidShownObserver: NSObjectProtocol?
public var keyboardDidHiddenObserver: NSObjectProtocol?
open var isKeyboardHidden: Bool = true
open var isImageViewHidden: Bool {
imageView.isHidden
@ -47,18 +50,16 @@ open class BasePlaceholderView<ImageView: UIView>: BaseInitializableView {
// MARK: - Deinit
deinit {
if let keyboardObserver = keyboardObserver {
NotificationCenter.default.removeObserver(keyboardObserver)
if let keyboardDidShownObserver = keyboardDidShownObserver {
NotificationCenter.default.removeObserver(keyboardDidShownObserver)
}
if let keyboardDidHiddenObserver = keyboardDidHiddenObserver {
NotificationCenter.default.removeObserver(keyboardDidHiddenObserver)
}
}
// MARK: - Life cycle
override open func layoutSubviews() {
super.layoutSubviews()
window?.endEditing(true)
}
// MARK: - BaseInitializableView
open override func addViews() {
super.addViews()
@ -114,11 +115,20 @@ open class BasePlaceholderView<ImageView: UIView>: BaseInitializableView {
open override func bindViews() {
super.bindViews()
keyboardObserver = NotificationCenter.default
keyboardDidShownObserver = NotificationCenter.default
.addObserver(forName: UIResponder.keyboardDidShowNotification,
object: nil,
queue: .main) { [weak self] _ in
self?.window?.endEditing(true)
queue: .main) { [weak self] notification in
self?.isKeyboardHidden = false
self?.configureLayoutForKeyboard(notification)
}
keyboardDidHiddenObserver = NotificationCenter.default
.addObserver(forName: UIResponder.keyboardDidHideNotification,
object: nil,
queue: .main) { [weak self] notification in
self?.isKeyboardHidden = true
self?.configureLayoutForKeyboard(notification)
}
}
@ -217,6 +227,22 @@ open class BasePlaceholderView<ImageView: UIView>: BaseInitializableView {
leadingConstraint: constraints.leadingConstraint,
trailingConstraint: constraints.trailingConstraint)
}
private func configureLayoutForKeyboard(_ notification: Notification) {
let multiplier = isKeyboardHidden ? 1.0 : -1.0
if let height = getKeyboardHeight(notification) {
controlsViewConstraints?.bottomConstraint?.constant = multiplier * height / 2
}
}
private func getKeyboardHeight(_ notification: Notification) -> CGFloat? {
guard let userInfo = notification.userInfo else {
return nil
}
return (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height
}
}
// MARK: - BaseAppearance + Appearance

View File

@ -281,8 +281,6 @@ placeholder.configure(with: .internetConnection)
В качестве примера показан заглушка с lottie анимацией:
```swift
import Lottie
public final class LottiePlaceholderStyle: BasePlaceholderStyle<LottiePlaceholderView.Appearance>, PlaceholderStyle {
public static var defaultStyle: LottiePlaceholderStyle {
@ -317,19 +315,17 @@ placeholder.configure(with: .internetConnection)
super.isImageViewHidden || imageView.animation == nil
}
public override func applyBaseStyle(style: BasePlaceholderStyle<some BaseAppearance<some WrappedViewAppearance> & ViewAppearance>) {
if let lottieStyle = style as? LottiePlaceholderStyle {
imageView.animation = LottieAnimation.named(lottieStyle .animationName)
imageView.animationSpeed = lottieStyle.animationSpeed
imageView.loopMode = lottieStyle.loopMode
public func apply(style: LottiePlaceholderStyle) {
imageView.animation = LottieAnimation.named(style.animationName)
imageView.animationSpeed = style.animationSpeed
imageView.loopMode = style.loopMode
imageView.play()
super.applyBaseStyle(style: style)
configureImageSizeConstraints(size: imageView.animation?.size ?? .zero)
}
super.applyBaseStyle(style: style)
configureImageSizeConstraints(size: imageView.animation?.size ?? .zero)
}
public func configure(appearance: Appearance) {
configureAppearance(appearance: appearance)
}
@ -357,6 +353,16 @@ placeholder.configure(with: .internetConnection)
}
}
extension PlaceholderFactory {
func createLottiePlaceholder(_ style: LottiePlaceholderStyle) -> LottiePlaceholderView {
let view = LottiePlaceholderView()
view.apply(style: style)
return view
}
}
class LottieAnimationViewController: BaseViewController<UIView, Void> {
let placeholderFactory = PlaceholderFactory()
@ -385,7 +391,7 @@ placeholder.configure(with: .internetConnection)
}
func showPlaceholder() {
let placeholder: LottiePlaceholderView = placeholderFactory.createCustomPlaceholder(Self.lottieStyle)
let placeholder = placeholderFactory.createLottiePlaceholder(Self.lottieStyle)
placeholder.frame = view.frame
view.addSubview(placeholder)
}

View File

@ -297,8 +297,6 @@ placeholder.configure(with: .internetConnection)
В качестве примера показан заглушка с lottie анимацией:
```swift
import Lottie
public final class LottiePlaceholderStyle: BasePlaceholderStyle<LottiePlaceholderView.Appearance>, PlaceholderStyle {
public static var defaultStyle: LottiePlaceholderStyle {
@ -333,19 +331,17 @@ placeholder.configure(with: .internetConnection)
super.isImageViewHidden || imageView.animation == nil
}
public override func applyBaseStyle(style: BasePlaceholderStyle<some BaseAppearance<some WrappedViewAppearance> & ViewAppearance>) {
if let lottieStyle = style as? LottiePlaceholderStyle {
imageView.animation = LottieAnimation.named(lottieStyle .animationName)
imageView.animationSpeed = lottieStyle.animationSpeed
imageView.loopMode = lottieStyle.loopMode
public func apply(style: LottiePlaceholderStyle) {
imageView.animation = LottieAnimation.named(style.animationName)
imageView.animationSpeed = style.animationSpeed
imageView.loopMode = style.loopMode
imageView.play()
super.applyBaseStyle(style: style)
configureImageSizeConstraints(size: imageView.animation?.size ?? .zero)
}
super.applyBaseStyle(style: style)
configureImageSizeConstraints(size: imageView.animation?.size ?? .zero)
}
public func configure(appearance: Appearance) {
configureAppearance(appearance: appearance)
}
@ -373,6 +369,16 @@ placeholder.configure(with: .internetConnection)
}
}
extension PlaceholderFactory {
func createLottiePlaceholder(_ style: LottiePlaceholderStyle) -> LottiePlaceholderView {
let view = LottiePlaceholderView()
view.apply(style: style)
return view
}
}
class LottieAnimationViewController: BaseViewController<UIView, Void> {
let placeholderFactory = PlaceholderFactory()
@ -401,7 +407,7 @@ placeholder.configure(with: .internetConnection)
}
func showPlaceholder() {
let placeholder: LottiePlaceholderView = placeholderFactory.createCustomPlaceholder(Self.lottieStyle)
let placeholder = placeholderFactory.createLottiePlaceholder(Self.lottieStyle)
placeholder.frame = view.frame
view.addSubview(placeholder)
}