Skip to content

Commit

Permalink
Improve SwiftUI sizing (#267)
Browse files Browse the repository at this point in the history
  • Loading branch information
bryankeller authored Sep 17, 2023
1 parent 54cd7f5 commit 2c843d7
Showing 1 changed file with 37 additions and 12 deletions.
49 changes: 37 additions & 12 deletions Sources/Public/CalendarViewRepresentable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -595,11 +595,12 @@ extension CalendarViewRepresentable {
uiView: CalendarView)
{
let children = Mirror(reflecting: proposedSize).children
let proposedSize = CGSize(
width: children.first { $0.label == "width" }?.value as? CGFloat ?? .infinity,
height: children.first { $0.label == "height" }?.value as? CGFloat ?? .infinity)

size = sizeThatFits(proposedSize, uiView: uiView)
let proposedWidth = children.first { $0.label == "width" }?.value as? CGFloat
let proposedHeight = children.first { $0.label == "height" }?.value as? CGFloat
size = sizeThatFits(
proposedWidth: proposedWidth ?? minimumReasonableWidth,
proposedHeight: proposedHeight ?? minimumReasonableHeight,
uiView: uiView)
}

// Post-iOS-16 support
Expand All @@ -612,17 +613,44 @@ extension CalendarViewRepresentable {
-> CGSize?
{
sizeThatFits(
CGSize(width: proposal.width ?? .infinity, height: proposal.height ?? .infinity),
proposedWidth: proposal.width ?? minimumReasonableWidth,
proposedHeight: proposal.height ?? minimumReasonableHeight,
uiView: uiView)
}
#endif

// MARK: Private

private func sizeThatFits(_ proposal: CGSize, uiView: CalendarView) -> CGSize {
private var minimumReasonableWidth: CGFloat {
// Minimum day width of 44, 7 days in a week, 6 margins, leading and trailing layout margins
let widthOfDays: CGFloat = 44 * 7
let interDayMargins = (horizontalDayMargin ?? 0) * 6
let layoutMargins = (layoutMargins?.leading ?? 0) + (layoutMargins?.trailing ?? 0)
return widthOfDays + interDayMargins + layoutMargins
}

private var minimumReasonableHeight: CGFloat {
switch monthsLayout {
case .vertical:
return minimumReasonableWidth

case .horizontal(let options):
return options.monthWidth(calendarWidth: minimumReasonableWidth, interMonthSpacing: 0)
}
}

private func sizeThatFits(
proposedWidth: CGFloat,
proposedHeight: CGFloat,
uiView: CalendarView)
-> CGSize
{
let width = min(proposedWidth, .maxLayoutValue)
let height = min(proposedHeight, .maxLayoutValue)

switch monthsLayout {
case .vertical:
return proposal
return CGSize(width: width, height: height)

case .horizontal:
let _insetsLayoutMarginsFromSafeArea = uiView.insetsLayoutMarginsFromSafeArea
Expand All @@ -631,17 +659,14 @@ extension CalendarViewRepresentable {
// margins. For some reason, this is only an issue in SwiftUI, not UIKit.
uiView.insetsLayoutMarginsFromSafeArea = false

let width = min(proposal.width, .maxLayoutValue)
let height = min(proposal.height, .maxLayoutValue)

let size = uiView.systemLayoutSizeFitting(
CGSize(width: width, height: height),
withHorizontalFittingPriority: .required,
verticalFittingPriority: .fittingSizeLevel)

uiView.insetsLayoutMarginsFromSafeArea = _insetsLayoutMarginsFromSafeArea

return CGSize(width: proposal.width, height: size.height)
return CGSize(width: proposedWidth, height: size.height)
}

}
Expand Down

0 comments on commit 2c843d7

Please sign in to comment.