You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI watchOS开发:统一文字样式、修改导航标题颜色与显示适配

watchOS SwiftUI 界面开发问题解决方案

问题1:双列网格菜单项文字大小统一

问题原因

当前代码中每个菜单项的Text是独立计算布局和缩放比例的:短文本(如"Set 1")长度足够不会触发缩放,长文本(如"My Settings")会触发minimumScaleFactor自动缩小字号,最终导致四个菜单项文字大小不一致。另外给文本添加的.scaledToFill()属于图像/视图缩放修饰符,对文本布局无效。

实现方案

  • 给所有菜单项文本设置统一固定宽度,宽度值以能容纳业务场景下最长文本"My Settings"为基准调整,watchOS双列网格下推荐设置60pt左右宽度
  • 给所有文本设置相同的基准字号,统一配置单行限制和最小缩放比例,确保最长文本刚好完整显示时,所有文本自动保持相同字号
  • 移除文本上无效的.scaledToFill()修饰符

对应代码片段

Text(item.name)
    .font(.system(size: 12)) // 统一基准字号
    .frame(width: 60) // 固定统一宽度,可根据实际显示效果微调
    .lineLimit(1)
    .minimumScaleFactor(0.8) // 调整数值直到"My Settings"完整显示,所有文本会统一使用最终字号
    .foregroundColor(Color.secondary)

问题2:自定义导航标题颜色+完整显示无省略

问题原因

  1. 原有代码中添加在ScrollView上的.scaledToFill()、.minimumScaleFactor()、.lineLimit()、.accentColor()都不会作用于系统原生导航栏标题控件,属于无效修饰
  2. accentColor仅能修改导航栏交互按钮的颜色,无法控制标题文字颜色;watchOS默认大尺寸导航标题在小屏设备上宽度不足时会自动截断显示省略号

实现方案

  • 放弃系统默认的导航标题样式,通过.toolbar修饰符自定义导航栏标题位置(.principal放置位)的内容
  • 自定义标题使用Text控件实现,可自由配置字体颜色、基准字号、缩放规则,确保"Sample Application"完整显示

对应代码片段

移除原有链式调用中无效的导航标题相关修饰,替换为以下代码:

.navigationTitle("") // 清空系统默认标题
.toolbar {
    ToolbarItem(placement: .principal) {
        Text("Sample Application")
            .font(.system(size: 13, weight: .semibold)) // 自定义标题字号字重
            .foregroundColor(.blue) // 自定义标题颜色,可替换为任意色值
            .lineLimit(1)
            .minimumScaleFactor(0.7) // 调整缩放比例保证文本完整显示无截断
    }
}

完整可运行修正代码

import SwiftUI

struct ContentView: View {
    
    @State var menu: [MenuItem] = [
        MenuItem(id: 0, name: "Set 1", imageName: "settings"),
        MenuItem(id: 1, name: "Set 2", imageName: "settings"),
        MenuItem(id: 2, name: "Settings 1", imageName: "settings"),
        MenuItem(id: 3, name: "My Settings", imageName: "settings"),
    ]
    
    var columns = Array(repeating: GridItem(.flexible(), spacing: 10), count: 2)
    @Namespace var namespace
    @State var selected: [MenuItem] = []
    
    var body: some View {
        NavigationView {
            ScrollView {
                if !self.menu.isEmpty {
                    LazyVGrid(columns: columns, spacing: 10) {
                        ForEach(self.menu) { item in
                            VStack {
                                Button(action: {}) {
                                    VStack{
                                        Image(item.imageName)
                                            .renderingMode(.template)
                                            .resizable()
                                            .scaledToFill()
                                            .frame(width: 20, height: 20)
                                            .padding(10)
                                            .background(Color(red: 34 / 255, green: 34 / 255, blue: 34 / 255))
                                            .foregroundColor(Color(red: 32 / 255, green: 148 / 255, blue: 249 / 255))
                                            .clipShape(Circle())
                                    }
                                }
                                .buttonStyle(PlainButtonStyle())
                                Text(item.name)
                                    .font(.system(size: 12))
                                    .frame(width: 60)
                                    .lineLimit(1)
                                    .minimumScaleFactor(0.8)
                                    .foregroundColor(Color.secondary)
                            }.padding(10)
                        }
                    }.padding()
                }
            }
            .navigationTitle("")
            .toolbar {
                ToolbarItem(placement: .principal) {
                    Text("Sample Application")
                        .font(.system(size: 13, weight: .semibold))
                        .foregroundColor(.blue)
                        .lineLimit(1)
                        .minimumScaleFactor(0.7)
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ContentView()
        }
    }
}

struct MenuItem: Identifiable {
    var id: Int
    var name: String
    var imageName: String
}

内容的提问来源于stack exchange,提问作者tech_human

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 21:45:47