As the title suggests, I'm looking to offset some views, a Circle
inside of an HStack
, however in doing so, this results in weird behavior where the frame of the HStack is no longer properly wrapping the contents. I need this "Offset" action to still allow proper leading and trailing padding, without empty space there. I considered using a ZStack
as well, however I feel like that might be cumbersome as I need it to "Wrap" my contents, rather than take all space available.
HStack {
ForEach(novaraUsers.indices, id: \.self) { index in
let user = novaraUsers[index]
if index < visibleUserCount + 1 {
Group {
if index < visibleUserCount {
Circle()
.fill(.white)
.stroke(Color.getRandomColor(from: user.username), lineWidth: 4)
.foregroundColor(.white)
.frame(width: 50, height: 50)
.overlay(
Text(user.username.prefix(1))
.font(.title)
.foregroundColor(.black)
.font(.h1)
)
} else {
Circle()
.fill(.white)
.stroke(Color.getRandomColor(from: String(novaraUsers.count)), lineWidth: 4)
.foregroundColor(.white)
.frame(width: 50, height: 50)
.overlay(
Text("\(moreThanCount)+")
.font(.title)
.foregroundColor(.black)
.font(.h1)
)
}
}
.offset(x: CGFloat(offsetPerCircle * index) * -1)
}
}
}
.frame(width: CGFloat(50 * (visibleUserCount + moreThanCount)))
.border(.black, width: 2)
One way to achieve this layout is to switch the way the circles are drawn. Instead of having a circle as the base view with the text as an overlay, use the text as the base view and apply the circle as background. If the circle is slightly larger than the base view (the text) then you get the overlap effect you are after and no offset needs to be used at all.
Like this:
Group {
if index < visibleUserCount {
Text(user.username.prefix(1))
.font(.title)
.foregroundColor(.black)
.font(.h1)
.frame(width: 35, height: 35)
.background {
Circle()
.inset(by: -7.5)
.fill(.white)
.stroke(Color.getRandomColor(from: user.username), lineWidth: 4)
.foregroundColor(.white)
}
} else {
Text("\(moreThanCount)+")
.font(.title)
.foregroundColor(.black)
.font(.h1)
.frame(width: 35, height: 35)
.background {
Circle()
.inset(by: -7.5)
.fill(.white)
.stroke(Color.getRandomColor(from: String(novaraUsers.count)), lineWidth: 4)
.foregroundColor(.white)
}
}
}
// Not needed
//.offset(x: CGFloat(offsetPerCircle * index) * -1)