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.
-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
struct Images:Identifiable {
var id = UUID() //← It seems that you must always prepare the property of the identifier.
var name: String
var img:String
}
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.