move presentation detents settings to modal view controller appearance
This commit is contained in:
parent
8007532351
commit
d55745efc6
|
|
@ -28,6 +28,7 @@ extension BaseModalViewController {
|
|||
|
||||
open class BaseAppearance: UIView.BaseAppearance<UIView.DefaultWrappedLayout> {
|
||||
|
||||
public var presentationDetents: [ModalViewPresentationDetent]
|
||||
public var dragViewState: DragView.State
|
||||
public var headerViewState: ModalHeaderView.State
|
||||
public var footerViewState: ModalFooterView<FooterContentView>.State
|
||||
|
|
@ -36,15 +37,26 @@ extension BaseModalViewController {
|
|||
backgroundColor: UIColor = .clear,
|
||||
border: UIViewBorder = .init(),
|
||||
shadow: UIViewShadow? = nil,
|
||||
presentationDetents: [ModalViewPresentationDetent] = [.maxHeight],
|
||||
dragViewState: DragView.State = .hidden,
|
||||
headerViewState: ModalHeaderView.State = .hidden,
|
||||
footerViewState: ModalFooterView<FooterContentView>.State = .hidden) {
|
||||
|
||||
self.presentationDetents = presentationDetents
|
||||
self.dragViewState = dragViewState
|
||||
self.headerViewState = headerViewState
|
||||
self.footerViewState = footerViewState
|
||||
|
||||
super.init(layout: layout, backgroundColor: backgroundColor, border: border, shadow: shadow)
|
||||
super.init(layout: layout,
|
||||
backgroundColor: backgroundColor,
|
||||
border: border,
|
||||
shadow: shadow)
|
||||
}
|
||||
}
|
||||
|
||||
public final class DefaultAppearance: BaseAppearance, ViewAppearance {
|
||||
public static var defaultAppearance: Self {
|
||||
Self()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,9 +153,7 @@ open class BaseModalViewController<ContentView: UIView,
|
|||
|
||||
// MARK: - Modal View Controller Configuration
|
||||
|
||||
open var viewControllerAppearance: BaseAppearance {
|
||||
.init(backgroundColor: .white)
|
||||
}
|
||||
public var viewControllerAppearance: BaseAppearance = .init(backgroundColor: .white)
|
||||
|
||||
open var panScrollable: UIScrollView? {
|
||||
contentView as? UIScrollView
|
||||
|
|
@ -167,9 +165,7 @@ open class BaseModalViewController<ContentView: UIView,
|
|||
}
|
||||
}
|
||||
|
||||
open var presentationDetents: [ModalViewPresentationDetent] {
|
||||
[.maxHeight]
|
||||
}
|
||||
public var dimmedView: DimmedView? = DimmedView()
|
||||
|
||||
open var headerViewHeight: CGFloat {
|
||||
let dragViewHeight = getHeight(of: dragView)
|
||||
|
|
@ -423,7 +419,7 @@ open class BaseModalViewController<ContentView: UIView,
|
|||
}
|
||||
|
||||
private func getSortedDetents() -> [ModalViewPresentationDetent] {
|
||||
presentationDetents.uniqued().sorted()
|
||||
viewControllerAppearance.presentationDetents.uniqued().sorted()
|
||||
}
|
||||
|
||||
private func getHeight(of view: UIView) -> CGFloat {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ open class DefaultModalWrapperViewController<ContentController: UIViewController
|
|||
self.contentViewController = contentViewController
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
addChild(contentViewController)
|
||||
contentViewController.didMove(toParent: self)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
|
|
@ -38,6 +41,10 @@ open class DefaultModalWrapperViewController<ContentController: UIViewController
|
|||
|
||||
super.init(coder: coder)
|
||||
}
|
||||
|
||||
open override func createContentView() -> UIView {
|
||||
contentViewController.view
|
||||
}
|
||||
}
|
||||
|
||||
public extension UIViewController {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import UIKit
|
|||
import PanModal
|
||||
|
||||
open class PassthroughDimmedView: DimmedView {
|
||||
weak var hitTestHandlerView: UIView?
|
||||
public weak var hitTestHandlerView: UIView?
|
||||
|
||||
public var isTransparent = false
|
||||
|
||||
|
|
|
|||
|
|
@ -30,21 +30,21 @@ extension UIButton {
|
|||
appearance.textAttributes?
|
||||
.configure(button: self,
|
||||
with: title(for: state),
|
||||
for: state)
|
||||
for: state)
|
||||
|
||||
if #available(iOS 15, *) {
|
||||
var config = configuration ?? .plain()
|
||||
|
||||
configureInsets(in: &config,
|
||||
contentInsets: appearance.contentLayout.contentInsets,
|
||||
titleInsets: appearance.contentLayout.titleInsets,
|
||||
imageInsets: appearance.contentLayout.imageInsets)
|
||||
contentInsets: appearance.contentLayout.contentInsets.replacingNan(with: .zero),
|
||||
titleInsets: appearance.contentLayout.titleInsets.replacingNan(with: .zero),
|
||||
imageInsets: appearance.contentLayout.imageInsets.replacingNan(with: .zero))
|
||||
|
||||
configuration = config
|
||||
} else {
|
||||
contentEdgeInsets = appearance.contentLayout.contentInsets
|
||||
titleEdgeInsets = appearance.contentLayout.titleInsets
|
||||
imageEdgeInsets = appearance.contentLayout.imageInsets
|
||||
contentEdgeInsets = appearance.contentLayout.contentInsets.replacingNan(with: .zero)
|
||||
titleEdgeInsets = appearance.contentLayout.titleInsets.replacingNan(with: .zero)
|
||||
imageEdgeInsets = appearance.contentLayout.imageInsets.replacingNan(with: .zero)
|
||||
}
|
||||
|
||||
super.configureUIView(appearance: appearance)
|
||||
|
|
@ -67,7 +67,7 @@ extension UIButton {
|
|||
currentImage
|
||||
]
|
||||
.compactMap { $0 }
|
||||
.first { !($0.size.width.isZero || $0.size.height.isZero) } != nil
|
||||
.contains { !($0.size.width.isZero || $0.size.height.isZero) }
|
||||
|
||||
if hasNonEmptyImage {
|
||||
let leadingContentInset: CGFloat
|
||||
|
|
|
|||
|
|
@ -27,15 +27,13 @@ open class ContainerSeparatorTableViewCell<View: UIView>: ContainerTableViewCell
|
|||
private lazy var topSeparatorView = createTopSeparator()
|
||||
private lazy var bottomSeparatorView = createBottomSeparator()
|
||||
|
||||
private var topViewLeftConstraint: NSLayoutConstraint?
|
||||
private var topViewRightConstraint: NSLayoutConstraint?
|
||||
private var topViewTopConstraint: NSLayoutConstraint?
|
||||
private var topViewHeightConstraint: NSLayoutConstraint?
|
||||
private lazy var topSeparatorConstraints: SubviewConstraints = {
|
||||
subviewConstraints(for: topSeparatorView)
|
||||
}()
|
||||
|
||||
private var bottomViewLeftConstraint: NSLayoutConstraint?
|
||||
private var bottomViewRightConstraint: NSLayoutConstraint?
|
||||
private var bottomViewBottomConstraint: NSLayoutConstraint?
|
||||
private var bottomViewHeightConstraint: NSLayoutConstraint?
|
||||
private lazy var bottomSeparatorConstraints: SubviewConstraints = {
|
||||
subviewConstraints(for: bottomSeparatorView)
|
||||
}()
|
||||
|
||||
open func createTopSeparator() -> UIView {
|
||||
.init()
|
||||
|
|
@ -93,41 +91,17 @@ open class ContainerSeparatorTableViewCell<View: UIView>: ContainerTableViewCell
|
|||
open override func configureLayout() {
|
||||
super.configureLayout()
|
||||
|
||||
if let separatorSuperview = topSeparatorView.superview {
|
||||
topViewTopConstraint = topSeparatorView.topAnchor.constraint(equalTo: separatorSuperview.topAnchor)
|
||||
topViewRightConstraint = separatorSuperview.rightAnchor.constraint(equalTo: topSeparatorView.rightAnchor)
|
||||
topViewLeftConstraint = topSeparatorView.leftAnchor.constraint(equalTo: separatorSuperview.leftAnchor)
|
||||
for view in [topSeparatorView, bottomSeparatorView] {
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
}
|
||||
|
||||
topViewHeightConstraint = topSeparatorView.heightAnchor.constraint(equalToConstant: 1)
|
||||
|
||||
if let separatorSuperview = topSeparatorView.superview {
|
||||
bottomViewRightConstraint = separatorSuperview.rightAnchor.constraint(equalTo: bottomSeparatorView.rightAnchor)
|
||||
bottomViewLeftConstraint = bottomSeparatorView.leftAnchor.constraint(equalTo: separatorSuperview.leftAnchor)
|
||||
bottomViewBottomConstraint = bottomSeparatorView.bottomAnchor.constraint(equalTo: separatorSuperview.bottomAnchor)
|
||||
}
|
||||
|
||||
bottomViewHeightConstraint = bottomSeparatorView.heightAnchor.constraint(equalToConstant: 1)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
topViewTopConstraint,
|
||||
topViewRightConstraint,
|
||||
topViewLeftConstraint,
|
||||
topViewHeightConstraint,
|
||||
bottomViewRightConstraint,
|
||||
bottomViewLeftConstraint,
|
||||
bottomViewBottomConstraint,
|
||||
bottomViewHeightConstraint
|
||||
].compactMap { $0 })
|
||||
}
|
||||
|
||||
open override func configureAppearance() {
|
||||
super.configureAppearance()
|
||||
|
||||
[topSeparatorView, bottomSeparatorView].forEach {
|
||||
$0.isHidden = true
|
||||
$0.backgroundColor = .black
|
||||
$0.translatesAutoresizingMaskIntoConstraints = false
|
||||
for view in [topSeparatorView, bottomSeparatorView] {
|
||||
view.isHidden = true
|
||||
view.backgroundColor = .black
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -136,20 +110,37 @@ open class ContainerSeparatorTableViewCell<View: UIView>: ContainerTableViewCell
|
|||
private func updateTopSeparator(with appearance: SeparatorAppearance) {
|
||||
topSeparatorView.configureUIView(appearance: appearance)
|
||||
|
||||
topViewHeightConstraint?.constant = appearance.layout.size.height
|
||||
|
||||
topViewTopConstraint?.constant = appearance.layout.insets.top
|
||||
topViewLeftConstraint?.constant = appearance.layout.insets.left
|
||||
topViewRightConstraint?.constant = appearance.layout.insets.right
|
||||
topSeparatorConstraints.update(from: appearance.layout)
|
||||
}
|
||||
|
||||
private func updateBottomSeparator(with appearance: SeparatorAppearance) {
|
||||
bottomSeparatorView.configureUIView(appearance: appearance)
|
||||
|
||||
bottomViewHeightConstraint?.constant = appearance.layout.size.height
|
||||
bottomSeparatorConstraints.update(from: appearance.layout)
|
||||
}
|
||||
|
||||
bottomViewBottomConstraint?.constant = appearance.layout.insets.bottom
|
||||
bottomViewLeftConstraint?.constant = appearance.layout.insets.left
|
||||
bottomViewRightConstraint?.constant = appearance.layout.insets.right
|
||||
private func subviewConstraints(for seperatorView: UIView) -> SubviewConstraints {
|
||||
let leadingConstraint = seperatorView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
|
||||
let trailingConstraint = seperatorView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
|
||||
let topConstraint = seperatorView.topAnchor.constraint(equalTo: contentView.topAnchor)
|
||||
let bottomConstraint = seperatorView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
|
||||
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: leadingConstraint,
|
||||
trailingConstraint: trailingConstraint,
|
||||
topConstraint: topConstraint,
|
||||
bottomConstraint: bottomConstraint)
|
||||
|
||||
let centerXConstraint = seperatorView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor)
|
||||
let centerYConstraint = seperatorView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
|
||||
|
||||
let centerConstraints = CenterConstraints(centerXConstraint: centerXConstraint,
|
||||
centerYConstraint: centerYConstraint)
|
||||
|
||||
let sizeConstraints = SizeConstraints(widthConstraint: seperatorView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: seperatorView.heightAnchor.constraint(equalToConstant: .zero))
|
||||
|
||||
return SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,14 +47,6 @@ public struct SubviewConstraints: ConstraintsSet {
|
|||
centerConstraints.update(offset: centerOffset)
|
||||
sizeConstraints.update(from: size)
|
||||
edgeConstraints.update(from: insets)
|
||||
|
||||
for verticalConstraint in edgeConstraints.vertical {
|
||||
verticalConstraint.isActive = !centerOffset.vertical.isFinite
|
||||
}
|
||||
|
||||
for horizontalConstraint in edgeConstraints.horizontal {
|
||||
horizontalConstraint.isActive = !centerOffset.horizontal.isFinite
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - WrappedViewLayout shortcut
|
||||
|
|
|
|||
|
|
@ -72,6 +72,13 @@ public extension UIEdgeInsets {
|
|||
.init(top: top, left: left, bottom: bottom, right: right)
|
||||
}
|
||||
|
||||
func replacingNan(with defaultValue: CGFloat) -> Self {
|
||||
.init(top: top.isFinite ? top : defaultValue,
|
||||
left: left.isFinite ? left : defaultValue,
|
||||
bottom: bottom.isFinite ? bottom : defaultValue,
|
||||
right: right.isFinite ? right : defaultValue)
|
||||
}
|
||||
|
||||
func add(_ lhsKeyPath: KeyPath<Self, CGFloat>,
|
||||
to rhsKeyPath: KeyPath<Self, CGFloat>,
|
||||
of rhs: Self,
|
||||
|
|
|
|||
Loading…
Reference in New Issue