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

SwiftUI如何修复已读/未读通知的标题与内容间距不一致问题?

问题:已读/未读通知的标题与正文间距不一致

我创建了如下结构体:

private struct Notification: View {
    let notification: NotificationModel
    let onClick: () -> Void
    
    init(
        notification: NotificationModel,
        onClick: @escaping () -> Void
    ) {
        self.notification = notification
        self.onClick = onClick
    }
    
    var body: some View {
        VStack(alignment: .leading) {
            Text(notification.title)
            HStack {
                Text(notification.body)
                if !notification.isRead {
                    Spacer()
                    Circle().frame(width: 6, height: 6)
                }
            }
        }
        .frame(maxWidth: .infinity)
        .onTapGesture(count: 1, perform: onClick)
    }
}

并按如下方式使用:

NavigationView {
    List {
        ForEach(model.notifications) { notification in
            Notification(
                notification: notification,
                onClick: { ... }
            )
            .listRowSeparator(.hidden)
        }
    }
    .listStyle(.plain)
    .navigationTitle("screen_notifications_title")
}

一切看起来都正常,除了已读通知和未读通知的标题与正文之间的间距不同。我认为该问题可能与Circle()有关,但未能修复,请问该如何解决?


解决办法

问题根源是已读通知的HStack仅包含文本,未读通知的HStack多了Spacer和Circle,两种状态下HStack的布局结构不一致,导致VStack内的间距出现差异。可以用以下两种方式修复:

方式一:统一HStack结构

让HStack在两种状态下的元素完全一致,仅通过透明度控制Circle的显示:

HStack {
    Text(notification.body)
    Spacer()
    Circle()
        .frame(width: 6, height: 6)
        .opacity(notification.isRead ? 0 : 1)
}

这样不管通知是否已读,HStack的布局结构完全相同,标题与正文的间距就会统一。

方式二:固定文本对齐基线

给HStack设置基线对齐,确保正文文本的垂直位置始终一致:

HStack(alignment: .firstTextBaseline) {
    Text(notification.body)
    if !notification.isRead {
        Spacer()
        Circle().frame(width: 6, height: 6)
    }
}

这种方式强制正文文本以基线对齐,即使HStack内容不同,也不会影响和上方标题的间距。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 04:22:18