Created
August 11, 2022 21:23
-
-
Save alexdremov/3fc5eebec4932a9550d7efc8a35f1f34 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ColumnsLayout(columnsNumber: 2) { | |
VStack { | |
Text("That's one view") | |
Image(systemName: "tortoise.fill") | |
} | |
.padding() | |
.border(.red) | |
Text("That's the second view ") | |
.padding() | |
.border(.red) | |
Text("That's the third view with long lines that are warped automatically") | |
.fixedSize(horizontal: false, vertical: true) | |
.padding() | |
.border(.red) | |
} | |
.border(.blue) | |
.padding() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
Get array of heights for every row. | |
Just get max height on every row | |
*/ | |
private func getRowHeights(subviews: Subviews, subviewProposal: ProposedViewSize) -> [CGFloat] { | |
var subviewProposalNoHLimit = subviewProposal | |
subviewProposalNoHLimit.height = .infinity | |
var rowHeights = [CGFloat]() | |
var index = 0 | |
while index < subviews.count { | |
var rowMax: CGFloat = 0 | |
for _ in 0..<columnsNumber where index < subviews.count { | |
let size = subviews[index].sizeThatFits(subviewProposalNoHLimit) | |
rowMax = max(rowMax, size.height) | |
index += 1 | |
} | |
rowHeights.append(rowMax) | |
} | |
return rowHeights | |
} | |
/** | |
Calculates proposal for subview — one cell in table | |
*/ | |
func getSubviewProposal(subviewsCount: Int, from globalProposal: ProposedViewSize) -> ProposedViewSize { | |
let rowHeight = max(ceil(Double(subviewsCount / columnsNumber)), 1) | |
return ProposedViewSize( | |
width: (globalProposal.width ?? 0) | |
/ CGFloat(columnsNumber), | |
height: (globalProposal.height ?? 0) / rowHeight | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public func placeSubviews( | |
in bounds: CGRect, | |
proposal: ProposedViewSize, | |
subviews: Subviews, | |
cache: inout () | |
) { | |
var subviewProposal = getSubviewProposal( | |
subviewsCount: subviews.count, | |
from: proposal | |
) | |
let colRealWidth = subviewProposal.width ?? 0 | |
let rowHeights = getRowHeights(subviews: subviews, subviewProposal: subviewProposal) | |
var curPos: CGFloat = bounds.minX | |
var curHeight: CGFloat = bounds.minY | |
var rowIndex = 0 | |
for (index, subview) in subviews.enumerated() { | |
subviewProposal.height = rowHeights[rowIndex] | |
let size = subview.dimensions(in: subviewProposal) | |
subview.place( | |
at: CGPoint(x: curPos, y: curHeight), | |
anchor: .topLeading, | |
proposal: subviewProposal | |
) | |
if index % columnsNumber == columnsNumber - 1 { | |
curPos = bounds.minX | |
curHeight += rowHeights[rowIndex] | |
rowIndex += 1 | |
} else { | |
curPos += colRealWidth | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public func sizeThatFits( | |
proposal: ProposedViewSize, | |
subviews: Subviews, | |
cache: inout () | |
) -> CGSize { | |
let subviewProposal = getSubviewProposal( | |
subviewsCount: subviews.count, | |
from: proposal | |
) | |
let rowHeights = getRowHeights( | |
subviews: subviews, | |
globalProposal: proposal | |
) | |
let resultWidth = proposal.width ?? | |
((subviewProposal.width ?? 0) * CGFloat(columnsNumber)) | |
return CGSize( | |
width: resultWidth, | |
height: rowHeights.reduce(0, +) | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment