Digital ACT-191 ONEAPP-10928 story: updated modal with alignments and spacing
This commit is contained in:
parent
3c1caa7f5a
commit
56155abbb0
@ -74,16 +74,17 @@ open class ModalDialog: View, UIScrollViewDelegate, ParentViewProtocol {
|
||||
$0.customIconSize = UIDevice.isIPad ? 32 : 32
|
||||
}
|
||||
open lazy var closeButton = Button().with{ $0.use = .secondary; $0.text = "Close"}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Configuration
|
||||
//--------------------------------------------------
|
||||
private var closeButtonHeight: CGFloat = 44.0
|
||||
private var fullWidth: CGFloat = 296
|
||||
private var minHeight: CGFloat = 96.0
|
||||
private var maxHeight: CGFloat = 312.0
|
||||
|
||||
private let containerViewInset = VDSLayout.space4X //UIDevice.isIPad ? VDSLayout.space12X : VDSLayout.space4X
|
||||
private var fullWidth: CGFloat = 0.0
|
||||
private var minHeight: CGFloat = 232.0
|
||||
private var maxHeight: CGFloat = 0.0
|
||||
private var minWidth: CGFloat = 560.0
|
||||
private var maxWidth: CGFloat = 0.0
|
||||
|
||||
private let containerViewInset = UIDevice.isIPad ? VDSLayout.space12X : VDSLayout.space4X
|
||||
private let contentLabelTopSpace = UIDevice.isIPad ? VDSLayout.space8X : VDSLayout.space6X
|
||||
private let contentLabelBottomSpace = UIDevice.isIPad ? VDSLayout.space8X : VDSLayout.space12X
|
||||
private let gapBetweenButtonItems = VDSLayout.space3X
|
||||
@ -99,46 +100,67 @@ open class ModalDialog: View, UIScrollViewDelegate, ParentViewProtocol {
|
||||
//--------------------------------------------------
|
||||
/// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations.
|
||||
open override func setup() {
|
||||
super.setup()
|
||||
super.setup()
|
||||
|
||||
fullWidth = UIScreen.main.bounds.size.width
|
||||
|
||||
// Max Width: 70% of viewport width.
|
||||
// Maximum width is only applied to a provided width and not to the default.
|
||||
maxWidth = fullWidth * (70/100)
|
||||
|
||||
// Max Height: Total window height 70% of viewport height.
|
||||
// For Tablet: By default the model's height is dynamic and is based on the amount of content
|
||||
// it contains. it can expand between a minimum and maximum height. The minimum height is determined by the minimum
|
||||
// height of the content area plus the top and bottom padding.
|
||||
maxHeight = UIScreen.main.bounds.size.height * (70/100)
|
||||
|
||||
titleLabel.accessibilityTraits = .header
|
||||
|
||||
layer.cornerRadius = 12
|
||||
contentStackView.addArrangedSubview(titleLabel)
|
||||
contentStackView.addArrangedSubview(contentLabel)
|
||||
contentStackView.setCustomSpacing(contentLabelTopSpace, after: titleLabel)
|
||||
|
||||
scrollView.addSubview(contentStackView)
|
||||
addSubview(closeCrossButton)
|
||||
addSubview(scrollView)
|
||||
addSubview(closeButton)
|
||||
self.bringSubviewToFront(closeCrossButton)
|
||||
let trailingSpace = UIDevice.isIPad ? containerViewInset/2 : containerViewInset
|
||||
|
||||
// Activate constraints
|
||||
NSLayoutConstraint.activate([
|
||||
widthAnchor.constraint(equalToConstant: fullWidth),
|
||||
widthAnchor.constraint(equalToConstant: maxWidth),
|
||||
|
||||
// Constraints for the scroll view
|
||||
scrollView.topAnchor.constraint(equalTo: topAnchor, constant: VDSLayout.space4X),
|
||||
scrollView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
scrollView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
// scrollView.bottomAnchor.constraint(equalTo: line.topAnchor),
|
||||
// Constraints for the closeCrossButton
|
||||
closeCrossButton.topAnchor.constraint(equalTo: topAnchor),
|
||||
closeCrossButton.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor),
|
||||
closeCrossButton.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
closeCrossButton.heightAnchor.constraint(equalToConstant: 48.0),
|
||||
closeCrossButton.widthAnchor.constraint(equalToConstant: 48.0),
|
||||
|
||||
// line.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
// line.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
|
||||
closeButton.topAnchor.constraint(equalTo: scrollView.bottomAnchor),
|
||||
closeButton.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
closeButton.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
closeButton.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
closeButton.heightAnchor.constraint(equalToConstant: closeButtonHeight),
|
||||
// Constraints for the bottom button view
|
||||
closeButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant:containerViewInset),
|
||||
closeButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -containerViewInset),
|
||||
closeButton.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -containerViewInset),
|
||||
|
||||
// Constraints for the scrollView
|
||||
scrollView.topAnchor.constraint(equalTo: topAnchor, constant: containerViewInset),
|
||||
scrollView.leadingAnchor.constraint(equalTo: leadingAnchor, constant:containerViewInset),
|
||||
scrollView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -(trailingSpace)),
|
||||
scrollView.bottomAnchor.constraint(equalTo: closeButton.topAnchor, constant: -contentLabelBottomSpace),
|
||||
|
||||
// Constraints for the contentStackView
|
||||
contentStackView.topAnchor.constraint(equalTo: scrollView.topAnchor),
|
||||
contentStackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: containerViewInset),
|
||||
contentStackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -containerViewInset),
|
||||
contentStackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: -(containerViewInset * 2)),
|
||||
|
||||
contentStackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
|
||||
contentStackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
|
||||
contentStackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: -trailingSpace),
|
||||
contentStackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor)
|
||||
])
|
||||
|
||||
contentStackViewBottomConstraint = contentStackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor)
|
||||
contentStackViewBottomConstraint?.activate()
|
||||
|
||||
heightConstraint = heightAnchor.constraint(equalToConstant: minHeight)
|
||||
heightConstraint = heightAnchor.constraint(equalToConstant: maxHeight)
|
||||
heightConstraint?.activate()
|
||||
}
|
||||
|
||||
@ -181,7 +203,7 @@ open class ModalDialog: View, UIScrollViewDelegate, ParentViewProtocol {
|
||||
}
|
||||
|
||||
if addedTitle && addedContent {
|
||||
contentStackView.setCustomSpacing(VDSLayout.space1X, after: titleLabel)
|
||||
contentStackView.setCustomSpacing(contentLabelTopSpace, after: titleLabel)
|
||||
}
|
||||
|
||||
let closeButtonTextColor = closeButtonTextColorConfiguration.getColor(self)
|
||||
@ -195,27 +217,6 @@ open class ModalDialog: View, UIScrollViewDelegate, ParentViewProtocol {
|
||||
|
||||
scrollView.setNeedsLayout()
|
||||
scrollView.layoutIfNeeded()
|
||||
|
||||
//dealing with height
|
||||
//we can't really use the minMax height and set constraints for
|
||||
//greaterThan or lessThan on the heightAnchor due to scrollView/stackView intrinsic size
|
||||
//therefore we can do a little math and manually set the height based off all of the content
|
||||
var contentHeight = closeButtonHeight + scrollView.contentSize.height + (containerViewInset * 2)
|
||||
|
||||
//reset the bottomConstraint
|
||||
contentStackViewBottomConstraint?.constant = 0
|
||||
|
||||
if contentHeight < minHeight {
|
||||
contentHeight = minHeight
|
||||
|
||||
} else if contentHeight > maxHeight {
|
||||
contentHeight = maxHeight
|
||||
//since we are now scrolling, add padding to the bottom of the
|
||||
//stackView between the bottom of the scrollView
|
||||
contentStackViewBottomConstraint?.constant = -containerViewInset
|
||||
}
|
||||
|
||||
heightConstraint?.constant = contentHeight
|
||||
}
|
||||
|
||||
/// Used to update any Accessibility properties.
|
||||
|
||||
@ -27,15 +27,7 @@ open class ModalDialogViewController: UIViewController, Surfaceable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var onClickCloseSubscriber: AnyCancellable? {
|
||||
willSet {
|
||||
if let onClickCloseSubscriber {
|
||||
onClickCloseSubscriber.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private let modalDialog = ModalDialog()
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -56,7 +48,7 @@ open class ModalDialogViewController: UIViewController, Surfaceable {
|
||||
//--------------------------------------------------
|
||||
open override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
isModalInPresentation = UIDevice.isIPad ? true : false
|
||||
isModalInPresentation = true
|
||||
setup()
|
||||
}
|
||||
open override func viewDidAppear(_ animated: Bool) {
|
||||
@ -95,11 +87,7 @@ open class ModalDialogViewController: UIViewController, Surfaceable {
|
||||
self.dismiss()
|
||||
}
|
||||
|
||||
onClickCloseSubscriber = modalDialog.closeCrossButton.publisher(for: .touchUpInside)
|
||||
.sink {[weak self] button in
|
||||
guard let self else { return }
|
||||
self.dismiss()
|
||||
}
|
||||
modalDialog.closeCrossButton.onClick = { _ in self.dismiss() }
|
||||
|
||||
view.addSubview(modalDialog)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user