fix: fix code review notes
This commit is contained in:
parent
4e8f60543d
commit
ba4cdc6e0e
|
|
@ -7,4 +7,5 @@ target 'TIBottomSheet' do
|
|||
pod 'TIUIElements', :path => '../../../../TIUIElements/TIUIElements.podspec'
|
||||
pod 'TIUIKitCore', :path => '../../../../TIUIKitCore/TIUIKitCore.podspec'
|
||||
pod 'TISwiftUtils', :path => '../../../../TISwiftUtils/TISwiftUtils.podspec'
|
||||
pod 'TIBottomSheet', :path => '../../../../TIBottomSheet/TIBottomSheet.podspec'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -35,10 +35,120 @@ open class BaseModalViewController<ContentView: UIView,
|
|||
private(set) public lazy var contentView = createContentView()
|
||||
private(set) public lazy var footerView = createFooterView()
|
||||
|
||||
public var dragViewConstraints: SubviewConstraints?
|
||||
public var headerViewConstraints: SubviewConstraints?
|
||||
public var contentViewConstraints: SubviewConstraints?
|
||||
public var footerViewConstraints: SubviewConstraints?
|
||||
public private(set) lazy var dragViewBottomToHeaderViewTopConstraint: NSLayoutConstraint = {
|
||||
dragView.bottomAnchor.constraint(equalTo: headerView.topAnchor)
|
||||
}()
|
||||
|
||||
public private(set) lazy var dragViewBottomToContentViewTopConstraint: NSLayoutConstraint = {
|
||||
dragView.bottomAnchor.constraint(equalTo: contentView.topAnchor)
|
||||
}()
|
||||
|
||||
public private(set) lazy var dragViewConstraints: SubviewConstraints = {
|
||||
let trailingConstraint = dragView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
|
||||
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: dragView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
trailingConstraint: trailingConstraint,
|
||||
topConstraint: dragView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
bottomConstraint: dragViewBottomToHeaderViewTopConstraint)
|
||||
|
||||
let centerXConstraint = dragView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
|
||||
let centerYConstraint = dragView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
|
||||
|
||||
let centerConstraints = CenterConstraints(centerXConstraint: centerXConstraint,
|
||||
centerYConstraint: centerYConstraint)
|
||||
|
||||
let sizeConstraints = SizeConstraints(widthConstraint: dragView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: dragView.heightAnchor.constraint(equalToConstant: .zero))
|
||||
|
||||
return SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
}()
|
||||
|
||||
public private(set) lazy var headerViewToSuperviewTopConstraint: NSLayoutConstraint = {
|
||||
headerView.topAnchor.constraint(equalTo: view.topAnchor)
|
||||
}()
|
||||
|
||||
public private(set) lazy var headerBottomToContentTopConstraint: NSLayoutConstraint = {
|
||||
headerView.bottomAnchor.constraint(equalTo: contentView.topAnchor)
|
||||
}()
|
||||
|
||||
public private(set) lazy var headerViewConstraints: SubviewConstraints = {
|
||||
let leadingConstraint = headerView.leadingAnchor.constraint(equalTo: view.leadingAnchor)
|
||||
let trailingConstraint = headerView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
|
||||
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: leadingConstraint,
|
||||
trailingConstraint: trailingConstraint,
|
||||
topConstraint: dragViewBottomToHeaderViewTopConstraint,
|
||||
bottomConstraint: headerBottomToContentTopConstraint)
|
||||
|
||||
let centerXConstraint = headerView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
|
||||
let centerYConstraint = headerView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
|
||||
|
||||
let centerConstraints = CenterConstraints(centerXConstraint: centerXConstraint,
|
||||
centerYConstraint: centerYConstraint)
|
||||
|
||||
let sizeConstraints = SizeConstraints(widthConstraint: headerView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: headerView.heightAnchor.constraint(equalToConstant: .zero))
|
||||
|
||||
return SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
}()
|
||||
|
||||
public private(set) lazy var contentViewTopToSuperviewConstraint: NSLayoutConstraint = {
|
||||
contentView.topAnchor.constraint(equalTo: view.topAnchor)
|
||||
}()
|
||||
|
||||
public private(set) lazy var contentViewBottomToSuperviewConstraint: NSLayoutConstraint = {
|
||||
contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
||||
}()
|
||||
|
||||
public private(set) lazy var contentViewConstraints: SubviewConstraints = {
|
||||
let leadingConstraint = contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor)
|
||||
let trailingConstraint = contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
|
||||
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: leadingConstraint,
|
||||
trailingConstraint: trailingConstraint,
|
||||
topConstraint: headerBottomToContentTopConstraint,
|
||||
bottomConstraint: contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor))
|
||||
|
||||
let centerXConstraint = contentView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
|
||||
let centerYConstraint = contentView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
|
||||
|
||||
let centerConstraints = CenterConstraints(centerXConstraint: centerXConstraint,
|
||||
centerYConstraint: centerYConstraint)
|
||||
|
||||
let sizeConstraints = SizeConstraints(widthConstraint: contentView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: contentView.heightAnchor.constraint(equalToConstant: .zero))
|
||||
|
||||
return SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
}()
|
||||
|
||||
public private(set) lazy var footerViewConstraints: SubviewConstraints = {
|
||||
let leadingConstraint = footerView.leadingAnchor.constraint(equalTo: view.leadingAnchor)
|
||||
let trailingConstraint = footerView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
|
||||
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: leadingConstraint,
|
||||
trailingConstraint: trailingConstraint,
|
||||
topConstraint: footerView.topAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||
bottomConstraint: footerView.bottomAnchor.constraint(equalTo: view.bottomAnchor))
|
||||
|
||||
let centerXConstraint = footerView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
|
||||
let centerYConstraint = footerView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
|
||||
|
||||
let centerConstraints = CenterConstraints(centerXConstraint: centerXConstraint,
|
||||
centerYConstraint: centerYConstraint)
|
||||
|
||||
let sizeConstraints = SizeConstraints(widthConstraint: footerView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: footerView.heightAnchor.constraint(equalToConstant: .zero))
|
||||
|
||||
return SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
}()
|
||||
|
||||
public var keyboardDidShownObserver: NSObjectProtocol?
|
||||
public var keyboardDidHiddenObserver: NSObjectProtocol?
|
||||
|
|
@ -117,6 +227,10 @@ open class BaseModalViewController<ContentView: UIView,
|
|||
open override func configureLayout() {
|
||||
super.configureLayout()
|
||||
|
||||
for view in [dragView, headerView, contentView, footerView] {
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
}
|
||||
|
||||
configureDragViewLayout()
|
||||
configureHeaderViewLayout()
|
||||
configureContentViewLayout()
|
||||
|
|
@ -161,7 +275,7 @@ open class BaseModalViewController<ContentView: UIView,
|
|||
}
|
||||
|
||||
open func configureLayoutForKeyboard(_ notification: Notification, isKeyboardHidden: Bool) {
|
||||
guard let height = getKeyboardHeight(notification) else {
|
||||
guard let keyboardHeight = getKeyboardHeight(notification) else {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -169,11 +283,14 @@ open class BaseModalViewController<ContentView: UIView,
|
|||
if isKeyboardHidden {
|
||||
adjustScrollViewIfNeeded()
|
||||
} else {
|
||||
panScrollable.contentInset = .vertical(bottom: height)
|
||||
panScrollable.contentInset = .vertical(bottom: keyboardHeight)
|
||||
}
|
||||
} else if case let .presented(footerViewAppearance) = viewControllerAppearance.footerViewState {
|
||||
let bottomInset = footerViewAppearance.layout.insets.add(\.bottom,
|
||||
to: \.bottom,
|
||||
of: .vertical(bottom: keyboardHeight))
|
||||
|
||||
} else {
|
||||
contentViewConstraints?.edgeConstraints.update(from: isKeyboardHidden ? .zero : .vertical(height))
|
||||
footerViewConstraints.edgeConstraints.bottomConstraint.constant = bottomInset
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -182,8 +299,8 @@ open class BaseModalViewController<ContentView: UIView,
|
|||
return
|
||||
}
|
||||
|
||||
let verticalInsets = appearance.layout.insets.vertical
|
||||
let subviewVerticalInsets = appearance.subviewAppearance.layout.insets.vertical
|
||||
let verticalInsets = appearance.layout.insets.vertical(onNan: .zero)
|
||||
let subviewVerticalInsets = appearance.subviewAppearance.layout.insets.vertical(onNan: .zero)
|
||||
let totalHeight = getHeight(of: footerView) + verticalInsets + subviewVerticalInsets
|
||||
|
||||
panScrollable.contentInset = .vertical(bottom: totalHeight)
|
||||
|
|
@ -192,93 +309,92 @@ open class BaseModalViewController<ContentView: UIView,
|
|||
// MARK: - Private Methods
|
||||
|
||||
private func configureDragViewLayout() {
|
||||
guard case let .presented(appearance) = viewControllerAppearance.dragViewState else {
|
||||
guard case let .presented(dragViewAppearance) = viewControllerAppearance.dragViewState else {
|
||||
return
|
||||
}
|
||||
|
||||
dragView.translatesAutoresizingMaskIntoConstraints = false
|
||||
let bottomConstraint: NSLayoutConstraint
|
||||
let bottomConstant: CGFloat
|
||||
|
||||
let dragViewConstraints = SubviewConstraints(
|
||||
edgeConstraints: .init(topConstraint: dragView.topAnchor.constraint(equalTo: view.topAnchor)),
|
||||
centerConstraints: .init(centerXConstraint: dragView.centerXAnchor.constraint(equalTo: view.centerXAnchor)),
|
||||
sizeConstraints: .init(widthConstraint: dragView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: dragView.heightAnchor.constraint(equalToConstant: .zero)))
|
||||
if case let .presented(headerViewAppearance) = viewControllerAppearance.headerViewState {
|
||||
dragViewBottomToContentViewTopConstraint.isActive = false
|
||||
bottomConstraint = dragViewBottomToHeaderViewTopConstraint
|
||||
bottomConstant = dragViewAppearance.layout.insets.add(\.bottom,
|
||||
to: \.top,
|
||||
of: headerViewAppearance.layout.insets)
|
||||
} else {
|
||||
dragViewBottomToHeaderViewTopConstraint.isActive = false
|
||||
bottomConstraint = dragViewBottomToContentViewTopConstraint
|
||||
bottomConstant = dragViewAppearance.layout.insets.bottom
|
||||
}
|
||||
|
||||
self.dragViewConstraints = dragViewConstraints
|
||||
dragViewConstraints.edgeConstraints.bottomConstraint = bottomConstraint
|
||||
dragViewConstraints.update(from: dragViewAppearance.layout)
|
||||
|
||||
appearance.layout.update(constraints: dragViewConstraints)
|
||||
|
||||
NSLayoutConstraint.activate(dragViewConstraints.centerConstraints.allConstraints)
|
||||
bottomConstraint.setActiveConstantOrDeactivate(constant: bottomConstant)
|
||||
}
|
||||
|
||||
private func configureHeaderViewLayout() {
|
||||
guard case let .presented(appearance) = viewControllerAppearance.headerViewState else {
|
||||
guard case let .presented(headerViewAppearance) = viewControllerAppearance.headerViewState else {
|
||||
return
|
||||
}
|
||||
|
||||
headerView.translatesAutoresizingMaskIntoConstraints = false
|
||||
let topConstraint: NSLayoutConstraint
|
||||
let topConstant: CGFloat
|
||||
|
||||
let isTopView = dragViewConstraints == nil
|
||||
let headerViewConstraints = SubviewConstraints(
|
||||
edgeConstraints: .init(
|
||||
leadingConstraint: headerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
trailingConstraint: headerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
topConstraint: headerView.topAnchor.constraint(equalTo: isTopView ? view.topAnchor : dragView.bottomAnchor)),
|
||||
centerConstraints: .init(),
|
||||
sizeConstraints: .init(widthConstraint: headerView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: headerView.heightAnchor.constraint(equalToConstant: .zero)))
|
||||
self.headerViewConstraints = headerViewConstraints
|
||||
if case let .presented(dragViewAppearance) = viewControllerAppearance.dragViewState {
|
||||
dragViewBottomToContentViewTopConstraint.isActive = false
|
||||
topConstraint = dragViewBottomToHeaderViewTopConstraint
|
||||
|
||||
appearance.layout.update(constraints: headerViewConstraints)
|
||||
topConstant = dragViewAppearance.layout.insets.add(\.bottom,
|
||||
to: \.top,
|
||||
of: headerViewAppearance.layout.insets)
|
||||
} else {
|
||||
dragViewBottomToHeaderViewTopConstraint.isActive = false
|
||||
topConstraint = dragViewBottomToContentViewTopConstraint
|
||||
topConstant = headerViewAppearance.layout.insets.top
|
||||
}
|
||||
|
||||
headerViewConstraints.edgeConstraints.topConstraint = topConstraint
|
||||
headerViewConstraints.update(from: headerViewAppearance.layout)
|
||||
|
||||
topConstraint.setActiveConstantOrDeactivate(constant: topConstant)
|
||||
}
|
||||
|
||||
private func configureContentViewLayout() {
|
||||
contentView.translatesAutoresizingMaskIntoConstraints = false
|
||||
let topConstraint: NSLayoutConstraint
|
||||
let topConstant: CGFloat
|
||||
|
||||
var topView: UIView
|
||||
if case let .presented(headerViewAppearance) = viewControllerAppearance.headerViewState {
|
||||
dragViewBottomToContentViewTopConstraint.isActive = false
|
||||
contentViewTopToSuperviewConstraint.isActive = false
|
||||
|
||||
if headerViewConstraints == nil {
|
||||
if dragViewConstraints == nil {
|
||||
topView = view
|
||||
} else {
|
||||
topView = dragView
|
||||
}
|
||||
topConstraint = headerBottomToContentTopConstraint
|
||||
topConstant = headerViewAppearance.layout.insets.bottom
|
||||
} else if case let .presented(dragViewAppearance) = viewControllerAppearance.dragViewState {
|
||||
contentViewTopToSuperviewConstraint.isActive = false
|
||||
headerBottomToContentTopConstraint.isActive = false
|
||||
|
||||
topConstraint = dragViewBottomToContentViewTopConstraint
|
||||
topConstant = dragViewAppearance.layout.insets.bottom
|
||||
} else {
|
||||
topView = headerView
|
||||
headerBottomToContentTopConstraint.isActive = false
|
||||
dragViewBottomToContentViewTopConstraint.isActive = false
|
||||
|
||||
topConstraint = contentViewTopToSuperviewConstraint
|
||||
topConstant = .zero
|
||||
}
|
||||
|
||||
let contentViewConstraints = SubviewConstraints(
|
||||
edgeConstraints: .init(
|
||||
leadingConstraint: contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
trailingConstraint: contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
topConstraint: contentView.topAnchor.constraint(equalTo: topView.bottomAnchor),
|
||||
bottomConstraint: contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor)),
|
||||
centerConstraints: .init(),
|
||||
sizeConstraints: .init())
|
||||
self.contentViewConstraints = contentViewConstraints
|
||||
|
||||
NSLayoutConstraint.activate(contentViewConstraints.allConstraints)
|
||||
topConstraint.setActiveConstantOrDeactivate(constant: topConstant)
|
||||
contentViewConstraints.activate()
|
||||
}
|
||||
|
||||
private func configureFooterViewLayout() {
|
||||
guard case let .presented(appearance) = viewControllerAppearance.footerViewState else {
|
||||
guard case let .presented(footerViewAppearance) = viewControllerAppearance.footerViewState else {
|
||||
return
|
||||
}
|
||||
|
||||
footerView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
let footerViewConstraints = SubviewConstraints(
|
||||
edgeConstraints: .init(
|
||||
leadingConstraint: footerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
trailingConstraint: footerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
bottomConstraint: footerView.bottomAnchor.constraint(equalTo: view.bottomAnchor)),
|
||||
centerConstraints: .init(),
|
||||
sizeConstraints: .init(widthConstraint: footerView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: footerView.heightAnchor.constraint(equalToConstant: .zero)))
|
||||
self.footerViewConstraints = footerViewConstraints
|
||||
|
||||
appearance.layout.update(constraints: footerViewConstraints)
|
||||
footerViewConstraints.update(from: footerViewAppearance.layout)
|
||||
}
|
||||
|
||||
private func configureDragViewAppearance() {
|
||||
|
|
@ -307,7 +423,7 @@ open class BaseModalViewController<ContentView: UIView,
|
|||
footerView.isHidden = true
|
||||
|
||||
case let .presented(appearance):
|
||||
footerView.configureAppearance(appearance: appearance)
|
||||
footerView.configureBaseWrappedViewHolder(appearance: appearance)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -328,7 +444,7 @@ open class BaseModalViewController<ContentView: UIView,
|
|||
return .zero
|
||||
}
|
||||
|
||||
return appearance.layout.insets.vertical
|
||||
return appearance.layout.insets.vertical(onNan: .zero)
|
||||
}
|
||||
|
||||
private func getHeaderViewVerticalInsets() -> CGFloat {
|
||||
|
|
@ -336,7 +452,7 @@ open class BaseModalViewController<ContentView: UIView,
|
|||
return .zero
|
||||
}
|
||||
|
||||
return appearance.layout.insets.vertical
|
||||
return appearance.layout.insets.vertical(onNan: .zero)
|
||||
}
|
||||
|
||||
private func getFittingSize(forView view: UIView) -> CGSize {
|
||||
|
|
|
|||
|
|
@ -26,16 +26,16 @@ public struct ModalViewPresentationDetent: Hashable {
|
|||
|
||||
// MARK: - Default Values
|
||||
|
||||
public static var headerOnly: ModalViewPresentationDetent {
|
||||
ModalViewPresentationDetent(height: CGFloat(Int.min))
|
||||
public static var headerOnly: Self {
|
||||
Self(height: -.greatestFiniteMagnitude)
|
||||
}
|
||||
|
||||
public static func height(_ height: CGFloat) -> ModalViewPresentationDetent {
|
||||
ModalViewPresentationDetent(height: height)
|
||||
public static func height(_ height: CGFloat) -> Self {
|
||||
Self(height: height)
|
||||
}
|
||||
|
||||
public static var maxHeight: ModalViewPresentationDetent {
|
||||
ModalViewPresentationDetent(height: CGFloat(Int.max))
|
||||
public static var maxHeight: Self {
|
||||
Self(height: .greatestFiniteMagnitude)
|
||||
}
|
||||
|
||||
// MARK: - Public Properties
|
||||
|
|
|
|||
|
|
@ -32,12 +32,6 @@ public extension ModalFooterView {
|
|||
|
||||
enum State {
|
||||
case hidden
|
||||
case presented(UIView.BaseWrappedViewHolderAppearance<UIView.DefaultWrappedAppearance, UIView.DefaultWrappedLayout>)
|
||||
}
|
||||
|
||||
func configureAppearance(appearance: UIView.BaseWrappedViewHolderAppearance<UIView.DefaultWrappedAppearance, UIView.DefaultWrappedLayout>) {
|
||||
wrappedView.configureUIView(appearance: appearance.subviewAppearance)
|
||||
configureUIView(appearance: appearance)
|
||||
contentInsets = appearance.subviewAppearance.layout.insets
|
||||
case presented(BaseWrappedViewHolderAppearance<DefaultWrappedAppearance, DefaultWrappedLayout>)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ open class ModalHeaderView: BaseInitializableView, AppearanceConfigurable {
|
|||
}
|
||||
|
||||
public enum ContentViewState {
|
||||
case none
|
||||
case buttonLeft(BaseButtonStyle)
|
||||
case buttonRight(BaseButtonStyle)
|
||||
case buttons(left: BaseButtonStyle, right: BaseButtonStyle)
|
||||
|
|
@ -46,24 +45,60 @@ open class ModalHeaderView: BaseInitializableView, AppearanceConfigurable {
|
|||
public let leftButton = StatefulButton()
|
||||
public let rightButton = StatefulButton()
|
||||
|
||||
public private(set) lazy var leftTrailingToRightLeadingConstraint: NSLayoutConstraint = {
|
||||
leftButton.trailingAnchor.constraint(equalTo: rightButton.leadingAnchor)
|
||||
}()
|
||||
|
||||
public private(set) lazy var leftTrailingToSuperviewTrailing: NSLayoutConstraint = {
|
||||
leftButton.trailingAnchor.constraint(equalTo: rightButton.leadingAnchor)
|
||||
}()
|
||||
|
||||
public private(set) lazy var leftButtonConstraints: SubviewConstraints = {
|
||||
SubviewConstraints(
|
||||
edgeConstraints: .init(
|
||||
leadingConstraint: leftButton.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
topConstraint: leftButton.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: leftButton.bottomAnchor.constraint(equalTo: bottomAnchor)),
|
||||
centerConstraints: .init(centerYConstraint: leftButton.centerYAnchor.constraint(equalTo: centerYAnchor)),
|
||||
sizeConstraints: .init())
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: leftButton.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingConstraint: leftTrailingToRightLeadingConstraint,
|
||||
topConstraint: leftButton.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: leftButton.bottomAnchor.constraint(equalTo: bottomAnchor))
|
||||
|
||||
let centerXConstraint = leftButton.centerXAnchor.constraint(equalTo: centerXAnchor)
|
||||
let centerYConstraint = leftButton.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))
|
||||
|
||||
return SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
}()
|
||||
|
||||
public private(set) lazy var rightLeadingToSuperviewLeadingConstraint: NSLayoutConstraint = {
|
||||
rightButton.leadingAnchor.constraint(equalTo: leadingAnchor)
|
||||
}()
|
||||
|
||||
public private(set) lazy var rightButtonConstraints: SubviewConstraints = {
|
||||
SubviewConstraints(
|
||||
edgeConstraints: .init(
|
||||
trailingConstraint: rightButton.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
topConstraint: rightButton.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: rightButton.bottomAnchor.constraint(equalTo: bottomAnchor)),
|
||||
centerConstraints: .init(centerYConstraint: rightButton.centerYAnchor.constraint(equalTo: centerYAnchor)),
|
||||
sizeConstraints: .init())
|
||||
let trailingConstraint = rightButton.trailingAnchor.constraint(equalTo: trailingAnchor)
|
||||
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: rightButton.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingConstraint: trailingConstraint,
|
||||
topConstraint: rightButton.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: rightButton.bottomAnchor.constraint(equalTo: bottomAnchor))
|
||||
|
||||
let centerXConstraint = rightButton.centerXAnchor.constraint(equalTo: centerXAnchor)
|
||||
let centerYConstraint = rightButton.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))
|
||||
|
||||
return SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
}()
|
||||
|
||||
public var customViewConstraints: SubviewConstraints?
|
||||
|
||||
// MARK: - BaseInitializableView
|
||||
|
|
@ -79,8 +114,6 @@ open class ModalHeaderView: BaseInitializableView, AppearanceConfigurable {
|
|||
|
||||
[leftButton, rightButton]
|
||||
.forEach { $0.translatesAutoresizingMaskIntoConstraints = false }
|
||||
|
||||
NSLayoutConstraint.activate(leftButtonConstraints.allConstraints + rightButtonConstraints.allConstraints)
|
||||
}
|
||||
|
||||
// MARK: - AppearanceConfigurable
|
||||
|
|
@ -98,20 +131,27 @@ open class ModalHeaderView: BaseInitializableView, AppearanceConfigurable {
|
|||
switch state {
|
||||
case let .buttonLeft(style):
|
||||
leftButtonStyle = style
|
||||
leftButtonConstraints.edgeConstraints.trailingConstraint = leftTrailingToSuperviewTrailing
|
||||
|
||||
case let .buttonRight(style):
|
||||
rightButtonStyle = style
|
||||
rightButtonConstraints.edgeConstraints.leadingConstraint = rightLeadingToSuperviewLeadingConstraint
|
||||
|
||||
case let .buttons(left, right):
|
||||
leftButtonStyle = left
|
||||
rightButtonStyle = right
|
||||
leftButtonConstraints.edgeConstraints.trailingConstraint = leftTrailingToRightLeadingConstraint
|
||||
rightButtonConstraints.edgeConstraints.leadingConstraint = leftTrailingToRightLeadingConstraint
|
||||
|
||||
let spacing = left.appearance.layout.insets.add(\.right,
|
||||
to: \.left,
|
||||
of: right.appearance.layout.insets)
|
||||
|
||||
leftTrailingToRightLeadingConstraint.setActiveConstantOrDeactivate(constant: spacing)
|
||||
|
||||
case let .custom(view, appearance):
|
||||
configureCustomView(view, withLayout: appearance.layout)
|
||||
view.configureUIView(appearance: appearance)
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
configure(buttonStyle: leftButtonStyle, forButton: leftButton, constraints: leftButtonConstraints)
|
||||
|
|
@ -125,21 +165,24 @@ open class ModalHeaderView: BaseInitializableView, AppearanceConfigurable {
|
|||
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
let customViewConstraints = SubviewConstraints(
|
||||
edgeConstraints: .init(
|
||||
leadingConstraint: view.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingConstraint: view.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
topConstraint: view.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: view.bottomAnchor.constraint(equalTo: bottomAnchor)),
|
||||
centerConstraints: .init(centerXConstraint: view.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
centerYConstraint: view.centerYAnchor.constraint(equalTo: centerYAnchor)),
|
||||
sizeConstraints: .init())
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: view.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingConstraint: view.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
topConstraint: view.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: view.bottomAnchor.constraint(equalTo: bottomAnchor))
|
||||
|
||||
let centerConstraints = CenterConstraints(centerXConstraint: view.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
centerYConstraint: view.centerYAnchor.constraint(equalTo: centerYAnchor))
|
||||
|
||||
let sizeConstraints = SizeConstraints(widthConstraint: view.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: view.heightAnchor.constraint(equalToConstant: .zero))
|
||||
|
||||
let customViewConstraints = SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
|
||||
self.customViewConstraints = customViewConstraints
|
||||
|
||||
NSLayoutConstraint.deactivate(customViewConstraints.centerConstraints.allConstraints)
|
||||
|
||||
layout.update(constraints: customViewConstraints)
|
||||
customViewConstraints.update(from: layout)
|
||||
}
|
||||
|
||||
private func configure(buttonStyle: BaseButtonStyle?,
|
||||
|
|
@ -153,9 +196,7 @@ open class ModalHeaderView: BaseInitializableView, AppearanceConfigurable {
|
|||
|
||||
button.isHidden = false
|
||||
|
||||
if let layout = buttonStyle.appearance[.normal]?.layout, let constraints {
|
||||
layout.update(constraints: constraints)
|
||||
}
|
||||
constraints?.update(from: buttonStyle.appearance.layout)
|
||||
|
||||
button.apply(style: buttonStyle)
|
||||
}
|
||||
|
|
@ -163,20 +204,20 @@ open class ModalHeaderView: BaseInitializableView, AppearanceConfigurable {
|
|||
|
||||
// MARK: - Appearance
|
||||
|
||||
extension ModalHeaderView {
|
||||
public extension ModalHeaderView {
|
||||
|
||||
public final class Appearance: UIView.BaseWrappedAppearance<UIView.DefaultWrappedLayout>, WrappedViewAppearance {
|
||||
final class Appearance: BaseWrappedAppearance<DefaultWrappedLayout>, WrappedViewAppearance {
|
||||
public static var defaultAppearance: Self {
|
||||
.init()
|
||||
Self()
|
||||
}
|
||||
|
||||
public var contentViewState: ContentViewState
|
||||
|
||||
public init(layout: UIView.DefaultWrappedLayout = .defaultLayout,
|
||||
public init(layout: DefaultWrappedLayout = .defaultLayout,
|
||||
backgroundColor: UIColor = .clear,
|
||||
border: UIViewBorder = .init(),
|
||||
shadow: UIViewShadow? = nil,
|
||||
contentViewState: ContentViewState = .none) {
|
||||
contentViewState: ContentViewState = .buttonLeft(.init())) {
|
||||
|
||||
self.contentViewState = contentViewState
|
||||
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ target 'TIBottomSheet' do
|
|||
pod 'TIUIElements', :path => '../../../../TIUIElements/TIUIElements.podspec'
|
||||
pod 'TIUIKitCore', :path => '../../../../TIUIKitCore/TIUIKitCore.podspec'
|
||||
pod 'TISwiftUtils', :path => '../../../../TISwiftUtils/TISwiftUtils.podspec'
|
||||
pod 'TIBottomSheet', :path => '../../../../TIBottomSheet/TIBottomSheet.podspec'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -56,7 +56,9 @@ class CustomViewController: BaseModalViewController<UIView, UIView> {
|
|||
$0.layout.size = .fixedHeight(52)
|
||||
$0.backgroundColor = .white
|
||||
$0.contentViewState = .buttonLeft(.init(titles: [.normal: "Close"],
|
||||
appearance: [.normal: .init(backgroundColor: .blue)]))
|
||||
appearance: .init(stateAppearances: [
|
||||
.normal: .init(backgroundColor: .blue)
|
||||
])))
|
||||
})
|
||||
|
||||
return appearance
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ Pod::Spec.new do |s|
|
|||
s.ios.deployment_target = '11.0'
|
||||
s.swift_versions = ['5.7']
|
||||
|
||||
sources = '/Sources/**/*'
|
||||
sources = 'Sources/**/*'
|
||||
if ENV["DEVELOPMENT_INSTALL"] # installing using :path =>
|
||||
s.source_files = sources
|
||||
s.exclude_files = s.name + '.app'
|
||||
else
|
||||
s.source_files = s.name + sources
|
||||
s.source_files = s.name + '/' + sources
|
||||
s.exclude_files = s.name + '/*.app'
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ open class DefaultFilterTableViewCell: ContainerTableViewCell<DefaultPickerView>
|
|||
// MARK: - Open methods
|
||||
|
||||
open func updateAppearance(with appearance: FilterCellStateAppearance) {
|
||||
contentInsets = appearance.contentInsets
|
||||
wrappedContentInsets = appearance.contentInsets
|
||||
wrappedView.textColor = appearance.fontColor
|
||||
wrappedView.images = appearance.stateImages ?? [:]
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ open class DefaultFilterCollectionCell: ContainerCollectionViewCell<UILabel>, Co
|
|||
// MARK: - Open methdos
|
||||
|
||||
open func updateAppearance(with appearance: FilterCellStateAppearance) {
|
||||
contentInsets = appearance.contentInsets
|
||||
wrappedContentInsets = appearance.contentInsets
|
||||
wrappedView.textColor = appearance.fontColor
|
||||
|
||||
backgroundColor = appearance.backgroundColor
|
||||
|
|
|
|||
|
|
@ -20,32 +20,51 @@
|
|||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
import TIUIKitCore
|
||||
import UIKit
|
||||
|
||||
public final class ScrollViewWrapper<ContentView: UIView>: UIScrollView {
|
||||
open class BaseInitializeableScrollView: UIScrollView, InitializableViewProtocol {
|
||||
public var callbacks: [ViewCallbacks] = []
|
||||
|
||||
private let contentView: ContentView
|
||||
override public init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
self.contentView = ContentView()
|
||||
|
||||
super.init(frame: .zero)
|
||||
|
||||
addSubview(contentView)
|
||||
contentView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
contentView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
contentView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
contentView.topAnchor.constraint(equalTo: topAnchor),
|
||||
contentView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
contentView.widthAnchor.constraint(equalTo: widthAnchor)
|
||||
])
|
||||
initializeView()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
contentView = ContentView()
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
super.init(coder: coder)
|
||||
initializeView()
|
||||
}
|
||||
|
||||
override open func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
for callback in callbacks {
|
||||
callback.onDidLayoutSubviews()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - InitializableView
|
||||
|
||||
open func addViews() {
|
||||
// override in subclass
|
||||
}
|
||||
|
||||
open func configureLayout() {
|
||||
// override in subclass
|
||||
}
|
||||
|
||||
open func bindViews() {
|
||||
// override in subclass
|
||||
}
|
||||
|
||||
open func configureAppearance() {
|
||||
// override in subclass
|
||||
}
|
||||
|
||||
open func localize() {
|
||||
// override in subclass
|
||||
}
|
||||
}
|
||||
|
|
@ -38,29 +38,47 @@ open class BaseListItemView<LeadingView: UIView,
|
|||
}()
|
||||
|
||||
public private(set) lazy var leadingViewConstraints: SubviewConstraints = {
|
||||
SubviewConstraints(edgeConstraints: EdgeConstraints(leadingConstraint: leadingView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingConstraint: middleViewLeadingConstraint,
|
||||
topConstraint: leadingView.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: leadingView.bottomAnchor.constraint(equalTo: bottomAnchor)),
|
||||
centerConstraints: CenterConstraints(centerXConstraint: leadingView.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
centerYConstraint: leadingView.centerYAnchor.constraint(equalTo: centerYAnchor)),
|
||||
sizeConstraints: SizeConstraints(widthConstraint: leadingView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: leadingView.heightAnchor.constraint(equalToConstant: .zero)))
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: leadingView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingConstraint: middleViewLeadingConstraint,
|
||||
topConstraint: leadingView.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: leadingView.bottomAnchor.constraint(equalTo: bottomAnchor))
|
||||
|
||||
let centerXConstraint = leadingView.centerXAnchor.constraint(equalTo: centerXAnchor)
|
||||
let centerYConstraint = leadingView.centerYAnchor.constraint(equalTo: centerYAnchor)
|
||||
|
||||
let centerConstraints = CenterConstraints(centerXConstraint: centerXConstraint,
|
||||
centerYConstraint: centerYConstraint)
|
||||
|
||||
let sizeConstraints = SizeConstraints(widthConstraint: leadingView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: leadingView.heightAnchor.constraint(equalToConstant: .zero))
|
||||
|
||||
return SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
}()
|
||||
|
||||
public private(set) lazy var trailingViewLeadingToMiddleViewConstraint: NSLayoutConstraint = {
|
||||
public private(set) lazy var trailingViewLeadingToMiddleConstraint: NSLayoutConstraint = {
|
||||
trailingView.leadingAnchor.constraint(equalTo: middleView.trailingAnchor)
|
||||
}()
|
||||
|
||||
public private(set) lazy var middleViewConstraints: SubviewConstraints = {
|
||||
SubviewConstraints(edgeConstraints: EdgeConstraints(leadingConstraint: middleViewLeadingConstraint,
|
||||
trailingConstraint: trailingViewLeadingToMiddleViewConstraint,
|
||||
topConstraint: middleView.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: middleView.bottomAnchor.constraint(equalTo: bottomAnchor)),
|
||||
centerConstraints: CenterConstraints(centerXConstraint: middleView.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
centerYConstraint: middleView.centerYAnchor.constraint(equalTo: centerYAnchor)),
|
||||
sizeConstraints: SizeConstraints(widthConstraint: middleView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: middleView.heightAnchor.constraint(equalToConstant: .zero)))
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: middleViewLeadingConstraint,
|
||||
trailingConstraint: trailingViewLeadingToMiddleConstraint,
|
||||
topConstraint: middleView.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: middleView.bottomAnchor.constraint(equalTo: bottomAnchor))
|
||||
|
||||
let centerXConstraint = middleView.centerXAnchor.constraint(equalTo: centerXAnchor)
|
||||
let centerYConstraint = middleView.centerYAnchor.constraint(equalTo: centerYAnchor)
|
||||
|
||||
let centerConstraints = CenterConstraints(centerXConstraint: centerXConstraint,
|
||||
centerYConstraint: centerYConstraint)
|
||||
|
||||
let sizeConstraints = SizeConstraints(widthConstraint: middleView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: middleView.heightAnchor.constraint(equalToConstant: .zero))
|
||||
|
||||
return SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
}()
|
||||
|
||||
public private(set) lazy var middleViewLeadingToSuperViewConstraint: NSLayoutConstraint = {
|
||||
|
|
@ -72,14 +90,25 @@ open class BaseListItemView<LeadingView: UIView,
|
|||
}()
|
||||
|
||||
public private(set) lazy var trailingViewConstraints: SubviewConstraints = {
|
||||
SubviewConstraints(edgeConstraints: EdgeConstraints(leadingConstraint: trailingViewLeadingToMiddleViewConstraint,
|
||||
trailingConstraint: trailingView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
topConstraint: trailingView.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: trailingView.bottomAnchor.constraint(equalTo: bottomAnchor)),
|
||||
centerConstraints: CenterConstraints(centerXConstraint: middleView.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
centerYConstraint: trailingView.centerYAnchor.constraint(equalTo: centerYAnchor)),
|
||||
sizeConstraints: SizeConstraints(widthConstraint: trailingView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: trailingView.heightAnchor.constraint(equalToConstant: .zero)))
|
||||
let trailingConstraint = trailingView.trailingAnchor.constraint(equalTo: trailingAnchor)
|
||||
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: trailingViewLeadingToMiddleConstraint,
|
||||
trailingConstraint: trailingConstraint,
|
||||
topConstraint: trailingView.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: trailingView.bottomAnchor.constraint(equalTo: bottomAnchor))
|
||||
|
||||
let centerXConstraint = middleView.centerXAnchor.constraint(equalTo: centerXAnchor)
|
||||
let centerYConstraint = trailingView.centerYAnchor.constraint(equalTo: centerYAnchor)
|
||||
|
||||
let centerConstraints = CenterConstraints(centerXConstraint: centerXConstraint,
|
||||
centerYConstraint: centerYConstraint)
|
||||
|
||||
let sizeConstraints = SizeConstraints(widthConstraint: trailingView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: trailingView.heightAnchor.constraint(equalToConstant: .zero))
|
||||
|
||||
return SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
}()
|
||||
|
||||
// MARK: - Public Properties
|
||||
|
|
@ -105,9 +134,6 @@ open class BaseListItemView<LeadingView: UIView,
|
|||
|
||||
[leadingView, middleView, trailingView]
|
||||
.forEach { $0.translatesAutoresizingMaskIntoConstraints = false }
|
||||
|
||||
[leadingViewConstraints, middleViewConstraints, trailingViewConstraints]
|
||||
.forEach { $0.update(insets: .zero, size: .infinity, centerOffset: .nan) }
|
||||
}
|
||||
|
||||
// MARK: - Public methods
|
||||
|
|
@ -118,21 +144,21 @@ open class BaseListItemView<LeadingView: UIView,
|
|||
|
||||
configureUIView(appearance: appearance)
|
||||
|
||||
updateLeadingViewLayout(leadingViewLayout: appearance.leadingViewAppearance.layout,
|
||||
middleViewLayout: appearance.middleViewAppearance.layout)
|
||||
update(leadingViewLayout: appearance.leadingViewAppearance.layout,
|
||||
middleViewLayout: appearance.middleViewAppearance.layout)
|
||||
|
||||
updateMiddleViewLayout(middleViewLayout: appearance.middleViewAppearance.layout)
|
||||
update(middleViewLayout: appearance.middleViewAppearance.layout)
|
||||
|
||||
updateTrailingViewLayout(trailingViewLayout: appearance.trailingAppearance.layout,
|
||||
middleViewLayout: appearance.middleViewAppearance.layout)
|
||||
update(trailingViewLayout: appearance.trailingAppearance.layout,
|
||||
middleViewLayout: appearance.middleViewAppearance.layout)
|
||||
}
|
||||
|
||||
// MARK: - Private methdos
|
||||
|
||||
private func updateLeadingViewLayout(leadingViewLayout: WrappedViewLayout,
|
||||
middleViewLayout: WrappedViewLayout) {
|
||||
private func update(leadingViewLayout: WrappedViewLayout,
|
||||
middleViewLayout: WrappedViewLayout) {
|
||||
|
||||
let leadingToSuperviewContraint: NSLayoutConstraint?
|
||||
let leadingToSuperviewContraint: NSLayoutConstraint
|
||||
let leadingViewLeftInset: CGFloat
|
||||
|
||||
if isLeadingViewHidden {
|
||||
|
|
@ -141,11 +167,15 @@ open class BaseListItemView<LeadingView: UIView,
|
|||
|
||||
leadingToSuperviewContraint = middleViewLeadingToSuperViewConstraint
|
||||
leadingViewLeftInset = middleViewLayout.insets.left
|
||||
|
||||
} else {
|
||||
middleViewLeadingConstraint.constant = leadingViewLayout.insets.right + middleViewLayout.insets.left
|
||||
leadingViewConstraints.edgeConstraints.leadingConstraint?.isActive = true
|
||||
middleViewConstraints.edgeConstraints.leadingConstraint?.isActive = true
|
||||
let middleViewLeadingConstant = leadingViewLayout.insets.add(\.left,
|
||||
to: \.right,
|
||||
of: middleViewLayout.insets,
|
||||
onNan: .zero)
|
||||
|
||||
middleViewLeadingConstraint.setActiveConstantOrDeactivate(constant: middleViewLeadingConstant)
|
||||
leadingViewConstraints.edgeConstraints.leadingConstraint.isActive = true
|
||||
middleViewConstraints.edgeConstraints.leadingConstraint.isActive = true
|
||||
middleViewLeadingToSuperViewConstraint.isActive = false
|
||||
|
||||
leadingViewConstraints.update(from: leadingViewLayout)
|
||||
|
|
@ -154,17 +184,17 @@ open class BaseListItemView<LeadingView: UIView,
|
|||
leadingViewLeftInset = leadingViewLayout.insets.left
|
||||
}
|
||||
|
||||
leadingToSuperviewContraint?.constant = leadingViewLeftInset
|
||||
leadingToSuperviewContraint.setActiveConstantOrDeactivate(constant: leadingViewLeftInset)
|
||||
}
|
||||
|
||||
private func updateMiddleViewLayout(middleViewLayout: WrappedViewLayout) {
|
||||
private func update(middleViewLayout: WrappedViewLayout) {
|
||||
middleViewConstraints.update(from: middleViewLayout)
|
||||
}
|
||||
|
||||
private func updateTrailingViewLayout(trailingViewLayout: WrappedViewLayout,
|
||||
middleViewLayout: WrappedViewLayout) {
|
||||
private func update(trailingViewLayout: WrappedViewLayout,
|
||||
middleViewLayout: WrappedViewLayout) {
|
||||
|
||||
let trailingToSuperviewConstraint: NSLayoutConstraint?
|
||||
let trailingToSuperviewConstraint: NSLayoutConstraint
|
||||
let trailingViewRightInset: CGFloat
|
||||
|
||||
if isTrailingViewHidden {
|
||||
|
|
@ -173,10 +203,14 @@ open class BaseListItemView<LeadingView: UIView,
|
|||
|
||||
trailingToSuperviewConstraint = middleViewTrailingToSuperViewConstraint
|
||||
trailingViewRightInset = middleViewLayout.insets.right
|
||||
|
||||
} else {
|
||||
trailingViewLeadingToMiddleViewConstraint.constant = middleViewLayout.insets.right + trailingViewLayout.insets.left
|
||||
trailingViewLeadingToMiddleViewConstraint.isActive = true
|
||||
let trailingViewLeadingToMiddleConstant = middleViewLayout.insets.add(\.right,
|
||||
to: \.left,
|
||||
of: trailingViewLayout.insets,
|
||||
onNan: .zero)
|
||||
|
||||
trailingViewLeadingToMiddleConstraint.setActiveConstantOrDeactivate(constant: trailingViewLeadingToMiddleConstant)
|
||||
trailingViewLeadingToMiddleConstraint.isActive = true
|
||||
middleViewTrailingToSuperViewConstraint.isActive = false
|
||||
|
||||
trailingViewConstraints.update(from: trailingViewLayout)
|
||||
|
|
@ -185,6 +219,6 @@ open class BaseListItemView<LeadingView: UIView,
|
|||
trailingViewRightInset = trailingViewLayout.insets.right
|
||||
}
|
||||
|
||||
trailingToSuperviewConstraint?.constant = -trailingViewRightInset
|
||||
trailingToSuperviewConstraint.setActiveConstantOrDeactivate(constant: -trailingViewRightInset)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,19 +33,19 @@ open class BasePlaceholderImageView<Placeholder: UIView>: UIImageView,
|
|||
|
||||
public private(set) lazy var wrappedView = Placeholder()
|
||||
|
||||
public var contentInsets: UIEdgeInsets = .zero {
|
||||
public var wrappedContentInsets: UIEdgeInsets = .zero {
|
||||
didSet {
|
||||
update(subviewConstraints: placeholderConstraints)
|
||||
}
|
||||
}
|
||||
|
||||
public var contentSize: CGSize = .infinity {
|
||||
public var wrappedContentSize: CGSize = .infinity {
|
||||
didSet {
|
||||
update(subviewConstraints: placeholderConstraints)
|
||||
}
|
||||
}
|
||||
|
||||
public var contentCenterOffset: UIOffset = .nan {
|
||||
public var wrappedContentCenterOffset: UIOffset = .nan {
|
||||
didSet {
|
||||
update(subviewConstraints: placeholderConstraints)
|
||||
}
|
||||
|
|
@ -118,7 +118,9 @@ open class BasePlaceholderImageView<Placeholder: UIView>: UIImageView,
|
|||
|
||||
// MARK: - Open methods
|
||||
|
||||
open func configureBasePlaceholder(appearance: BaseWrappedViewHolderAppearance<UIView.DefaultWrappedAppearance, some WrappedViewLayout>) {
|
||||
open func configureBasePlaceholder(appearance: BaseWrappedViewHolderAppearance<
|
||||
some BaseWrappedAppearance<some ViewLayout>,
|
||||
some WrappedViewLayout>) {
|
||||
configureUIView(appearance: appearance)
|
||||
|
||||
wrappedView.configureUIView(appearance: appearance.subviewAppearance)
|
||||
|
|
|
|||
|
|
@ -31,44 +31,74 @@ open class BasePlaceholderView<ImageView: UIView>: BaseInitializableView {
|
|||
public let controlsStackView = UIStackView()
|
||||
|
||||
public private(set) lazy var imageViewConstraints: SubviewConstraints = {
|
||||
SubviewConstraints(edgeConstraints: EdgeConstraints(leadingConstraint: imageView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingConstraint: imageView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
topConstraint: imageView.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: imageView.bottomAnchor.constraint(equalTo: textView.topAnchor)),
|
||||
centerConstraints: CenterConstraints(centerXConstraint: imageView.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
centerYConstraint: imageView.centerYAnchor.constraint(equalTo: centerYAnchor)),
|
||||
sizeConstraints: SizeConstraints(widthConstraint: imageView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: imageView.heightAnchor.constraint(equalToConstant: .zero)))
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: imageView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingConstraint: imageView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
topConstraint: imageView.topAnchor.constraint(equalTo: topAnchor),
|
||||
bottomConstraint: imageView.bottomAnchor.constraint(equalTo: textView.topAnchor))
|
||||
|
||||
let centerConstraints = CenterConstraints(centerXConstraint: imageView.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
centerYConstraint: imageView.centerYAnchor.constraint(equalTo: centerYAnchor))
|
||||
|
||||
let sizeConstraints = SizeConstraints(widthConstraint: imageView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: imageView.heightAnchor.constraint(equalToConstant: .zero))
|
||||
|
||||
return SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
}()
|
||||
|
||||
public private(set) lazy var textViewTopToSuperviewTopConstraint: NSLayoutConstraint = {
|
||||
textView.topAnchor.constraint(equalTo: topAnchor)
|
||||
}()
|
||||
|
||||
public private(set) lazy var textViewBottomToSuperviewBottomConstraint: NSLayoutConstraint = {
|
||||
public private(set) lazy var textViewToSuperviewBottomConstraint: NSLayoutConstraint = {
|
||||
textView.bottomAnchor.constraint(equalTo: bottomAnchor)
|
||||
}()
|
||||
|
||||
public private(set) lazy var textViewConstraints: SubviewConstraints = {
|
||||
SubviewConstraints(edgeConstraints: EdgeConstraints(leadingConstraint: textView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingConstraint: textView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
topConstraint: textView.topAnchor.constraint(equalTo: imageView.bottomAnchor),
|
||||
bottomConstraint: textView.bottomAnchor.constraint(lessThanOrEqualTo: controlsStackView.topAnchor)),
|
||||
centerConstraints: CenterConstraints(centerXConstraint: textView.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
centerYConstraint: textView.centerYAnchor.constraint(equalTo: centerYAnchor)),
|
||||
sizeConstraints: SizeConstraints(widthConstraint: textView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: textView.heightAnchor.constraint(equalToConstant: .zero)))
|
||||
let bottomConstraint = textView.bottomAnchor.constraint(lessThanOrEqualTo: controlsStackView.topAnchor)
|
||||
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: textView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingConstraint: textView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
topConstraint: textView.topAnchor.constraint(equalTo: imageView.bottomAnchor),
|
||||
bottomConstraint: bottomConstraint)
|
||||
|
||||
let centerConstraints = CenterConstraints(centerXConstraint: textView.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
centerYConstraint: textView.centerYAnchor.constraint(equalTo: centerYAnchor))
|
||||
|
||||
let sizeConstraints = SizeConstraints(widthConstraint: textView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: textView.heightAnchor.constraint(equalToConstant: .zero))
|
||||
|
||||
return SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
}()
|
||||
|
||||
public private(set) lazy var controlsViewConstraints: SubviewConstraints = {
|
||||
SubviewConstraints(edgeConstraints: EdgeConstraints(leadingConstraint: controlsStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingConstraint: controlsStackView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
topConstraint: controlsStackView.topAnchor.constraint(equalTo: textView.bottomAnchor),
|
||||
bottomConstraint: controlsStackView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor)),
|
||||
centerConstraints: CenterConstraints(centerXConstraint: controlsStackView.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
centerYConstraint: controlsStackView.centerYAnchor.constraint(equalTo: centerYAnchor)),
|
||||
sizeConstraints: SizeConstraints(widthConstraint: controlsStackView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: controlsStackView.heightAnchor.constraint(equalToConstant: .zero)))
|
||||
let leadingConstraint = controlsStackView.leadingAnchor.constraint(equalTo: leadingAnchor)
|
||||
let trailingConstraint = controlsStackView.trailingAnchor.constraint(equalTo: trailingAnchor)
|
||||
let topConstraint = controlsStackView.topAnchor.constraint(equalTo: textView.bottomAnchor)
|
||||
let bottomConstraint = controlsStackView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor)
|
||||
|
||||
let edgeConstraints = EdgeConstraints(leadingConstraint: leadingConstraint,
|
||||
trailingConstraint: trailingConstraint,
|
||||
topConstraint: topConstraint,
|
||||
bottomConstraint: bottomConstraint)
|
||||
|
||||
let centerXConstraint = controlsStackView.centerXAnchor.constraint(equalTo: centerXAnchor)
|
||||
let centerYConstraint = controlsStackView.centerYAnchor.constraint(equalTo: centerYAnchor)
|
||||
|
||||
let centerConstraints = CenterConstraints(centerXConstraint: centerXConstraint,
|
||||
centerYConstraint: centerYConstraint)
|
||||
|
||||
let heightConstraint = controlsStackView.heightAnchor.constraint(equalToConstant: .zero)
|
||||
|
||||
let sizeConstraints = SizeConstraints(widthConstraint: controlsStackView.widthAnchor.constraint(equalToConstant: .zero),
|
||||
heightConstraint: heightConstraint)
|
||||
|
||||
return SubviewConstraints(edgeConstraints: edgeConstraints,
|
||||
centerConstraints: centerConstraints,
|
||||
sizeConstraints: sizeConstraints)
|
||||
}()
|
||||
|
||||
public var keyboardDidShownObserver: NSObjectProtocol?
|
||||
|
|
@ -82,18 +112,6 @@ open class BasePlaceholderView<ImageView: UIView>: BaseInitializableView {
|
|||
controlsStackView.isHidden || controlsStackView.arrangedSubviews.isEmpty
|
||||
}
|
||||
|
||||
// MARK: - Deinit
|
||||
|
||||
deinit {
|
||||
if let keyboardDidShownObserver = keyboardDidShownObserver {
|
||||
NotificationCenter.default.removeObserver(keyboardDidShownObserver)
|
||||
}
|
||||
|
||||
if let keyboardDidHiddenObserver = keyboardDidHiddenObserver {
|
||||
NotificationCenter.default.removeObserver(keyboardDidHiddenObserver)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - BaseInitializableView
|
||||
|
||||
open override func addViews() {
|
||||
|
|
@ -146,7 +164,7 @@ open class BasePlaceholderView<ImageView: UIView>: BaseInitializableView {
|
|||
|
||||
// MARK: - Open methods
|
||||
|
||||
open func applyBaseStyle(style: BasePlaceholderStyle<some BaseAppearance<some WrappedViewAppearance> & ViewAppearance>) {
|
||||
open func applyBase(style: BasePlaceholderStyle<some BaseAppearance<some WrappedViewAppearance> & ViewAppearance>) {
|
||||
textView.configure(with: style.titleSubtitle)
|
||||
controlsStackView.axis = style.controlsViewAxis
|
||||
|
||||
|
|
@ -158,7 +176,7 @@ open class BasePlaceholderView<ImageView: UIView>: BaseInitializableView {
|
|||
controlsStackView.addArrangedSubview(button)
|
||||
}
|
||||
|
||||
configureAppearance(appearance: style.appearance)
|
||||
configureBase(appearance: style.appearance)
|
||||
}
|
||||
|
||||
open func addAction(_ action: UIButton.Action,
|
||||
|
|
@ -169,10 +187,10 @@ open class BasePlaceholderView<ImageView: UIView>: BaseInitializableView {
|
|||
button?.addTarget(action.target, action: action.action, for: action.event)
|
||||
}
|
||||
|
||||
open func configureAppearance(appearance: BaseAppearance<some WrappedViewAppearance>) {
|
||||
configureImageViewLayout(layout: appearance.imageViewAppearance.layout)
|
||||
configureTextViewLayout(layout: appearance.textViewAppearance.layout)
|
||||
configureControlsViewLayout(layout: appearance.controlsViewAppearance.layout)
|
||||
open func configureBase(appearance: BaseAppearance<some WrappedViewAppearance>) {
|
||||
configureImageView(layout: appearance.imageViewAppearance.layout)
|
||||
configureTextView(layout: appearance.textViewAppearance.layout)
|
||||
configureControlsView(layout: appearance.controlsViewAppearance.layout)
|
||||
|
||||
configureUIView(appearance: appearance)
|
||||
textView.configure(appearance: appearance.textViewAppearance)
|
||||
|
|
@ -183,13 +201,13 @@ open class BasePlaceholderView<ImageView: UIView>: BaseInitializableView {
|
|||
let multiplier = isKeyboardHidden ? 1.0 : -1.0
|
||||
|
||||
if let height = getKeyboardHeight(notification) {
|
||||
controlsViewConstraints.edgeConstraints.bottomConstraint?.constant = multiplier * height / 2
|
||||
controlsViewConstraints.edgeConstraints.bottomConstraint.constant = multiplier * height / 2
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private methods
|
||||
|
||||
private func configureImageViewLayout(layout: WrappedViewLayout) {
|
||||
private func configureImageView(layout: WrappedViewLayout) {
|
||||
guard !isImageViewHidden else {
|
||||
imageViewConstraints.deactivate()
|
||||
return
|
||||
|
|
@ -198,17 +216,17 @@ open class BasePlaceholderView<ImageView: UIView>: BaseInitializableView {
|
|||
imageViewConstraints.update(from: layout)
|
||||
}
|
||||
|
||||
private func configureTextViewLayout(layout: WrappedViewLayout) {
|
||||
textViewConstraints.edgeConstraints.topConstraint?.isActive = !isImageViewHidden
|
||||
private func configureTextView(layout: WrappedViewLayout) {
|
||||
textViewConstraints.edgeConstraints.topConstraint.isActive = !isImageViewHidden
|
||||
textViewTopToSuperviewTopConstraint.isActive = isImageViewHidden
|
||||
|
||||
textViewConstraints.edgeConstraints.bottomConstraint?.isActive = !isControlsViewHidden
|
||||
textViewBottomToSuperviewBottomConstraint.isActive = isControlsViewHidden
|
||||
textViewConstraints.edgeConstraints.bottomConstraint.isActive = !isControlsViewHidden
|
||||
textViewToSuperviewBottomConstraint.isActive = isControlsViewHidden
|
||||
|
||||
textViewConstraints.update(from: layout)
|
||||
}
|
||||
|
||||
private func configureControlsViewLayout(layout: SpacedWrappedViewLayout) {
|
||||
private func configureControlsView(layout: SpacedWrappedViewLayout) {
|
||||
guard !isControlsViewHidden else {
|
||||
controlsViewConstraints.deactivate()
|
||||
return
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public final class DefaultPlaceholderView: BasePlaceholderView<UIImageView>, App
|
|||
public func apply(style: DefaultPlaceholderStyle) {
|
||||
imageView.image = style.image
|
||||
|
||||
super.applyBaseStyle(style: style)
|
||||
super.applyBase(style: style)
|
||||
|
||||
guard let image = imageView.image else {
|
||||
return
|
||||
|
|
@ -44,14 +44,14 @@ public final class DefaultPlaceholderView: BasePlaceholderView<UIImageView>, App
|
|||
// MARK: - AppearanceConfigurable
|
||||
|
||||
public func configure(appearance: Appearance) {
|
||||
configureAppearance(appearance: appearance)
|
||||
configureBase(appearance: appearance)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Default appearance model
|
||||
|
||||
extension DefaultPlaceholderView {
|
||||
public final class Appearance: BaseAppearance<UIView.DefaultWrappedAppearance>, ViewAppearance {
|
||||
public extension DefaultPlaceholderView {
|
||||
final class Appearance: BaseAppearance<UIView.DefaultWrappedAppearance>, ViewAppearance {
|
||||
public static var defaultAppearance: Self {
|
||||
.init()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@
|
|||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
extension StatefulButton {
|
||||
public func apply(style: BaseButtonStyle) {
|
||||
public extension StatefulButton {
|
||||
func apply(style: BaseButtonStyle) {
|
||||
set(titles: style.titles)
|
||||
set(images: style.images)
|
||||
set(appearance: style.appearance)
|
||||
configureStatefulButton(appearance: style.appearance)
|
||||
|
||||
if let action = style.action {
|
||||
addTarget(action.target, action: action.action, for: action.event)
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
import UIKit
|
||||
|
||||
public struct CenterConstraints: ConstraintsSet {
|
||||
public let centerXConstraint: NSLayoutConstraint?
|
||||
public let centerYConstraint: NSLayoutConstraint?
|
||||
public var centerXConstraint: NSLayoutConstraint
|
||||
public var centerYConstraint: NSLayoutConstraint
|
||||
|
||||
// MARK: - ConstraintsSet
|
||||
|
||||
|
|
@ -32,19 +32,19 @@ public struct CenterConstraints: ConstraintsSet {
|
|||
[
|
||||
centerXConstraint,
|
||||
centerYConstraint
|
||||
].compactMap { $0 }
|
||||
]
|
||||
}
|
||||
|
||||
public init(centerXConstraint: NSLayoutConstraint? = nil,
|
||||
centerYConstraint: NSLayoutConstraint? = nil) {
|
||||
public init(centerXConstraint: NSLayoutConstraint,
|
||||
centerYConstraint: NSLayoutConstraint) {
|
||||
|
||||
self.centerXConstraint = centerXConstraint
|
||||
self.centerYConstraint = centerYConstraint
|
||||
}
|
||||
|
||||
public func update(offset: UIOffset) {
|
||||
centerXConstraint?.setActiveConstantOrDeactivate(constant: offset.horizontal)
|
||||
centerYConstraint?.setActiveConstantOrDeactivate(constant: offset.vertical)
|
||||
centerXConstraint.setActiveConstantOrDeactivate(constant: offset.horizontal)
|
||||
centerYConstraint.setActiveConstantOrDeactivate(constant: offset.vertical)
|
||||
}
|
||||
|
||||
public var centerConstraints: [NSLayoutConstraint] {
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@
|
|||
import UIKit
|
||||
|
||||
public struct EdgeConstraints: ConstraintsSet {
|
||||
public let leadingConstraint: NSLayoutConstraint?
|
||||
public let trailingConstraint: NSLayoutConstraint?
|
||||
public let topConstraint: NSLayoutConstraint?
|
||||
public let bottomConstraint: NSLayoutConstraint?
|
||||
public var leadingConstraint: NSLayoutConstraint
|
||||
public var trailingConstraint: NSLayoutConstraint
|
||||
public var topConstraint: NSLayoutConstraint
|
||||
public var bottomConstraint: NSLayoutConstraint
|
||||
|
||||
// MARK: - ConstraintsSet
|
||||
|
||||
|
|
@ -36,27 +36,27 @@ public struct EdgeConstraints: ConstraintsSet {
|
|||
trailingConstraint,
|
||||
topConstraint,
|
||||
bottomConstraint
|
||||
].compactMap { $0 }
|
||||
]
|
||||
}
|
||||
|
||||
public var horizontal: [NSLayoutConstraint] {
|
||||
[
|
||||
leadingConstraint,
|
||||
trailingConstraint
|
||||
].compactMap { $0 }
|
||||
]
|
||||
}
|
||||
|
||||
public var vertical: [NSLayoutConstraint] {
|
||||
[
|
||||
topConstraint,
|
||||
bottomConstraint
|
||||
].compactMap { $0 }
|
||||
]
|
||||
}
|
||||
|
||||
public init(leadingConstraint: NSLayoutConstraint? = nil,
|
||||
trailingConstraint: NSLayoutConstraint? = nil,
|
||||
topConstraint: NSLayoutConstraint? = nil,
|
||||
bottomConstraint: NSLayoutConstraint? = nil) {
|
||||
public init(leadingConstraint: NSLayoutConstraint,
|
||||
trailingConstraint: NSLayoutConstraint,
|
||||
topConstraint: NSLayoutConstraint,
|
||||
bottomConstraint: NSLayoutConstraint) {
|
||||
|
||||
self.leadingConstraint = leadingConstraint
|
||||
self.trailingConstraint = trailingConstraint
|
||||
|
|
@ -65,9 +65,9 @@ public struct EdgeConstraints: ConstraintsSet {
|
|||
}
|
||||
|
||||
public func update(from insets: UIEdgeInsets) {
|
||||
leadingConstraint?.setActiveConstantOrDeactivate(constant: insets.left)
|
||||
trailingConstraint?.setActiveConstantOrDeactivate(constant: -insets.right)
|
||||
topConstraint?.setActiveConstantOrDeactivate(constant: insets.top)
|
||||
bottomConstraint?.setActiveConstantOrDeactivate(constant: -insets.bottom)
|
||||
leadingConstraint.setActiveConstantOrDeactivate(constant: insets.left)
|
||||
trailingConstraint.setActiveConstantOrDeactivate(constant: -insets.right)
|
||||
topConstraint.setActiveConstantOrDeactivate(constant: insets.top)
|
||||
bottomConstraint.setActiveConstantOrDeactivate(constant: -insets.bottom)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
import UIKit.NSLayoutConstraint
|
||||
|
||||
extension NSLayoutConstraint {
|
||||
public extension NSLayoutConstraint {
|
||||
func setActiveConstantOrDeactivate(constant: CGFloat) {
|
||||
if constant.isFinite {
|
||||
self.constant = constant
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
import UIKit
|
||||
|
||||
public struct SizeConstraints: ConstraintsSet {
|
||||
public let widthConstraint: NSLayoutConstraint?
|
||||
public let heightConstraint: NSLayoutConstraint?
|
||||
public var widthConstraint: NSLayoutConstraint
|
||||
public var heightConstraint: NSLayoutConstraint
|
||||
|
||||
// MARK: - ConstraintsSet
|
||||
|
||||
|
|
@ -32,18 +32,18 @@ public struct SizeConstraints: ConstraintsSet {
|
|||
[
|
||||
widthConstraint,
|
||||
heightConstraint
|
||||
].compactMap { $0 }
|
||||
]
|
||||
}
|
||||
|
||||
public init(widthConstraint: NSLayoutConstraint? = nil,
|
||||
heightConstraint: NSLayoutConstraint? = nil) {
|
||||
public init(widthConstraint: NSLayoutConstraint,
|
||||
heightConstraint: NSLayoutConstraint) {
|
||||
|
||||
self.widthConstraint = widthConstraint
|
||||
self.heightConstraint = heightConstraint
|
||||
}
|
||||
|
||||
public func update(from size: CGSize) {
|
||||
widthConstraint?.setActiveConstantOrDeactivate(constant: size.width)
|
||||
heightConstraint?.setActiveConstantOrDeactivate(constant: size.height)
|
||||
widthConstraint.setActiveConstantOrDeactivate(constant: size.width)
|
||||
heightConstraint.setActiveConstantOrDeactivate(constant: size.height)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ public struct SubviewConstraints: ConstraintsSet {
|
|||
}
|
||||
|
||||
public init(edgeConstraints: EdgeConstraints,
|
||||
centerConstraints: CenterConstraints,
|
||||
sizeConstraints: SizeConstraints) {
|
||||
centerConstraints: CenterConstraints,
|
||||
sizeConstraints: SizeConstraints) {
|
||||
|
||||
self.edgeConstraints = edgeConstraints
|
||||
self.centerConstraints = centerConstraints
|
||||
|
|
@ -59,9 +59,12 @@ public struct SubviewConstraints: ConstraintsSet {
|
|||
|
||||
// MARK: - WrappedViewLayout shortcut
|
||||
|
||||
func update(from layout: some WrappedViewLayout) {
|
||||
@discardableResult
|
||||
public func update(from layout: some WrappedViewLayout) -> Self {
|
||||
update(insets: layout.insets,
|
||||
size: layout.size,
|
||||
centerOffset: layout.centerOffset)
|
||||
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ open class CollectionTableViewCell<CollectionView: UICollectionView>: ContainerT
|
|||
|
||||
if #available(iOS 16, *) {
|
||||
contentSizeObservation = wrappedView.observe(\.contentSize,
|
||||
options: [.new]) { collectionView, change in
|
||||
options: [.new]) { collectionView, change in
|
||||
|
||||
if let contentSize = change.newValue, !contentSize.equalTo(collectionView.bounds.size) {
|
||||
self.invalidateIntrinsicContentSize()
|
||||
|
|
@ -52,12 +52,12 @@ open class CollectionTableViewCell<CollectionView: UICollectionView>: ContainerT
|
|||
}
|
||||
|
||||
let cachedCollectionFrame = wrappedView.frame
|
||||
wrappedView.frame.size.width = targetSize.width - contentInsets.left - contentInsets.right
|
||||
wrappedView.frame.size.width = targetSize.width - wrappedContentInsets.left - wrappedContentInsets.right
|
||||
let collectionContentHeight = wrappedView.collectionViewLayout.collectionViewContentSize.height
|
||||
wrappedView.frame = cachedCollectionFrame
|
||||
|
||||
return CGSize(width: targetSize.width,
|
||||
height: collectionContentHeight + contentInsets.top + contentInsets.bottom)
|
||||
height: collectionContentHeight + wrappedContentInsets.top + wrappedContentInsets.bottom)
|
||||
}
|
||||
|
||||
// MARK: - Open methods
|
||||
|
|
|
|||
|
|
@ -26,24 +26,24 @@ import TIUIKitCore
|
|||
open class ContainerCollectionViewCell<View: UIView>: UICollectionViewCell, InitializableViewProtocol, WrappedViewHolder {
|
||||
|
||||
public var callbacks: [ViewCallbacks] = []
|
||||
|
||||
|
||||
// MARK: - WrappedViewHolder
|
||||
|
||||
public private(set) lazy var wrappedView = createView()
|
||||
|
||||
public var contentInsets: UIEdgeInsets = .zero {
|
||||
public var wrappedContentInsets: UIEdgeInsets = .zero {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
}
|
||||
|
||||
public var contentSize: CGSize = .infinity {
|
||||
public var wrappedContentSize: CGSize = .infinity {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
}
|
||||
|
||||
public var contentCenterOffset: UIOffset = .nan {
|
||||
public var wrappedContentCenterOffset: UIOffset = .nan {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
|
|
@ -98,6 +98,6 @@ open class ContainerCollectionViewCell<View: UIView>: UICollectionViewCell, Init
|
|||
}
|
||||
|
||||
open func createView() -> View {
|
||||
return View()
|
||||
View()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
//
|
||||
// Copyright (c) 2023 Touch Instinct
|
||||
//
|
||||
// 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 TIUIKitCore
|
||||
import UIKit
|
||||
|
||||
open class ContainerScrollView<ContentView: UIView>: BaseInitializeableScrollView, WrappedViewHolder {
|
||||
|
||||
// MARK: - WrappedViewHolder
|
||||
|
||||
public private(set) lazy var wrappedView = createView()
|
||||
|
||||
public var wrappedContentInsets: UIEdgeInsets = .zero {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
}
|
||||
|
||||
public var wrappedContentSize: CGSize = .infinity {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
}
|
||||
|
||||
public var wrappedContentCenterOffset: UIOffset = .nan {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var subviewContraints: SubviewConstraints = {
|
||||
configureWrappedViewLayout()
|
||||
}()
|
||||
|
||||
open func createView() -> ContentView {
|
||||
ContentView()
|
||||
}
|
||||
|
||||
// MARK: - InitializableViewProtocol
|
||||
|
||||
open override func addViews() {
|
||||
super.addViews()
|
||||
|
||||
addSubview(wrappedView)
|
||||
}
|
||||
}
|
||||
|
||||
extension ContainerScrollView: AppearanceConfigurable where View: AppearanceConfigurable,
|
||||
View.Appearance: WrappedViewAppearance {
|
||||
|
||||
public func configure(appearance: DefaultWrappedViewHolderAppearance<View.Appearance, NoLayout>) {
|
||||
configureWrappedViewHolder(appearance: appearance)
|
||||
}
|
||||
}
|
||||
|
|
@ -24,24 +24,24 @@ import UIKit
|
|||
import TIUIKitCore
|
||||
|
||||
open class ContainerTableViewCell<View: UIView>: BaseInitializableCell, WrappedViewHolder {
|
||||
|
||||
|
||||
// MARK: - WrappedViewHolder
|
||||
|
||||
public private(set) lazy var wrappedView = createView()
|
||||
|
||||
public var contentInsets: UIEdgeInsets = .zero {
|
||||
public var wrappedContentInsets: UIEdgeInsets = .zero {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
}
|
||||
|
||||
public var contentSize: CGSize = .infinity {
|
||||
public var wrappedContentSize: CGSize = .infinity {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
}
|
||||
|
||||
public var contentCenterOffset: UIOffset = .nan {
|
||||
public var wrappedContentCenterOffset: UIOffset = .nan {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
|
|
@ -66,14 +66,7 @@ open class ContainerTableViewCell<View: UIView>: BaseInitializableCell, WrappedV
|
|||
}
|
||||
|
||||
open func createView() -> View {
|
||||
return View()
|
||||
}
|
||||
|
||||
// MARK: - Open methods
|
||||
|
||||
public func configureContainerTableViewCell(appearance: BaseWrappedViewHolderAppearance<some WrappedViewAppearance, some ViewLayout>) {
|
||||
updateContentLayout(from: appearance.subviewAppearance.layout)
|
||||
configureUIView(appearance: appearance)
|
||||
View()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -82,8 +75,7 @@ open class ContainerTableViewCell<View: UIView>: BaseInitializableCell, WrappedV
|
|||
extension ContainerTableViewCell: AppearanceConfigurable where View: AppearanceConfigurable,
|
||||
View.Appearance: WrappedViewAppearance {
|
||||
|
||||
public func configure(appearance: DefaultWrappedViewHolderAppearance<View.Appearance, UIView.NoLayout>) {
|
||||
configureContainerTableViewCell(appearance: appearance)
|
||||
wrappedView.configure(appearance: appearance.subviewAppearance)
|
||||
public func configure(appearance: DefaultWrappedViewHolderAppearance<View.Appearance, NoLayout>) {
|
||||
configureWrappedViewHolder(appearance: appearance)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,19 +27,19 @@ public final class ContainerView<View: UIView>: BaseInitializableView, WrappedVi
|
|||
|
||||
public private(set) lazy var wrappedView = View()
|
||||
|
||||
public var contentInsets: UIEdgeInsets = .zero {
|
||||
public var wrappedContentInsets: UIEdgeInsets = .zero {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
}
|
||||
|
||||
public var contentSize: CGSize = .infinity {
|
||||
public var wrappedContentSize: CGSize = .infinity {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
}
|
||||
|
||||
public var contentCenterOffset: UIOffset = .nan {
|
||||
public var wrappedContentCenterOffset: UIOffset = .nan {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
|
|
@ -80,8 +80,6 @@ extension ContainerView: AppearanceConfigurable where View: AppearanceConfigurab
|
|||
public typealias Appearance = UIView.DefaultWrappedViewHolderAppearance<View.Appearance, UIView.DefaultWrappedLayout>
|
||||
|
||||
public func configure(appearance: Appearance) {
|
||||
wrappedView.configure(appearance: appearance.subviewAppearance)
|
||||
configureUIView(appearance: appearance)
|
||||
updateContentLayout(from: appearance.subviewAppearance.layout)
|
||||
configureWrappedViewHolder(appearance: appearance)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,26 +23,28 @@
|
|||
import UIKit
|
||||
import TIUIKitCore
|
||||
|
||||
open class ReusableCollectionContainerView<View: UIView>: UICollectionReusableView, InitializableViewProtocol, WrappedViewHolder {
|
||||
open class ReusableCollectionContainerView<View: UIView>: UICollectionReusableView,
|
||||
InitializableViewProtocol,
|
||||
WrappedViewHolder {
|
||||
public var callbacks: [ViewCallbacks] = []
|
||||
|
||||
// MARK: - WrappedViewHolder
|
||||
|
||||
|
||||
public private(set) lazy var wrappedView = createView()
|
||||
|
||||
public var contentInsets: UIEdgeInsets = .zero {
|
||||
public var wrappedContentInsets: UIEdgeInsets = .zero {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
}
|
||||
|
||||
public var contentSize: CGSize = .infinity {
|
||||
public var wrappedContentSize: CGSize = .infinity {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
}
|
||||
|
||||
public var contentCenterOffset: UIOffset = .nan {
|
||||
public var wrappedContentCenterOffset: UIOffset = .nan {
|
||||
didSet {
|
||||
update(subviewConstraints: subviewContraints)
|
||||
}
|
||||
|
|
@ -97,6 +99,6 @@ open class ReusableCollectionContainerView<View: UIView>: UICollectionReusableVi
|
|||
}
|
||||
|
||||
open func createView() -> View {
|
||||
return View()
|
||||
View()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,12 +21,22 @@
|
|||
//
|
||||
|
||||
import TIUIKitCore
|
||||
import UIKit
|
||||
import UIKit.UIView
|
||||
|
||||
public extension WrappedViewLayout {
|
||||
func update(constraints: SubviewConstraints) {
|
||||
constraints.update(insets: insets,
|
||||
size: size,
|
||||
centerOffset: centerOffset)
|
||||
public extension WrappedViewHolder {
|
||||
func configureBaseWrappedViewHolder(appearance: some UIView.BaseWrappedViewHolderAppearance<
|
||||
some WrappedViewAppearance,
|
||||
some ViewLayout>) {
|
||||
updateContentLayout(from: appearance.subviewAppearance.layout)
|
||||
contentView.configureUIView(appearance: appearance)
|
||||
}
|
||||
}
|
||||
|
||||
public extension WrappedViewHolder where View: AppearanceConfigurable, View.Appearance: WrappedViewAppearance {
|
||||
func configureWrappedViewHolder(appearance: some UIView.BaseWrappedViewHolderAppearance<
|
||||
View.Appearance,
|
||||
some ViewLayout>) {
|
||||
configureBaseWrappedViewHolder(appearance: appearance)
|
||||
wrappedView.configure(appearance: appearance.subviewAppearance)
|
||||
}
|
||||
}
|
||||
|
|
@ -28,9 +28,10 @@ public protocol WrappedViewHolder: AnyObject {
|
|||
|
||||
var wrappedView: View { get }
|
||||
var contentView: UIView { get }
|
||||
var contentInsets: UIEdgeInsets { get set }
|
||||
var contentSize: CGSize { get set }
|
||||
var contentCenterOffset: UIOffset { get set }
|
||||
|
||||
var wrappedContentInsets: UIEdgeInsets { get set }
|
||||
var wrappedContentSize: CGSize { get set }
|
||||
var wrappedContentCenterOffset: UIOffset { get set }
|
||||
}
|
||||
|
||||
public extension WrappedViewHolder {
|
||||
|
|
@ -65,17 +66,17 @@ public extension WrappedViewHolder {
|
|||
// MARK: - SubviewConstraints shortcut
|
||||
|
||||
func update(subviewConstraints: SubviewConstraints) {
|
||||
subviewConstraints.update(insets: contentInsets,
|
||||
size: contentSize,
|
||||
centerOffset: contentCenterOffset)
|
||||
subviewConstraints.update(insets: wrappedContentInsets,
|
||||
size: wrappedContentSize,
|
||||
centerOffset: wrappedContentCenterOffset)
|
||||
}
|
||||
|
||||
// MARK: - WrappedViewLayout shortcut
|
||||
|
||||
func updateContentLayout(from layout: some WrappedViewLayout) {
|
||||
contentInsets = layout.insets
|
||||
contentSize = layout.size
|
||||
contentCenterOffset = layout.centerOffset
|
||||
wrappedContentInsets = layout.insets
|
||||
wrappedContentSize = layout.size
|
||||
wrappedContentCenterOffset = layout.centerOffset
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,10 +57,10 @@ let customStyle = DefaultPlaceholderStyle(
|
|||
}, buttonsStyles: [
|
||||
.init(titles: [.normal: "Reload"],
|
||||
appearance: .init(stateAppearances: [
|
||||
.normal: UIButton.DefaultAppearance(textAttributes: .init(font: .systemFont(ofSize: 20),
|
||||
color: .black,
|
||||
alignment: .natural,
|
||||
isMultiline: false))
|
||||
.normal: UIButton.DefaultStateAppearance(textAttributes: .init(font: .systemFont(ofSize: 20),
|
||||
color: .black,
|
||||
alignment: .natural,
|
||||
isMultiline: false))
|
||||
]))
|
||||
])
|
||||
|
||||
|
|
|
|||
|
|
@ -31,33 +31,31 @@ public extension UIEdgeInsets {
|
|||
}
|
||||
|
||||
static func horizontal(_ insets: CGFloat) -> UIEdgeInsets {
|
||||
.init(top: .zero, left: insets, bottom: .zero, right: insets)
|
||||
.init(top: .nan, left: insets, bottom: .nan, right: insets)
|
||||
}
|
||||
|
||||
static func vertical(_ insets: CGFloat) -> UIEdgeInsets {
|
||||
.init(top: insets, left: .zero, bottom: insets, right: .zero)
|
||||
.init(top: insets, left: .nan, bottom: insets, right: .nan)
|
||||
}
|
||||
|
||||
static func horizontal(left: CGFloat = .zero, right: CGFloat = .zero) -> UIEdgeInsets {
|
||||
.init(top: .zero, left: left, bottom: .zero, right: right)
|
||||
static func horizontal(left: CGFloat = .nan, right: CGFloat = .nan) -> UIEdgeInsets {
|
||||
.init(top: .nan, left: left, bottom: .nan, right: right)
|
||||
}
|
||||
|
||||
static func vertical(top: CGFloat = .zero, bottom: CGFloat = .zero) -> UIEdgeInsets {
|
||||
.init(top: top, left: .zero, bottom: bottom, right: .zero)
|
||||
}
|
||||
|
||||
// MARK: - Computed Properties
|
||||
|
||||
var vertical: CGFloat {
|
||||
top + bottom
|
||||
}
|
||||
|
||||
var horizontal: CGFloat {
|
||||
left + right
|
||||
static func vertical(top: CGFloat = .nan, bottom: CGFloat = .nan) -> UIEdgeInsets {
|
||||
.init(top: top, left: .nan, bottom: bottom, right: .nan)
|
||||
}
|
||||
|
||||
// MARK: - Instance methods
|
||||
|
||||
func vertical(onNan defaultValue: CGFloat = .nan) -> CGFloat {
|
||||
add(\.top, to: \.bottom, of: self, onNan: defaultValue)
|
||||
}
|
||||
|
||||
func horizontal(onNan defaultValue: CGFloat = .nan) -> CGFloat {
|
||||
add(\.left, to: \.right, of: self, onNan: defaultValue)
|
||||
}
|
||||
|
||||
func horizontal(_ insets: CGFloat) -> UIEdgeInsets {
|
||||
.init(top: top, left: insets, bottom: bottom, right: insets)
|
||||
}
|
||||
|
|
@ -73,4 +71,24 @@ public extension UIEdgeInsets {
|
|||
func vertical(top: CGFloat = .zero, bottom: CGFloat = .zero) -> UIEdgeInsets {
|
||||
.init(top: top, left: left, bottom: bottom, right: right)
|
||||
}
|
||||
|
||||
func add(_ lhsKeyPath: KeyPath<Self, CGFloat>,
|
||||
to rhsKeyPath: KeyPath<Self, CGFloat>,
|
||||
of rhs: Self,
|
||||
onNan defaultValue: CGFloat = .nan) -> CGFloat {
|
||||
|
||||
let lhsValue = self[keyPath: lhsKeyPath]
|
||||
let rhsValue = rhs[keyPath: rhsKeyPath]
|
||||
|
||||
switch (lhsValue.isFinite, rhsValue.isFinite) {
|
||||
case (true, true):
|
||||
return lhsValue + rhsValue
|
||||
case (true, false):
|
||||
return lhsValue
|
||||
case (false, true):
|
||||
return rhsValue
|
||||
case (false, false):
|
||||
return defaultValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,9 @@ class CustomViewController: BaseModalViewController<UIView, UIView> {
|
|||
$0.layout.size = .fixedHeight(52)
|
||||
$0.backgroundColor = .white
|
||||
$0.contentViewState = .buttonLeft(.init(titles: [.normal: "Close"],
|
||||
appearance: [.normal: .init(backgroundColor: .blue)]))
|
||||
appearance: .init(stateAppearances: [
|
||||
.normal: .init(backgroundColor: .blue)
|
||||
])))
|
||||
})
|
||||
|
||||
return appearance
|
||||
|
|
|
|||
|
|
@ -60,10 +60,10 @@ let customStyle = DefaultPlaceholderStyle(
|
|||
}, buttonsStyles: [
|
||||
.init(titles: [.normal: "Reload"],
|
||||
appearance: .init(stateAppearances: [
|
||||
.normal: UIButton.DefaultAppearance(textAttributes: .init(font: .systemFont(ofSize: 20),
|
||||
color: .black,
|
||||
alignment: .natural,
|
||||
isMultiline: false))
|
||||
.normal: UIButton.DefaultStateAppearance(textAttributes: .init(font: .systemFont(ofSize: 20),
|
||||
color: .black,
|
||||
alignment: .natural,
|
||||
isMultiline: false))
|
||||
]))
|
||||
])
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue