release(ios): 0.2.2 构建 10 修消息卡空洞、标签胶囊假宽与表单标题层级

- 消息卡片删除按钮移出正文行,改用 overlay 悬在右侧,44pt 点击区不再把行撑高
- 批量标签胶囊由等宽栅格改为流式布局,新增 AIFlowLayout 并让节点页复用同一实现
- 设置页应用信息补「构建」一行,版本号全程不带括号
- 添加实例与发送消息两张表单表统一行内标题,去掉大标题留下的空白带
- 节点空态文案改为「节点未返回设备信息」,与量表条实际返回的数据不矛盾
- 图标石墨底、面板阴影与插槽统一压暖 3~4 级,全图 0 蓝色像素
This commit is contained in:
chick
2026-09-15 13:03:23 +08:00
parent c3d17b3daf
commit 802ddd1102
16 changed files with 138 additions and 82 deletions
@@ -1170,7 +1170,9 @@ extension FleetView {
.padding(.vertical, 9)
.accessibilityLabel("正在读取运行信息")
} else {
Text("节点未返回运行信息")
// 这一区只放设备与容量读数;信号、延迟这些运行指标在上方的量表里,
// 说「未返回运行信息」会和同一张卡片上的延迟读数自相矛盾。
Text("节点未返回设备信息")
.font(.caption)
.foregroundStyle(AITheme.faint)
.padding(.vertical, 9)
@@ -1479,59 +1481,8 @@ extension FleetView {
}
}
struct FlowLayout: Layout {
let spacing: CGFloat
func sizeThatFits(
proposal: ProposedViewSize,
subviews: Subviews,
cache: inout ()
) -> CGSize {
let maxWidth = proposal.width ?? .infinity
var x: CGFloat = 0
var y: CGFloat = 0
var rowHeight: CGFloat = 0
var rowWidth: CGFloat = 0
for subview in subviews {
let size = subview.sizeThatFits(.unspecified)
if x > 0, x + size.width > maxWidth {
x = 0
y += rowHeight + spacing
rowHeight = 0
rowWidth = 0
}
x += size.width + spacing
rowHeight = max(rowHeight, size.height)
rowWidth = max(rowWidth, x - spacing)
}
return CGSize(width: rowWidth, height: max(0, y + rowHeight - (rowHeight > 0 ? 0 : spacing)))
}
func placeSubviews(
in bounds: CGRect,
proposal: ProposedViewSize,
subviews: Subviews,
cache: inout ()
) {
var x = bounds.minX
var y = bounds.minY
var rowHeight: CGFloat = 0
for subview in subviews {
let size = subview.sizeThatFits(.unspecified)
if x > bounds.minX, x + size.width > bounds.maxX {
x = bounds.minX
y += rowHeight + spacing
rowHeight = 0
}
subview.place(at: CGPoint(x: x, y: y), proposal: .unspecified)
x += size.width + spacing
rowHeight = max(rowHeight, size.height)
}
}
}
/// 流式排布已提到主题层,这里保留原名,卡片标签行不用改调用点。
typealias FlowLayout = AIFlowLayout
struct FleetMetric: View {
let label: String