Watch: demo screenshots, wrapping reply chips, feed toolbar and inset fixes, README
Screenshots of Pair, Feed, Thread (finished, approval, question) and New thread, taken in the Series 12 46mm simulator in demo mode. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
bdfb79b891
commit
9731fd621f
10 files changed
+103
-3
No files matched your search
@@ -110,3 +110,60 @@ enum Format {
|
||||
return words.joined(separator: " ")
|
||||
}
|
||||
}
|
||||
|
||||
/// Lays children out left to right and wraps them onto new lines, like the mock's reply chips.
|
||||
struct FlowLayout: Layout {
|
||||
var spacing: CGFloat = 6
|
||||
|
||||
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
|
||||
let rows = arrange(width: proposal.width ?? .infinity, subviews: subviews)
|
||||
return CGSize(width: proposal.width ?? rows.map(\.width).max() ?? 0, height: rows.last.map { $0.y + $0.height } ?? 0)
|
||||
}
|
||||
|
||||
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
|
||||
for row in arrange(width: bounds.width, subviews: subviews) {
|
||||
var x = bounds.minX
|
||||
for index in row.indices {
|
||||
let size = subviews[index].sizeThatFits(.unspecified)
|
||||
subviews[index].place(at: CGPoint(x: x, y: bounds.minY + row.y), proposal: ProposedViewSize(size))
|
||||
x += size.width + spacing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct Row {
|
||||
var indices: [Int] = []
|
||||
var y: CGFloat = 0
|
||||
var width: CGFloat = 0
|
||||
var height: CGFloat = 0
|
||||
}
|
||||
|
||||
private func arrange(width: CGFloat, subviews: Subviews) -> [Row] {
|
||||
var rows: [Row] = []
|
||||
var row = Row()
|
||||
for index in subviews.indices {
|
||||
let size = subviews[index].sizeThatFits(.unspecified)
|
||||
if !row.indices.isEmpty, row.width + spacing + size.width > width {
|
||||
rows.append(row)
|
||||
row = Row(y: row.y + row.height + spacing)
|
||||
}
|
||||
row.width += (row.indices.isEmpty ? 0 : spacing) + size.width
|
||||
row.height = max(row.height, size.height)
|
||||
row.indices.append(index)
|
||||
}
|
||||
if !row.indices.isEmpty { rows.append(row) }
|
||||
return rows
|
||||
}
|
||||
}
|
||||
|
||||
/// A content-sized chip, for one-tap replies.
|
||||
struct ChipButtonStyle: ButtonStyle {
|
||||
func makeBody(configuration: Configuration) -> some View {
|
||||
configuration.label
|
||||
.font(.system(size: 13, weight: .semibold, design: .rounded))
|
||||
.foregroundStyle(.white)
|
||||
.padding(.vertical, 6)
|
||||
.padding(.horizontal, 10)
|
||||
.background(Theme.card.opacity(configuration.isPressed ? 0.6 : 1), in: Capsule())
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user