简体   繁体   中英

SwiftUI simple view, need a push into right direction

I am complete beginner with SwiftUI and I can't wrap my head around how to connect these images with views that represents lines. Now I simply have 3 VStacks with image and text and put them into a HStack, but don't know how to connect these images with a line shown in red in the picture I attached. Note that there's some space between the line and the image. I need general direction and some hints, full working code not necessary.

Thank you.

3 个盒子,水平排列,里面有图像。每个框下方都有一个文本。在每个框之间是红线。

How's this?

3 个盒子,里面有笑脸,下面有文字。盒子之间的红线

In SwiftUI, you use HStack s and VStack s to stack your Views. For the red line, a Rectangle should do. Here's the code:

struct ContentView: View {
    var body: some View {
        
        HStack { /// horizontal stack
            
            VStack {
                Image(systemName: "face.smiling")
                    .font(.system(size: 80))
                    .padding()
                    .border(Color.black, width: 5)
                    
                Text("Text TEXTEXT")
            }
            
            Rectangle()
                .fill(Color.red)
                .frame(height: 5)
            
            VStack {
                Image(systemName: "face.smiling")
                    .font(.system(size: 80))
                    .padding()
                    .border(Color.black, width: 5)
                    
                Text("Text TEXTEXT")
            }
            
            Rectangle()
                .fill(Color.red)
                .frame(height: 5)
            
            VStack {
                Image(systemName: "face.smiling")
                    .font(.system(size: 80))
                    .padding()
                    .border(Color.black, width: 5)
                    
                Text("Text TEXTEXT")
            }
            
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .previewLayout(.fixed(width: 800, height: 200))
    }
}

Version 1.0.0

I decided to give my answer which is same like aheze answer with this difference that you can have CustomVerticalAlignment as well: As I see in your Image in question you want that also:


with CustomVerticalAlignment: In center! 在此处输入图像描述

without CustomVerticalAlignment: off center!

在此处输入图像描述


import SwiftUI

struct ContentView: View {
    var body: some View {
        
        HStack(alignment: .customVerticalAlignment) {
            
            VStack {
                Image(systemName: "star")
                    .resizable()
                    .scaledToFit()
                    .frame(width: 50, height: 50, alignment: .center)
                    .padding()
                    .border(Color.black, width: 5)
                    .alignmentGuide(.customVerticalAlignment) { d in d[VerticalAlignment.center] }
                
                Text("Text")
            }
            
            Capsule()
                .fill(Color.red)
                .frame(height: 5)
                .alignmentGuide(.customVerticalAlignment) { d in d[VerticalAlignment.center] }
            
            VStack {
                Image(systemName: "star")
                    .resizable()
                    .scaledToFit()
                    .frame(width: 50, height: 50, alignment: .center)
                    .padding()
                    .border(Color.black, width: 5)
                    .alignmentGuide(.customVerticalAlignment) { d in d[VerticalAlignment.center] }
                
                Text("Text")
            }
            
            Capsule()
                .fill(Color.red)
                .frame(height: 5)
                .alignmentGuide(.customVerticalAlignment) { d in d[VerticalAlignment.center] }
            
            VStack {
                Image(systemName: "star")
                    .resizable()
                    .scaledToFit()
                    .frame(width: 50, height: 50, alignment: .center)
                    .padding()
                    .border(Color.black, width: 5)
                    .alignmentGuide(.customVerticalAlignment) { d in d[VerticalAlignment.center] }
                
                Text("Text")
            }
            
        }
        .padding()
    }
}


extension VerticalAlignment {
    
    struct CustomVerticalAlignment: AlignmentID {
        
        static func defaultValue(in d: ViewDimensions) -> CGFloat {
            d[VerticalAlignment.center]
        }
        
    }
    
    static let customVerticalAlignment = VerticalAlignment(CustomVerticalAlignment.self)
    
}

Update Version 2.0.0

About this version: I would say it does the same job of version 1.0.0 in less code and also Text and Line are not depending on VStack or eachother any moere!


在此处输入图像描述


import SwiftUI

struct ContentView: View {
    
    var body: some View {
        
        HStack {
            
            image.overlay(text.offset(y: 40), alignment: .bottom)
            
            capsule
            
            image.overlay(text.offset(y: 40), alignment: .bottom)
            
            capsule
            
            image.overlay(text.offset(y: 40), alignment: .bottom)
            
        }
        .padding(50)
    }

    var image: some View {
        
        return Image(systemName: "star.fill")
            .resizable()
            .scaledToFit()
            .padding(10)
            .shadow(radius: 10)
            .frame(width: 50, height: 50, alignment: .center)
            .foregroundColor(Color.red)
            .background(Color.yellow)
            .border(Color.black, width: 5)
        
    }
    
    var capsule: some View {
        
        return Capsule()
            .fill(Color.red)
            .frame(height: 5)
        
    }
    
    var text: some View {
        
        return Text("Hello World!")
            .lineLimit(1)
            .fixedSize()
        
    }
    
}

You could define a Shape that represents your line.

I used the spacing parameter of HStack to do the spacing:

struct MyLine : Shape {
    func path(in rect: CGRect) -> Path {
        Path { path in
            path.move(to: CGPoint(x: 0, y: rect.midY))
            path.addLine(to: CGPoint(x: rect.maxX, y: rect.midY))
        }
    }
}

struct ContentView: View {
    var body: some View {
        HStack(spacing: 10) {
            VStack {
                Image(systemName: "pencil")
                Text("Label")
            }
            MyLine().stroke(Color.red)
            VStack {
                Image(systemName: "pencil")
                Text("Label 2")
            }
            MyLine().stroke(Color.red)
            VStack {
                Image(systemName: "pencil")
                Text("Label 3")
            }
        }
    }
}

You could add a lineWidth parameter to make the stroke thicker:

.stroke(Color.red, lineWidth: 4)

Also, if you didn't using spacing on the HStack , you could using a padding modifier on either the VStack s or the MyLine s to get the spacing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM