191 lines
9.7 KiB
Swift
191 lines
9.7 KiB
Swift
//
|
|
// 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 BaseListItemView<LeadingView: UIView,
|
|
MiddleView: UIView,
|
|
TrailingView: UIView>: BaseInitializableView {
|
|
|
|
public let leadingView = LeadingView()
|
|
public let middleView = MiddleView()
|
|
public let trailingView = TrailingView()
|
|
|
|
// MARK: - Constraints
|
|
|
|
public private(set) lazy var middleViewLeadingConstraint: NSLayoutConstraint = {
|
|
middleView.leadingAnchor.constraint(equalTo: leadingView.trailingAnchor)
|
|
}()
|
|
|
|
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)))
|
|
}()
|
|
|
|
public private(set) lazy var trailingViewLeadingToMiddleViewConstraint: 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)))
|
|
}()
|
|
|
|
public private(set) lazy var middleViewLeadingToSuperViewConstraint: NSLayoutConstraint = {
|
|
middleView.leadingAnchor.constraint(equalTo: leadingAnchor)
|
|
}()
|
|
|
|
public private(set) lazy var middleViewTrailingToSuperViewConstraint: NSLayoutConstraint = {
|
|
middleView.trailingAnchor.constraint(equalTo: trailingAnchor)
|
|
}()
|
|
|
|
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)))
|
|
}()
|
|
|
|
// MARK: - Public Properties
|
|
|
|
open var isLeadingViewHidden: Bool {
|
|
leadingView.isHidden
|
|
}
|
|
|
|
open var isTrailingViewHidden: Bool {
|
|
trailingView.isHidden
|
|
}
|
|
|
|
// MARK: - BaseInitializableView
|
|
|
|
open override func addViews() {
|
|
super.addViews()
|
|
|
|
addSubviews(leadingView, middleView, trailingView)
|
|
}
|
|
|
|
open override func configureLayout() {
|
|
super.configureLayout()
|
|
|
|
[leadingView, middleView, trailingView]
|
|
.forEach { $0.translatesAutoresizingMaskIntoConstraints = false }
|
|
|
|
[leadingViewConstraints, middleViewConstraints, trailingViewConstraints]
|
|
.forEach { $0.update(insets: .zero, size: .infinity, centerOffset: .nan) }
|
|
}
|
|
|
|
// MARK: - Public methods
|
|
|
|
public func configureBaseListItem(appearance: BaseListItemAppearance<some WrappedViewAppearance,
|
|
some WrappedViewAppearance,
|
|
some WrappedViewAppearance>) {
|
|
|
|
configureUIView(appearance: appearance)
|
|
|
|
updateLeadingViewLayout(leadingViewLayout: appearance.leadingViewAppearance.layout,
|
|
middleViewLayout: appearance.middleViewAppearance.layout)
|
|
|
|
updateMiddleViewLayout(middleViewLayout: appearance.middleViewAppearance.layout)
|
|
|
|
updateTrailingViewLayout(trailingViewLayout: appearance.trailingAppearance.layout,
|
|
middleViewLayout: appearance.middleViewAppearance.layout)
|
|
}
|
|
|
|
// MARK: - Private methdos
|
|
|
|
private func updateLeadingViewLayout(leadingViewLayout: WrappedViewLayout,
|
|
middleViewLayout: WrappedViewLayout) {
|
|
|
|
let leadingToSuperviewContraint: NSLayoutConstraint
|
|
let leadingViewLeftInset: CGFloat
|
|
|
|
if isLeadingViewHidden {
|
|
leadingViewConstraints.deactivate()
|
|
middleViewLeadingToSuperViewConstraint.isActive = true
|
|
|
|
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
|
|
middleViewLeadingToSuperViewConstraint.isActive = false
|
|
|
|
leadingViewConstraints.update(from: leadingViewLayout)
|
|
|
|
leadingToSuperviewContraint = leadingViewConstraints.edgeConstraints.leadingConstraint
|
|
leadingViewLeftInset = leadingViewLayout.insets.left
|
|
}
|
|
|
|
leadingToSuperviewContraint.constant = leadingViewLeftInset
|
|
}
|
|
|
|
private func updateMiddleViewLayout(middleViewLayout: WrappedViewLayout) {
|
|
middleViewConstraints.update(from: middleViewLayout)
|
|
}
|
|
|
|
private func updateTrailingViewLayout(trailingViewLayout: WrappedViewLayout,
|
|
middleViewLayout: WrappedViewLayout) {
|
|
|
|
let trailingToSuperviewConstraint: NSLayoutConstraint
|
|
let trailingViewRightInset: CGFloat
|
|
|
|
if isTrailingViewHidden {
|
|
trailingViewConstraints.deactivate()
|
|
middleViewTrailingToSuperViewConstraint.isActive = true
|
|
|
|
trailingToSuperviewConstraint = middleViewTrailingToSuperViewConstraint
|
|
trailingViewRightInset = middleViewLayout.insets.right
|
|
|
|
} else {
|
|
trailingViewLeadingToMiddleViewConstraint.constant = middleViewLayout.insets.right + trailingViewLayout.insets.left
|
|
trailingViewLeadingToMiddleViewConstraint.isActive = true
|
|
middleViewTrailingToSuperViewConstraint.isActive = false
|
|
|
|
trailingViewConstraints.update(from: trailingViewLayout)
|
|
|
|
trailingToSuperviewConstraint = trailingViewConstraints.edgeConstraints.trailingConstraint
|
|
trailingViewRightInset = trailingViewLayout.insets.right
|
|
}
|
|
|
|
trailingToSuperviewConstraint.constant = -trailingViewRightInset
|
|
}
|
|
}
|