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

如何判断ViewThatFits中最后一个适配视图并移除其Divider

解决ViewThatFits中最后一个可见条目移除Divider的问题

你当前的场景是用ForEach结合ViewThatFits实现适配可用空间的条目展示,每个条目下方带Divider,需要让最后一个实际显示的条目不显示下方分割线(比如示例中的“Four”)。核心思路是通过PreferenceKey收集所有可见的条目,再判断每个条目是否为最后一个可见项,从而控制Divider的显示。

修改后的完整代码

import SwiftUI

// 定义PreferenceKey用于收集可见条目
struct VisibleItemPreferenceKey: PreferenceKey {
    static var defaultValue: [String] = []
    
    static func reduce(value: inout [String], nextValue: () -> [String]) {
        value.append(contentsOf: nextValue())
    }
}

struct ContentView: View {
    let items = ["One", "Two", "Three", "Four", "Five", "Six", "Seven"]
    @State private var visibleItems: [String] = []
    
    var body: some View {
        VStack(spacing: 0) {
            Spacer()
            
            ForEach(items, id: \.self) { item in
                RowView(title: item, isLastVisible: visibleItems.last == item)
                    .layoutPriority(Double(items.count - items.firstIndex(of: item)!))
            }
        }
        .frame(width: 200, height: 150)
        .background(.fill)
        .onPreferenceChange(VisibleItemPreferenceKey.self) { newValue in
            visibleItems = newValue
        }
    }
}

struct RowView: View {
    let title: String
    let isLastVisible: Bool
    
    var body: some View {
        ViewThatFits {
            // 显示内容时,将当前条目标记为可见
            VStack(spacing: 0) {
                Text(title)
                    .padding(.vertical, 5)
                
                // 不是最后一个可见条目才显示Divider
                if !isLastVisible {
                    Divider()
                }
            }
            .preference(key: VisibleItemPreferenceKey.self, value: [title])
            
            // 空间不足时显示空视图,不标记为可见
            Color.clear
                .frame(height: 0)
        }
    }
}

实现逻辑说明

  1. VisibleItemPreferenceKey:用于在视图树中传递所有实际显示内容的条目title,父视图通过onPreferenceChange收集这些数据。
  2. RowView修改:当ViewThatFits选择显示文本内容时,通过.preference将当前title注入到偏好中;如果显示空视图,则不注入。同时根据isLastVisible参数决定是否显示Divider。
  3. ContentView修改:用@State变量存储可见条目列表,在ForEach中给每个RowView传递visibleItems.last == item的判断结果,实现最后一个可见条目隐藏Divider。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 12:15:15