微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

基于单元格大小的可变矩形尺寸绘制时间线

如何解决基于单元格大小的可变矩形尺寸绘制时间线

我正在尝试构建一个我希望看起来像时间线的列表。 每个单元格将代表一个里程碑。 在表格的左侧,我希望通过一条线(时间线)“连接”单元格。 我尝试了各种方法来让它按我想要的方式显示,但我已经解决了基本的几何形状,即 Circle() 和 Rectangle()。

这是突出问题的示例代码

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        let roles: [String] = ["CEO","CFO","Managing Director and Chairman of the supervisory board","Systems Analyst","Supply Chain Expert"]
        NavigationView{
            vstack{
                List {
                    ForEach(0..<5) { toto in
                        NavigationLink(
                            destination: dummyView()
                        ) {
                            HStack(alignment: .top,spacing: 0) {
                                vstack(alignment: .center,spacing: 0){
                                    Rectangle()
                                        .frame(width: 1,height: 30,alignment: .center)
                                    Circle()
                                        .frame(width: 10,height: 10)
                                    Rectangle()
                                        .frame(width: 1,height: 20,alignment: .center)
                                    Circle()
                                        .frame(width: 30,height: 30)
                                        .overlay(
                                            Image(systemName: "gear")
                                                .foregroundColor(.gray)
                                                .font(.system(size: 30,weight: .light,design: .rounded))
                                                .frame(width: 30,height: 30)
                                        )
  //THIS IS THE RECTANGLE OBJECT FOR WHICH I WANT THE HEIGHT TO BE VARIABLE
                                    Rectangle()
                                        .frame(width: 1,height: 40,alignment: .center)
                                        .foregroundColor(.green)
                                }
                                .frame(width: 32,height: 80,alignment: .center)
                                .foregroundColor(.green)
                                
                                
                                vstack(alignment: .leading,spacing: 0,content: {
                                    Text("Dummy operation text that will be in the top of the cell")
                                        .font(.subheadline)
                                        .multilineTextAlignment(.leading)
                                        .lineLimit(1)
                                    Label {
                                        Text("march 6,2021")
                                            .font(.caption2)
                                    } icon: {
                                        Image(systemName: "calendar.badge.clock")
                                    }
                                    
                                    HStack{
                                        
                                        HStack{
                                            Image(systemName: "flag.fill")
                                            Text("In Progress")
                                                .font(.system(size: 12))
                                        }
                                        .padding(.horizontal,4)
                                        .padding(.vertical,3)
                                        .foregroundColor(.blue)
                                        .background(Color.white)
                                        .cornerRadius(5,antialiased: true)
                                        
                                        HStack{
                                            Image(systemName: "person.fill")
                                            Text(roles[toto])
                                                .font(.system(size: 12))
                                            
                                        }
                                        .padding(.horizontal,3)
                                        .foregroundColor(.green)
                                        .background(Color.white)
                                        .cornerRadius(5,antialiased: true)
                                        
                                        
                                        HStack{
                                            Image(systemName: "deskclock")
                                            Text("in 2 Months")
                                                .font(.system(size: 12))
                                        }
                                        .padding(.horizontal,3)
                                        .foregroundColor(.red
                                            
                                        )
                                        .background(
                                            Color.white
                                        )
                                        .cornerRadius(5,antialiased: true)
                                    }
                                    
                                })
                            }.listRowInsets(.init(top: 0,leading: 0,bottom: 0,trailing: 0))
                        }
                    }
                }
            }
        }    
    }
}



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

struct dummyView: View {
    var body: some View {
        Text("Hello,World!")
    }
}

struct dummyView_Previews: PreviewProvider {
    static var previews: some View {
        dummyView()
    }
}

但是正如您在随附的图片中看到的那样,存在不需要的间隙

enter image description here

因此单元格中的其他内容使整个单元格的高度“不可预测”并断线。

有没有办法确定单元格的高度并扩展矩形的尺寸,使其延伸到单元格的整个高度?

您有没有更好的方法来尝试构建这样的时间表?

PS:我尝试过使用 .frame 和 .infinity,但这确实有效。 非常感谢。

解决方法

为什么不根据行的大小来画线。见Creating custom paths with SwiftUI。请记住,一切都是视图。

首先,你需要将你正在做的事情分解成子视图。一个视图中的移动部件太多,无法正确显示。另外,我会避免设置特定的填充量,因为这会在您更换设备时搞砸。您需要一个简单、智能的视图,该视图足够通用以处理不同的设备。

我会有一个带有几何读取器的行视图,因此它知道自己的高度。然后,您可以绘制线条,使其跨越行的整个高度,而不管高度如何。类似的东西:

struct ListRow: View {
    var body: some View {
        GeometryReader { geometry in
            ZStack {
                HStack {
                    Spacer()
                    Text("Hello,World!")
                    Spacer()
                }
                VerticalLine(geometry: geometry)
            }
        }
    }
}

struct VerticalLine: View {
    
    let geometry: GeometryProxy
    
    var body: some View {
        Path { path in
            path.move(to: CGPoint(x: 20,y: -30))
            path.addLine(to: CGPoint(x: 20,y: geometry.size.height+30))
        }
        .stroke(Color.green,lineWidth: 4)
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。