diff --git a/TIUIElements/Sources/Views/Placeholder/PlaceholderFactory.swift b/TIUIElements/Sources/Views/Placeholder/PlaceholderFactory.swift index ac390b5e..015b8087 100644 --- a/TIUIElements/Sources/Views/Placeholder/PlaceholderFactory.swift +++ b/TIUIElements/Sources/Views/Placeholder/PlaceholderFactory.swift @@ -115,17 +115,6 @@ open class PlaceholderFactory { return view } - - open func createCustomPlaceholder, - GA: WrappedViewAppearance, - A: BasePlaceholderView.BaseAppearance & ViewAppearance>(_ style: BasePlaceholderStyle) -> P { - - let view = P() - view.applyBaseStyle(style: style) - - return view - } } // MARK: - Private configurations diff --git a/TIUIElements/Sources/Views/Placeholder/Views/BasePlaceholderView.swift b/TIUIElements/Sources/Views/Placeholder/Views/BasePlaceholderView.swift index da75ad1f..168ae13d 100644 --- a/TIUIElements/Sources/Views/Placeholder/Views/BasePlaceholderView.swift +++ b/TIUIElements/Sources/Views/Placeholder/Views/BasePlaceholderView.swift @@ -34,7 +34,10 @@ open class BasePlaceholderView: 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: 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: 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: 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 diff --git a/TIUIElements/TIUIElements.app/Contents/MacOS/TIUIElements.playground/Pages/Placeholder.xcplaygroundpage/Contents.swift b/TIUIElements/TIUIElements.app/Contents/MacOS/TIUIElements.playground/Pages/Placeholder.xcplaygroundpage/Contents.swift index 27ec6a24..5b01d3f6 100644 --- a/TIUIElements/TIUIElements.app/Contents/MacOS/TIUIElements.playground/Pages/Placeholder.xcplaygroundpage/Contents.swift +++ b/TIUIElements/TIUIElements.app/Contents/MacOS/TIUIElements.playground/Pages/Placeholder.xcplaygroundpage/Contents.swift @@ -281,8 +281,6 @@ placeholder.configure(with: .internetConnection) В качестве примера показан заглушка с lottie анимацией: ```swift - import Lottie - public final class LottiePlaceholderStyle: BasePlaceholderStyle, 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 & 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 { 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) } diff --git a/docs/tiuielements/placeholder.md b/docs/tiuielements/placeholder.md index 8db719bf..2d371202 100644 --- a/docs/tiuielements/placeholder.md +++ b/docs/tiuielements/placeholder.md @@ -297,8 +297,6 @@ placeholder.configure(with: .internetConnection) В качестве примера показан заглушка с lottie анимацией: ```swift - import Lottie - public final class LottiePlaceholderStyle: BasePlaceholderStyle, 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 & 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 { 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) }