SwiftUI --App development I tried arranging Views like that.

As the title suggests, I arranged the views like that. I just placed it for the time being, but I was able to study a lot.

This time I tried arranging the views appropriately, but I personally thought that it is quite nice that the Swift UI can arrange the views neatly thanks to the padding and Spacer.

I've listed some of the things you can learn from the code, so if you're interested, try implementing them.

SwiftUI-demo.gif

What you can learn

-Implementation of Identifiable protocol ・ Data transfer between views ・ Timing to use @State and @Binding ・ HStack, VStack, ScrollView -Each property of each View ・ How to use For Each ・ Round the image ・ Toggle () etc

Implementation

Implementation of the Identifiable protocol

struct Images:Identifiable {
    var id = UUID() //← It seems that you must always prepare the property of the identifier.
    var name: String
    var img:String
}

Main View

struct ContentView: View {
    //@If State is added, View will be redrawn when changed.
    //@Bidirectional data sharing between views is possible with Binding
    @State var flag:Bool = false
    @State var tapName:String = "tapNAME"
    
    private var images = [Images(name: "Xxxx Xxxx", img: "myimage"),
                          Images(name: "Aaaaa Aaaa", img: "myimage"),
                          Images(name: "Bbbbb Bbbb", img: "myimage"),
                          Images(name: "Ccccc Cccc", img: "myimage"),
                          Images(name: "Ddddd Dddd", img: "myimage"),
                          Images(name: "Eeeee Eeee", img: "myimage"),
                          Images(name: "Fffff Ffff", img: "myimage"),
                          Images(name: "Ggggg Gggg", img: "myimage")]
    
    
    var body: some View {
        VStack {
            ScrollView(.vertical, showsIndicators: false, content: {
                HStack {
                    Image(images.first?.img ?? "NoImage")
                        .resizable()
                        .frame(width: 75, height: 75)
                        .clipShape(Circle())
                        .overlay(Circle().stroke(Color.white,lineWidth: 1))
                        .shadow(radius: 10)
                        .padding(.leading)
                    
                    Text(images.first?.name ?? "NoName")
                        .font(.title2)
                        .fontWeight(.bold)
                        .foregroundColor(Color.white)
                        .padding(.leading)
                    
                    Spacer()
                    
                    Image(systemName: "bell.badge")
                        .font(.title)
                        .foregroundColor(Color.white)
                        .padding(.trailing)
                    
                }.padding(.top)
                
                Text(tapName).foregroundColor(.white)
                
                ScrollView(.horizontal, showsIndicators: false, content: {
                    HStack {
                        ForEach(images) { image in
                            CustomBtn(img: Image(image.img), name: image.name, flag: $flag, tapName: $tapName) //To pass variables to CustomBtn$To the head
                        }
                    }
                    HStack {
                        ForEach(images) { image in
                            CustomBtn(img: Image(image.img), name: image.name, flag: $flag, tapName: $tapName)
                        }
                    }
                }).padding(.top)
                //MARK:- First CollectionView
                VStack(alignment: .leading, spacing: nil, content: {
                    Text("First CollectionView")
                        .font(.title)
                        .foregroundColor(Color.white)
                        .fontWeight(.bold)
                        .padding(.top).padding(.leading)
                    ScrollView(.horizontal, showsIndicators: false, content: {
                        HStack {
                            ForEach(images) { image in
                                Image(image.img)
                                    .resizable()
                                    .frame(width: 150, height: 150, alignment: .center)
                                    .cornerRadius(5.0)
                            }
                        }.padding(.leading).padding(.trailing) //Left and right space only
                    })
                })
                //MARK:- Seccond CollectionView
                VStack(alignment: .leading, spacing: nil, content: {
                    Text("Seccond CollectionView")
                        .font(.title)
                        .foregroundColor(Color.white)
                        .fontWeight(.bold)
                        .padding(.top).padding(.leading)
                    ScrollView(.horizontal, showsIndicators: false, content: {
                        HStack {
                            ForEach(images) { image in
                                Image(image.img)
                                    .resizable()
                                    .frame(width: 150, height: 150, alignment:.center)
                                    .cornerRadius(5.0)
                                    .clipShape(Circle())
                            }
                        }.padding(.leading).padding(.trailing)
                    })
                })
                //MARK:- Third CollectionView
                VStack(alignment: .leading, spacing: nil, content: {
                    Text("Third CollectionView")
                        .font(.title)
                        .foregroundColor(Color.white)
                        .fontWeight(.bold)
                        .padding(.top).padding(.leading)
                    ScrollView(.horizontal, showsIndicators: false, content: {
                        HStack {
                            ForEach(images) { image in
                                Image(image.img)
                                    .resizable()
                                    .frame(width: 250, height: 150, alignment:.center)
                                    .cornerRadius(5.0)
                            }
                        }.padding(.leading).padding(.trailing).padding(.bottom)
                    })
                })
                //-------
            })
        }.padding(.top)
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color(#colorLiteral(red: 0.09886621684, green: 0.1093793288, blue: 0.2782805264, alpha: 1)))
        .edgesIgnoringSafeArea(.all)
        
    }
}

The buttons (image and text) at the top of the screen are referenced by creating a Struct below.

//CustomBtn
struct CustomBtn: View {
    let img:Image
    let name:String
    @Binding var flag:Bool
    @Binding var tapName:String //@Bidirectional data sharing between views is possible with Binding
    
    var body:some View {
        //Button
        Button(action: {
            //Write what happens when you press a button in this section
            self.flag.toggle() //false / true Inverts
            self.tapName = name
        }){
            img
                .resizable() //Resize the image nicely
                .frame(width: 50, height: 50) //Frame size
            Text(name)
                .font(.subheadline) //Resize
                .fontWeight(.heavy) //Bold
                .minimumScaleFactor(0.7) //Minimum font size (because it is automatically resized)
                .lineLimit(2) //Maximum number of lines
                .foregroundColor(Color.white)
            
            Spacer()
            
        }.background(Color(#colorLiteral(red: 0.1695919633, green: 0.164103806, blue: 0.3997933269, alpha: 1)))
        .cornerRadius(5.0) //Round the corners a little
        .padding(.horizontal)
        
    }
}

Outputs such as basic view layout and data transfer between views. If I'm self-taught, it works as a program, but I'm always wondering if this is really a best practice. .. So if you can write more beautifully or faster, please let me know in the comments.

I would like to keep it as a memorandum in the future.

Recommended Posts

SwiftUI --App development I tried arranging Views like that.
I tried to introduce CircleCI 2.0 to Rails app
I tried to use Selenium like JQuery
I tried to create a LINE clone app
I made a viewer app that displays a PDF