// // 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 BaseTitleSubtitleView: BaseInitializableView { public let titleView = TitleView() public let subtitleView = SubtitleView() public internal(set) lazy var titleBottomToSuperviewConstraint: NSLayoutConstraint = { titleView.bottomAnchor.constraint(equalTo: bottomAnchor) }() public internal(set) lazy var titleBottomToSubtitleConstraint: NSLayoutConstraint = { titleView.bottomAnchor.constraint(equalTo: subtitleView.topAnchor) }() public internal(set) lazy var titleConstraints: SubviewConstraints = { let leadingConstraint = titleView.leadingAnchor.constraint(equalTo: leadingAnchor) let trailingConstraint = titleView.trailingAnchor.constraint(equalTo: trailingAnchor) let topConstraint = titleView.topAnchor.constraint(equalTo: topAnchor) let edgeConstraints = EdgeConstraints(leadingConstraint: leadingConstraint, trailingConstraint: trailingConstraint, topConstraint: topConstraint, bottomConstraint: titleBottomToSubtitleConstraint) let centerXConstraint = titleView.centerXAnchor.constraint(equalTo: centerXAnchor) let centerYConstraint = titleView.centerYAnchor.constraint(equalTo: centerYAnchor) let centerConstraints = CenterConstraints(centerXConstraint: centerXConstraint, centerYConstraint: centerYConstraint) let sizeConstraints = SizeConstraints(widthConstraint: titleView.widthAnchor.constraint(equalToConstant: .zero), heightConstraint: titleView.heightAnchor.constraint(equalToConstant: .zero)) return SubviewConstraints(edgeConstraints: edgeConstraints, centerConstraints: centerConstraints, sizeConstraints: sizeConstraints) }() public internal(set) lazy var subtitleConstraints: SubviewConstraints = { let leadingConstraint = subtitleView.leadingAnchor.constraint(equalTo: leadingAnchor) let trailingConstraint = subtitleView.trailingAnchor.constraint(equalTo: trailingAnchor) let bottomConstraint = subtitleView.bottomAnchor.constraint(equalTo: bottomAnchor) let edgeConstraints = EdgeConstraints(leadingConstraint: leadingConstraint, trailingConstraint: trailingConstraint, topConstraint: titleBottomToSubtitleConstraint, bottomConstraint: bottomConstraint) let centerXConstraint = subtitleView.centerXAnchor.constraint(equalTo: centerXAnchor) let centerYConstraint = subtitleView.centerYAnchor.constraint(equalTo: centerYAnchor) let centerConstraints = CenterConstraints(centerXConstraint: centerXConstraint, centerYConstraint: centerYConstraint) let sizeConstraints = SizeConstraints(widthConstraint: subtitleView.widthAnchor.constraint(equalToConstant: .zero), heightConstraint: subtitleView.heightAnchor.constraint(equalToConstant: .zero)) return SubviewConstraints(edgeConstraints: edgeConstraints, centerConstraints: centerConstraints, sizeConstraints: sizeConstraints) }() // MARK: - InitializableViewProtocol open override func addViews() { super.addViews() addSubviews(titleView, subtitleView) } open override func configureLayout() { super.configureLayout() [titleView, subtitleView] .forEach { $0.translatesAutoresizingMaskIntoConstraints = false } } // MARK: - Public methods open func setSubtitle(hidden: Bool) { guard subtitleView.isHidden != hidden else { return } subtitleView.isHidden = hidden } // MARK: - AppearanceConfigurable open func configureBaseTitleSubtitle(appearance: Appearance) { configureUIView(appearance: appearance) configure(layout: appearance.layout, titleLayout: appearance.titleAppearance.layout, subtitleLayout: appearance.subtitleAppearance.layout, subtitleHidden: subtitleView.isHidden) } public func configure(layout: some SpacedWrappedViewLayout, titleLayout: some WrappedViewLayout, subtitleLayout: some WrappedViewLayout, subtitleHidden: Bool) { titleConstraints.edgeConstraints.bottomConstraint.isActive = false titleConstraints.edgeConstraints.bottomConstraint = subtitleHidden ? titleBottomToSuperviewConstraint : titleBottomToSubtitleConstraint titleConstraints.update(from: titleLayout) let spacing: CGFloat let titleBottomInset = titleLayout.insets.bottom if subtitleHidden { spacing = titleBottomInset.isFinite ? layout.spacing + titleBottomInset : layout.spacing subtitleConstraints.deactivate() } else { let verticalInsets = titleLayout.insets.add(\.bottom, to: \.top, of: subtitleLayout.insets) spacing = verticalInsets.isFinite ? layout.spacing + verticalInsets : layout.spacing subtitleConstraints.update(from: subtitleLayout) } titleBottomToSubtitleConstraint.constant = -spacing } }