updated date picker
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
891a816f55
commit
32a44a51b5
@ -30,8 +30,10 @@ open class DatePicker: EntryFieldBase {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Properties
|
||||
//--------------------------------------------------
|
||||
internal override var responder: UIResponder? { hiddenView }
|
||||
internal var hiddenView = UITextView().with { $0.width(0) }
|
||||
internal var minWidthDefault = 186.0
|
||||
internal var popoverView: UIView!
|
||||
internal var popoverView: UIScrollView!
|
||||
internal var popoverVisible = false
|
||||
internal var outsideTapGesture: UITapGestureRecognizer?
|
||||
internal var outsidePanGesture: UIPanGestureRecognizer?
|
||||
@ -141,6 +143,7 @@ open class DatePicker: EntryFieldBase {
|
||||
}
|
||||
controlStackView.addArrangedSubview(calendarIcon)
|
||||
controlStackView.addArrangedSubview(selectedDateLabel)
|
||||
controlStackView.addArrangedSubview(hiddenView)
|
||||
return controlStackView
|
||||
}
|
||||
|
||||
@ -168,25 +171,11 @@ open class DatePicker: EntryFieldBase {
|
||||
formatter.dateFormat = dateFormat.format
|
||||
selectedDateLabel.text = formatter.string(from: date)
|
||||
}
|
||||
|
||||
internal var popoverController: ClearPopoverViewController?
|
||||
|
||||
func didSelect(_ date: Date) {
|
||||
selectedDate = date
|
||||
sendActions(for: .valueChanged)
|
||||
UIAccessibility.post(notification: .layoutChanged, argument: self.containerView)
|
||||
popoverController?.dismiss(animated: true){ [weak self] in
|
||||
guard let self else { return }
|
||||
popoverController = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension DatePicker {
|
||||
|
||||
private func showPopover() {
|
||||
guard let viewController = UIApplication.topViewController(), let parentView = viewController.view else { return }
|
||||
|
||||
if popoverVisible {
|
||||
hidePopoverView()
|
||||
} else {
|
||||
@ -226,34 +215,33 @@ extension DatePicker {
|
||||
|
||||
parentView.addSubview(overlayView)
|
||||
|
||||
popoverView = UIView()
|
||||
popoverView.backgroundColor = .white
|
||||
popoverView.layer.cornerRadius = 10
|
||||
popoverView.layer.shadowColor = UIColor.black.cgColor
|
||||
popoverView.layer.shadowOpacity = 0.2
|
||||
popoverView.layer.shadowOffset = CGSize(width: 0, height: 5)
|
||||
popoverView.layer.shadowRadius = 10
|
||||
popoverView = UIScrollView()
|
||||
popoverView.backgroundColor = .green
|
||||
popoverView.clipsToBounds = true
|
||||
popoverView.backgroundColor = .clear
|
||||
popoverView.isHidden = true
|
||||
popoverView.addSubview(calendar)
|
||||
calendar.pinToSuperView()
|
||||
popoverView.translatesAutoresizingMaskIntoConstraints = false
|
||||
parentView.addSubview(popoverView)
|
||||
|
||||
popoverView.width(calendar.frame.width)
|
||||
popoverView.height(calendar.frame.height)
|
||||
|
||||
let spacing: CGFloat = 4
|
||||
let (popoverX, popoverY) = calculatePopoverPosition(relativeTo: containerView, in: parentView, size: calendar.frame.size, with: spacing)
|
||||
popoverView.leadingAnchor.constraint(equalTo: parentView.leadingAnchor, constant: popoverX).isActive = true
|
||||
popoverView.topAnchor.constraint(equalTo: parentView.topAnchor, constant: popoverY).isActive = true
|
||||
let popoverSize: CGSize = .init(width: calendar.frame.width, height: calendar.frame.height)
|
||||
popoverView.contentSize = CGSize(width: popoverSize.width, height: popoverSize.height)
|
||||
|
||||
let (popoverX, popoverY, adjustedHeight) = calculatePopoverPosition(relativeTo: containerView, in: parentView, size: popoverSize, with: spacing)
|
||||
//let adjustedX = adjustedHeight != popoverSize.height ? popoverX - 10 : popoverX
|
||||
let adjustedWidth = adjustedHeight != popoverSize.height ? popoverSize.width + 10 : popoverSize.width
|
||||
popoverView.frame = CGRect(x: popoverX, y: popoverY, width: adjustedWidth, height: adjustedHeight)
|
||||
|
||||
parentView.layoutIfNeeded()
|
||||
popoverView.alpha = 0
|
||||
popoverView.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
|
||||
popoverView.isHidden = false
|
||||
popoverVisible = true
|
||||
|
||||
UIView.animate(withDuration: 0.3,
|
||||
_ = responder?.becomeFirstResponder()
|
||||
updateContainerView()
|
||||
UIView.animate(withDuration: 0.3,
|
||||
delay: 0,
|
||||
usingSpringWithDamping: 0.8,
|
||||
initialSpringVelocity: 0.2,
|
||||
@ -262,6 +250,10 @@ extension DatePicker {
|
||||
guard let self else { return }
|
||||
popoverView.alpha = 1
|
||||
popoverView.transform = CGAffineTransform.identity
|
||||
if popoverSize.height > adjustedHeight {
|
||||
popoverView.flashScrollIndicators()
|
||||
}
|
||||
UIAccessibility.post(notification: .layoutChanged, argument: calendar)
|
||||
parentView.layoutIfNeeded()
|
||||
})
|
||||
}
|
||||
@ -270,10 +262,9 @@ extension DatePicker {
|
||||
private func hidePopoverView() {
|
||||
overlayView.isHidden = true
|
||||
overlayView.removeFromSuperview()
|
||||
|
||||
outsideTapGesture = nil
|
||||
outsidePanGesture = nil
|
||||
UIView.animate(withDuration: 0.2,
|
||||
UIView.animate(withDuration: 0.2,
|
||||
animations: {[weak self] in
|
||||
guard let self else { return }
|
||||
popoverView.alpha = 0
|
||||
@ -283,17 +274,23 @@ extension DatePicker {
|
||||
popoverView.isHidden = true
|
||||
popoverView.removeFromSuperview()
|
||||
popoverVisible = false
|
||||
responder?.resignFirstResponder()
|
||||
setNeedsUpdate()
|
||||
UIAccessibility.post(notification: .layoutChanged, argument: containerView)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private func calculatePopoverPosition(relativeTo sourceView: UIView, in parentView: UIView, size: CGSize, with spacing: CGFloat) -> (CGFloat, CGFloat) {
|
||||
|
||||
private func calculatePopoverPosition(relativeTo sourceView: UIView, in parentView: UIView, size: CGSize, with spacing: CGFloat) -> (CGFloat, CGFloat, CGFloat) {
|
||||
let sourceFrameInParent = sourceView.convert(sourceView.bounds, to: parentView)
|
||||
let parentBounds = parentView.bounds
|
||||
let popoverWidth: CGFloat = size.width
|
||||
let popoverHeight: CGFloat = size.height
|
||||
let safeAreaInsets = parentView.safeAreaInsets
|
||||
let popoverWidth = size.width
|
||||
let popoverHeight = size.height
|
||||
|
||||
var popoverX: CGFloat = 0
|
||||
var popoverY: CGFloat = 0
|
||||
var adjustedHeight = popoverHeight
|
||||
|
||||
// Calculate horizontal position
|
||||
if sourceFrameInParent.width < popoverWidth {
|
||||
@ -311,19 +308,34 @@ extension DatePicker {
|
||||
popoverX = sourceFrameInParent.midX - popoverWidth / 2
|
||||
}
|
||||
|
||||
// Calculate vertical position
|
||||
if sourceFrameInParent.origin.y > parentBounds.height / 2 {
|
||||
// Show above
|
||||
popoverY = sourceFrameInParent.minY - popoverHeight - spacing
|
||||
} else {
|
||||
// Show below
|
||||
popoverY = sourceFrameInParent.maxY + spacing
|
||||
}
|
||||
|
||||
// Ensure the popover is within the parent's bounds
|
||||
// Ensure the popover is within the parent's bounds horizontally
|
||||
popoverX = max(0, min(popoverX, parentBounds.width - popoverWidth))
|
||||
|
||||
return (popoverX, popoverY)
|
||||
// Calculate vertical position and height
|
||||
let availableSpaceAbove = sourceFrameInParent.minY - safeAreaInsets.top - spacing
|
||||
let availableSpaceBelow = parentBounds.height - sourceFrameInParent.maxY - safeAreaInsets.bottom - spacing
|
||||
let totalAvailableHeight = parentBounds.height - safeAreaInsets.top - safeAreaInsets.bottom
|
||||
|
||||
if availableSpaceAbove >= popoverHeight {
|
||||
// Show above without adjusting height
|
||||
popoverY = sourceFrameInParent.minY - popoverHeight - spacing
|
||||
} else if availableSpaceBelow >= popoverHeight {
|
||||
// Show below without adjusting height
|
||||
popoverY = sourceFrameInParent.maxY + spacing
|
||||
|
||||
} else if totalAvailableHeight >= popoverHeight {
|
||||
// check if the total
|
||||
if availableSpaceAbove > availableSpaceBelow {
|
||||
popoverY = safeAreaInsets.top
|
||||
} else {
|
||||
popoverY = parentBounds.height - safeAreaInsets.bottom - popoverHeight
|
||||
}
|
||||
} else {
|
||||
popoverY = safeAreaInsets.top
|
||||
adjustedHeight = totalAvailableHeight
|
||||
}
|
||||
|
||||
return (popoverX, popoverY, adjustedHeight)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user