Swiftui Wrapping Hstack with Images

SwiftUI Wrapping HStack with Images

According to the WrappingHStack library, if you want to achieve what you above-mentioned, you need to do two things:

  • Give your Image a frame so that the WrappingHStack can know how many elements to put in per line.
  • Change your ForEach loop to WrappingHStack, because WrappingHStack can be used as a ForEach to loop over items.
WrappingHStack(0..<numEarths, id:\.self) { _ in
Image("logo")
.resizable()
.frame(width: 100, height: 100)
}

Working Solution image

How to image setup in hstack under Swiftui

With zIndex you can do it



Sample Image

Version 1.0.0

struct ImageStackRoundUpr: View {

var friendImages = ["1", "2", "3", "4", "5"]

var body: some View {

HStack(spacing: -10.0) {

ForEach(friendImages.indices, id: \.self) { index in
Image(friendImages[index])
.resizable()
.scaledToFit()
.frame(width: 80, height: 80)
.background(Color.gray)
.clipShape(Circle())
.overlay(Circle().stroke(Color.black, lineWidth: 2))
.zIndex(Double(friendImages.count - index))
}

Spacer()

}
.background(Color.green)

}
}


Version 2.0.0

ultimately you would looking for this

Sample Image



import SwiftUI

struct ContentView: View {
var body: some View {

zIndexHierarchyView()

}
}


struct zIndexHierarchyView: View {

let imageArray: [String] = ["1", "2", "3", "4", "5"]

var body: some View {

ScrollView(.horizontal, showsIndicators: false) {

HStack(spacing: -30.0) {

ForEach(imageArray.indices, id: \.self) { index in

Image(imageArray[index])
.resizable()
.scaledToFit()
.frame(width: 150, height: 150)
.background(Color.gray)
.clipShape(Circle())
.overlay(Circle().strokeBorder(Color.black, lineWidth: 3))
.zIndex(Double(imageArray.count + imageArray.count - index)) // <<: Here!
.shadow(radius: 10)

}

ForEach(imageArray.indices, id: \.self) { index in

Image(imageArray[index])
.resizable()
.scaledToFit()
.frame(width: 150, height: 150)
.background(Color.gray)
.clipShape(Circle())
.overlay(Circle().stroke(Color.black, lineWidth: 3))
.zIndex(Double(imageArray.count - index)) // <<: Here!
.shadow(radius: 10)

}

}
.padding(10)
.background(Color.green)
.cornerRadius(10)

}
.shadow(radius: 10)
.statusBar(hidden: true)

}
}


Version 2.0.1

About update: this update made just per request of OP for solving new issue!



Sample Image

struct ImageStackRoundUpr: View {

var friendRiders = ["1", "2", "3", "4", "5"]
var nonFriendRiders = ["1", "2", "3", "4", "5"]

var body: some View {

HStack(spacing: -10) {

Image("1")
.renderingMode(.original)
.resizable()
.frame(width: 40, height: 40)
.background(Color.gray)
.clipShape(Circle())
.overlay(Circle().stroke(Color.black, lineWidth: 1))
.zIndex(Double(friendRiders.count + nonFriendRiders.count + 1))
.overlay(Image("Crown")
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 23, height: 23)
.shadow(radius: 1)
.offset(x: 0, y: -25)
.rotationEffect(.degrees(12)))

ForEach(self.friendRiders.indices, id: \.self) { rider in

Image(friendRiders[rider])
.renderingMode(.original)
.resizable()
.frame(width: 34, height: 34)
.background(Color.gray)
.clipShape(Circle())
.overlay(Circle().stroke(Color.black, lineWidth: 1))
.zIndex(Double(friendRiders.count + nonFriendRiders.count - rider))

}

ForEach(self.nonFriendRiders.indices, id: \.self) { rider in

Image(nonFriendRiders[rider])
.renderingMode(.original)
.resizable()
.frame(width: 34, height: 34)
.background(Color.gray)
.clipShape(Circle())
.overlay(Circle().stroke(Color.black, lineWidth: 1))
.zIndex(Double(nonFriendRiders.count - rider))
}


Spacer()

}
.padding(.vertical)

}
}

SwiftUi line pass with a hstack

As someone suggested, you should try to checkout LazyVStack or LazyHStack. Here is some code that may help you.

struct ContentView: View {

let items = [GridItem(.flexible()), GridItem(.flexible()),GridItem(.flexible())]

let data = (1...20).map { "Item #\($0)" }

var body: some View {
LazyVGrid(columns: items) {
ForEach(data, id: \.self) { item in
Text(item)
.padding()
.background(.green)
}
}
}
}

Sample Image

Wrap Text Around a Variable Amount of Images in SwiftUI

Thanks to @Fogmeister for the tip! Went with just doing Text(someImageVar) + Text("The text...) and this works great. I've now just got something like this:

var body: some View {
HStack(alignment: .bottom) {
content
}
.padding(.horizontal, 10)
.padding(.vertical, 1)
.onAppear(perform: onAppear)
}

And the onAppear logic just runs an async Task and ends up doing content = content + Text(newlyLoadedImage)

How do I center these images in a straight line inside my HStack in SwiftUI

Wrapping everything in a geometryreader and assigning relative width to your textviews should do the trick:

var body: some View {
//decide which image to show
GeometryReader{ readerProxy in <- add this
HStack(alignment: .center){
Text(dailyData.time)
.fontWeight(.semibold)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
.frame(width: readerProxy.size.width / 3, alignment: .left) <- add this
Spacer()
Image(dailyData.icon)
.resizable()
.scaledToFit()
.frame(width: 25, height: 25, alignment: .center)
.multilineTextAlignment(.leading)
Spacer()
HStack(spacing: 10){
Text(dailyData.lowtemp + "°")
.fontWeight(.regular)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
Text(dailyData.hightemp + "°")
.fontWeight(.regular)
.foregroundColor(Color(UIColor.white))
.font(.system(size: 16))
}
.frame(width: readerProxy.size.width / 3, alignment: .right) <- add this
}
}
}

Constrain the size of an HStack (with Images) to the width of the device

Use resizable() and aspectRatio()modifier for Image.

HStack {
Image("apple").resizable().aspectRatio(contentMode: .fit)
Image("cherry").resizable().aspectRatio(contentMode: .fit)
Image("star").resizable().aspectRatio(contentMode: .fit)
}

You can also use

Image("star").resizable().scaledToFit()


Related Topics



Leave a reply



Submit