From 80075323519ec32f3ec259720cc7fa30938e9968 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Tue, 25 Jul 2023 18:36:24 +0300 Subject: [PATCH] fix: keyboard overlapping for footer and content view of BaseModalViewController --- .../BottomSheet/BaseModalViewController.swift | 54 +++++++++---------- ...> DefaultModalWrapperViewController.swift} | 24 +++++---- .../Sources/BottomSheet/Views/DragView.swift | 2 +- .../BottomSheet/Views/ModalFooterView.swift | 7 +-- .../BottomSheet/Views/ModalHeaderView.swift | 52 +++++++++--------- .../Views/BasePlaceholderView.swift | 16 +++++- .../Containers/CollectionTableViewCell.swift | 4 +- .../Wrappers/Containers/ContainerView.swift | 2 +- 8 files changed, 86 insertions(+), 75 deletions(-) rename TIBottomSheet/Sources/BottomSheet/{BaseModalWrapperViewController.swift => DefaultModalWrapperViewController.swift} (61%) diff --git a/TIBottomSheet/Sources/BottomSheet/BaseModalViewController.swift b/TIBottomSheet/Sources/BottomSheet/BaseModalViewController.swift index 01a7369e..92f1b5c3 100644 --- a/TIBottomSheet/Sources/BottomSheet/BaseModalViewController.swift +++ b/TIBottomSheet/Sources/BottomSheet/BaseModalViewController.swift @@ -151,9 +151,6 @@ open class BaseModalViewController: BaseModalViewController -where ContentViewController: UIViewController { +open class DefaultModalWrapperViewController: BaseModalViewController { - private(set) public lazy var contentViewController = createContentViewController() + private(set) public var contentViewController: ContentController - // MARK: - BaseModalViewController + public init(contentViewController: ContentController) { + self.contentViewController = contentViewController - open override func createContentView() -> UIView { - contentViewController.view + super.init(nibName: nil, bundle: nil) } - // MARK: - Open methods + @available(*, unavailable) + required public init?(coder: NSCoder) { + contentViewController = ContentController() - open func createContentViewController() -> ContentViewController { - ContentViewController() + super.init(coder: coder) + } +} + +public extension UIViewController { + func wrappedInBottomSheetController() -> DefaultModalWrapperViewController { + DefaultModalWrapperViewController(contentViewController: self) } } diff --git a/TIBottomSheet/Sources/BottomSheet/Views/DragView.swift b/TIBottomSheet/Sources/BottomSheet/Views/DragView.swift index 1f05d400..22edd8ea 100644 --- a/TIBottomSheet/Sources/BottomSheet/Views/DragView.swift +++ b/TIBottomSheet/Sources/BottomSheet/Views/DragView.swift @@ -54,7 +54,7 @@ public final class DragView: BaseInitializableView, AppearanceConfigurable { public final class Appearance: UIView.BaseWrappedAppearance, WrappedViewAppearance { public static var defaultAppearance: Appearance { - Self().update { dragView in + .make { dragView in dragView.backgroundColor = Constants.dragViewBackgroundColor dragView.border = Constants.dragViewBorder diff --git a/TIBottomSheet/Sources/BottomSheet/Views/ModalFooterView.swift b/TIBottomSheet/Sources/BottomSheet/Views/ModalFooterView.swift index 20aae228..ab83ddfb 100644 --- a/TIBottomSheet/Sources/BottomSheet/Views/ModalFooterView.swift +++ b/TIBottomSheet/Sources/BottomSheet/Views/ModalFooterView.swift @@ -24,13 +24,10 @@ import TIUIElements import TIUIKitCore import UIKit -public typealias ModalFooterView = ContainerView - -public extension ModalFooterView { - +open class ModalFooterView: ContainerView { // MARK: - Nested Types - enum State { + public enum State { case hidden case presented(BaseWrappedViewHolderAppearance) } diff --git a/TIBottomSheet/Sources/BottomSheet/Views/ModalHeaderView.swift b/TIBottomSheet/Sources/BottomSheet/Views/ModalHeaderView.swift index 2827abb8..dc6ec762 100644 --- a/TIBottomSheet/Sources/BottomSheet/Views/ModalHeaderView.swift +++ b/TIBottomSheet/Sources/BottomSheet/Views/ModalHeaderView.swift @@ -42,31 +42,31 @@ open class ModalHeaderView: BaseInitializableView, AppearanceConfigurable { // MARK: - Public properties - public let leftButton = StatefulButton() - public let rightButton = StatefulButton() + public let leadingButton = StatefulButton() + public let trailingButton = StatefulButton() public private(set) lazy var leftTrailingToRightLeadingConstraint: NSLayoutConstraint = { - leftButton.trailingAnchor.constraint(equalTo: rightButton.leadingAnchor) + leadingButton.trailingAnchor.constraint(equalTo: trailingButton.leadingAnchor) }() public private(set) lazy var leftTrailingToSuperviewTrailing: NSLayoutConstraint = { - leftButton.trailingAnchor.constraint(equalTo: rightButton.leadingAnchor) + leadingButton.trailingAnchor.constraint(equalTo: trailingButton.leadingAnchor) }() public private(set) lazy var leftButtonConstraints: SubviewConstraints = { - let edgeConstraints = EdgeConstraints(leadingConstraint: leftButton.leadingAnchor.constraint(equalTo: leadingAnchor), + let edgeConstraints = EdgeConstraints(leadingConstraint: leadingButton.leadingAnchor.constraint(equalTo: leadingAnchor), trailingConstraint: leftTrailingToRightLeadingConstraint, - topConstraint: leftButton.topAnchor.constraint(equalTo: topAnchor), - bottomConstraint: leftButton.bottomAnchor.constraint(equalTo: bottomAnchor)) + topConstraint: leadingButton.topAnchor.constraint(equalTo: topAnchor), + bottomConstraint: leadingButton.bottomAnchor.constraint(equalTo: bottomAnchor)) - let centerXConstraint = leftButton.centerXAnchor.constraint(equalTo: centerXAnchor) - let centerYConstraint = leftButton.centerYAnchor.constraint(equalTo: centerYAnchor) + let centerXConstraint = leadingButton.centerXAnchor.constraint(equalTo: centerXAnchor) + let centerYConstraint = leadingButton.centerYAnchor.constraint(equalTo: centerYAnchor) let centerConstraints = CenterConstraints(centerXConstraint: centerXConstraint, centerYConstraint: centerYConstraint) - let sizeConstraints = SizeConstraints(widthConstraint: leftButton.widthAnchor.constraint(equalToConstant: .zero), - heightConstraint: leftButton.heightAnchor.constraint(equalToConstant: .zero)) + let sizeConstraints = SizeConstraints(widthConstraint: leadingButton.widthAnchor.constraint(equalToConstant: .zero), + heightConstraint: leadingButton.heightAnchor.constraint(equalToConstant: .zero)) return SubviewConstraints(edgeConstraints: edgeConstraints, centerConstraints: centerConstraints, @@ -74,25 +74,26 @@ open class ModalHeaderView: BaseInitializableView, AppearanceConfigurable { }() public private(set) lazy var rightLeadingToSuperviewLeadingConstraint: NSLayoutConstraint = { - rightButton.leadingAnchor.constraint(equalTo: leadingAnchor) + trailingButton.leadingAnchor.constraint(equalTo: leadingAnchor) }() public private(set) lazy var rightButtonConstraints: SubviewConstraints = { - let trailingConstraint = rightButton.trailingAnchor.constraint(equalTo: trailingAnchor) + let leadingConstraint = trailingButton.leadingAnchor.constraint(equalTo: leadingAnchor) + let trailingConstraint = trailingButton.trailingAnchor.constraint(equalTo: trailingAnchor) - let edgeConstraints = EdgeConstraints(leadingConstraint: rightButton.leadingAnchor.constraint(equalTo: leadingAnchor), + let edgeConstraints = EdgeConstraints(leadingConstraint: leadingConstraint, trailingConstraint: trailingConstraint, - topConstraint: rightButton.topAnchor.constraint(equalTo: topAnchor), - bottomConstraint: rightButton.bottomAnchor.constraint(equalTo: bottomAnchor)) + topConstraint: trailingButton.topAnchor.constraint(equalTo: topAnchor), + bottomConstraint: trailingButton.bottomAnchor.constraint(equalTo: bottomAnchor)) - let centerXConstraint = rightButton.centerXAnchor.constraint(equalTo: centerXAnchor) - let centerYConstraint = rightButton.centerYAnchor.constraint(equalTo: centerYAnchor) + let centerXConstraint = trailingButton.centerXAnchor.constraint(equalTo: centerXAnchor) + let centerYConstraint = trailingButton.centerYAnchor.constraint(equalTo: centerYAnchor) let centerConstraints = CenterConstraints(centerXConstraint: centerXConstraint, centerYConstraint: centerYConstraint) - let sizeConstraints = SizeConstraints(widthConstraint: rightButton.widthAnchor.constraint(equalToConstant: .zero), - heightConstraint: rightButton.heightAnchor.constraint(equalToConstant: .zero)) + let sizeConstraints = SizeConstraints(widthConstraint: trailingButton.widthAnchor.constraint(equalToConstant: .zero), + heightConstraint: trailingButton.heightAnchor.constraint(equalToConstant: .zero)) return SubviewConstraints(edgeConstraints: edgeConstraints, centerConstraints: centerConstraints, @@ -106,14 +107,15 @@ open class ModalHeaderView: BaseInitializableView, AppearanceConfigurable { open override func addViews() { super.addViews() - addSubviews(leftButton, rightButton) + addSubviews(leadingButton, trailingButton) } open override func configureLayout() { super.configureLayout() - [leftButton, rightButton] - .forEach { $0.translatesAutoresizingMaskIntoConstraints = false } + for view in [leadingButton, trailingButton] { + view.translatesAutoresizingMaskIntoConstraints = false + } } // MARK: - AppearanceConfigurable @@ -154,8 +156,8 @@ open class ModalHeaderView: BaseInitializableView, AppearanceConfigurable { view.configureUIView(appearance: appearance) } - configure(buttonStyle: leadingButtonStyle, forButton: leftButton, constraints: leftButtonConstraints) - configure(buttonStyle: trailingButtonStyle, forButton: rightButton, constraints: rightButtonConstraints) + configure(buttonStyle: leadingButtonStyle, forButton: leadingButton, constraints: leftButtonConstraints) + configure(buttonStyle: trailingButtonStyle, forButton: trailingButton, constraints: rightButtonConstraints) } // MARK: - Private methods diff --git a/TIUIElements/Sources/Views/Placeholder/Views/BasePlaceholderView.swift b/TIUIElements/Sources/Views/Placeholder/Views/BasePlaceholderView.swift index 49b6cca7..772d4538 100644 --- a/TIUIElements/Sources/Views/Placeholder/Views/BasePlaceholderView.swift +++ b/TIUIElements/Sources/Views/Placeholder/Views/BasePlaceholderView.swift @@ -101,8 +101,8 @@ open class BasePlaceholderView: BaseInitializableView { sizeConstraints: sizeConstraints) }() - public var keyboardDidShownObserver: NSObjectProtocol? - public var keyboardDidHiddenObserver: NSObjectProtocol? + private var keyboardDidShownObserver: NSObjectProtocol? + private var keyboardDidHiddenObserver: NSObjectProtocol? open var isImageViewHidden: Bool { imageView.isHidden @@ -112,6 +112,18 @@ open class BasePlaceholderView: BaseInitializableView { controlsStackView.isHidden || controlsStackView.arrangedSubviews.isEmpty } + deinit { + let notificationCenter = NotificationCenter.default + + if let keyboardDidShownObserver { + notificationCenter.removeObserver(keyboardDidShownObserver) + } + + if let keyboardDidHiddenObserver { + notificationCenter.removeObserver(keyboardDidHiddenObserver) + } + } + // MARK: - BaseInitializableView open override func addViews() { diff --git a/TIUIElements/Sources/Wrappers/Containers/CollectionTableViewCell.swift b/TIUIElements/Sources/Wrappers/Containers/CollectionTableViewCell.swift index d753f46f..efd45b8f 100644 --- a/TIUIElements/Sources/Wrappers/Containers/CollectionTableViewCell.swift +++ b/TIUIElements/Sources/Wrappers/Containers/CollectionTableViewCell.swift @@ -52,12 +52,12 @@ open class CollectionTableViewCell: ContainerT } let cachedCollectionFrame = wrappedView.frame - wrappedView.frame.size.width = targetSize.width - wrappedContentInsets.left - wrappedContentInsets.right + wrappedView.frame.size.width = targetSize.width - wrappedContentInsets.horizontal(onNan: .zero) let collectionContentHeight = wrappedView.collectionViewLayout.collectionViewContentSize.height wrappedView.frame = cachedCollectionFrame return CGSize(width: targetSize.width, - height: collectionContentHeight + wrappedContentInsets.top + wrappedContentInsets.bottom) + height: collectionContentHeight + wrappedContentInsets.vertical(onNan: .zero)) } // MARK: - Open methods diff --git a/TIUIElements/Sources/Wrappers/Containers/ContainerView.swift b/TIUIElements/Sources/Wrappers/Containers/ContainerView.swift index 9549c06b..272ad2e4 100644 --- a/TIUIElements/Sources/Wrappers/Containers/ContainerView.swift +++ b/TIUIElements/Sources/Wrappers/Containers/ContainerView.swift @@ -23,7 +23,7 @@ import TIUIKitCore import UIKit -public final class ContainerView: BaseInitializableView, WrappedViewHolder { +open class ContainerView: BaseInitializableView, WrappedViewHolder { public private(set) lazy var wrappedView = View()