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
+14 -10
View File
@@ -6,9 +6,12 @@
// light source from the upper left, no metal texture, so it still reads at the
// 29pt settings size. The plate keeps the classic single SIM cut, top-left.
//
// The field is deliberately neutral (R = G = B): the moment it drifts cool the
// whole icon reads as "blue icon" on a lit home screen. The gold is pushed warm
// and deep enough that it stays metal rather than mustard.
// The field is warm-neutral, not mathematically neutral. A perfectly grey R=G=B
// plate sitting next to saturated gold loses the comparison and reads cool on a
// lit home screen — that is how "there is no blue in it" still looked "blue" to
// the eye. Red runs 2..4 levels over blue instead, which is invisible as a cast
// but impossible to misread. The gold stays warm and deep so it reads metal
// rather than mustard.
//
// Every coordinate is in visual space (origin top-left, y grows down).
import AppKit
@@ -133,10 +136,10 @@ func directionalRim(_ path: CGPath, _ rect: CGRect, _ width: CGFloat, _ stops: [
fillLinear(
rectPath(CGRect(x: 0, y: 0, width: side, height: side)),
[
// 石墨底严格等色。原先 B 比 R 高 1 级,缩到 60pt 后边缘像素仍会落在蓝色波段。
(0.00, (32, 32, 32, 255)),
(0.55, (19, 19, 19, 255)),
(1.00, (10, 10, 10, 255)),
// 石墨底走暖一档:R 比 B 高 4 级,肉眼看不出偏色,但再也不可能被读成冷调。
(0.00, (34, 32, 30, 255)),
(0.55, (20, 19, 18, 255)),
(1.00, (11, 10, 10, 255)),
] as [Stop],
CGPoint(x: side * 0.06, y: 0),
CGPoint(x: side * 0.94, y: side)
@@ -161,7 +164,7 @@ let plateRect = CGRect(
let plate = simPath(plateRect, corner: plateCorner, chamfer: plateChamfer)
ctx.saveGState()
ctx.setShadow(offset: CGSize(width: 0, height: -22), blur: 46, color: rgb(0, 3, 2, 150))
ctx.setShadow(offset: CGSize(width: 0, height: -22), blur: 46, color: rgb(2, 1, 0, 150))
ctx.addPath(plate)
ctx.setFillColor(rgb(0, 0, 0))
ctx.fillPath()
@@ -211,8 +214,9 @@ for (index, height) in slotHeights.enumerated() {
fillLinear(
path,
[
(0.00, (16, 16, 16, 255)),
(1.00, (32, 32, 32, 255)),
// 插槽与底同色温,避免金面板上的洞看起来发青。
(0.00, (17, 16, 14, 255)),
(1.00, (34, 32, 30, 255)),
] as [Stop],
CGPoint(x: rect.minX, y: rect.minY),
CGPoint(x: rect.minX, y: rect.maxY)