SwiftUI:在列表中的两个视图之间画一条线/如何确定视图的中心位置?

Posted

技术标签:

【中文标题】SwiftUI:在列表中的两个视图之间画一条线/如何确定视图的中心位置?【英文标题】:SwiftUI: Drawing a line between two views in a list / how to determine the center location of a view? 【发布时间】:2021-12-01 04:36:32 【问题描述】:

当我按下“连接”按钮时,我想在选定的源视图和选定的目标视图之间画一条线。 据我了解,我需要这些视图的(中心?)CGPoint ...... 如何确定 forEach-HStack-list 中视图的中心 CGPoint?

两个列表中的元素都将被删除/添加。

struct ContentView: View 
    @State private var selectedTarget: Int = 0
    @State private var selectedSource: Int = 3
    @State private var isConnected = false
    
    
    var body: some View 
       
        ZStack 
            VStack 
                HStack 
                    ForEach(0..<6)  index in
                        Text("Target \(index)")
                            .padding()
                            .foregroundColor(.white)
                            .background(selectedTarget == index ? .red : .black)
                            .onTapGesture 
                                selectedTarget = index
                            
                    
                
                
                List 
                    EmptyView()
                
                .frame(width: 400, height: 400, alignment: .center)
                .border(.black, width: 2)
        
                HStack 
                    ForEach(0..<6)  index in
                        Text("Source \(index)")
                            .padding()
                            .foregroundColor(.white)
                            .background(selectedSource == index ? .orange : .black)
                            .onTapGesture 
                                selectedSource = index
                            
                    
                
                Button(isConnected ? "CUT" : "CONNECT") 
                    isConnected.toggle()
                
                .padding()
            
        
        
    
    

【问题讨论】:

【参考方案1】:

这里是粗略的演示代码,并从这段代码中获得灵感。 您可以通过首先通过GeometryReader 找到Text 的位置并在这些点之间绘制路径来实现这一点。

struct ContentView: View 
    @State private var selectedTarget: Int = 0
    @State private var selectedSource: Int = 3
    @State private var isConnected = false
    
    @State private var targetCGPoint: CGPoint = .zero
    @State private var sourceCGPoint: CGPoint = .zero
    
    var body: some View 
        
        ZStack 
            if isConnected 
                getPath()
            
            VStack 
                HStack 
                    ForEach(0..<6)  index in
                        GeometryReader  geo in
                        Text("Target \(index)")
                            .padding()
                            .foregroundColor(.white)
                            .background(selectedTarget == index ? Color.red : Color.black)
                            .onTapGesture 
                                let size = geo.size
                                targetCGPoint = CGPoint(x: geo.frame(in: .global).origin.x + (size.width / 2), y: geo.frame(in: .global).origin.y)
                                print("Target Global center: \(geo.frame(in: .global).midX) x \(geo.frame(in: .global).midY)")
                                selectedTarget = index
                            
                        
                    
                
                
                // Removed list for demo
                Spacer()
                
                HStack 
                    ForEach(0..<6)  index in
                        GeometryReader  geo in
                            Text("Source \(index)")
                                .padding()
                                .foregroundColor(.white)
                                .background(selectedSource == index ? Color.orange : Color.black)
                                .onTapGesture 
                                    let size = geo.size
                                    sourceCGPoint = CGPoint(x: geo.frame(in: .global).origin.x + (size.width / 2), y: geo.frame(in: .global).origin.y)
                                    print("Source Global center: \(geo.frame(in: .global).midX) x \(geo.frame(in: .global).midY)")
                                    selectedSource = index
                                
                        
                        
                    
                
                Button(isConnected ? "CUT" : "CONNECT") 
                    isConnected.toggle()
                
                .padding()
            
        
        
    
    
    func getPath() -> some View 
        Path  path in
            path.move(to: sourceCGPoint)
            path.addLine(to: targetCGPoint)
        
        .stroke(Color.blue, lineWidth: 10)
    

【讨论】:

这就是我要找的。感谢您的帮助!

以上是关于SwiftUI:在列表中的两个视图之间画一条线/如何确定视图的中心位置?的主要内容,如果未能解决你的问题,请参考以下文章

在不同组中的两个点之间画一条线,同时对点进行捕捉

Flutter:Google Map Plugin如何在地图内的两个坐标之间画一条线

如何用 matplotlib 画一条线?

如何在Matlab中永久地在图像的两个坐标之间画一条线? [重复]

使用 SceneKit 在两点之间绘制一条线

我一直忙于寻找如何在我的应用程序中的地图上的一个(GPS)点和一个标记之间画一条线。有人可以吗?