I have capsule view on which I would like to superimpose a second "sticker" view to the upper right and cannot get it to work. The upper sticker view remains centered.
How can I get the sticker view to align to the right? Thanks for any suggestions.
Code of top "sticker" view:
struct StickerView: View {
var text: String
var isSelected: Bool {true}
var body: some View {
ZStack{
Capsule()
.fill(Color.red)
.frame(height:56)
.cornerRadius(12)
.frame(maxWidth: .infinity, alignment: .trailing)//no effect
Text(text)
.fontWeight(.bold)
.foregroundColor(.white)
.padding(.horizontal,18)
.multilineTextAlignment(.center)
}.padding(.top,-80)
.fixedSize()
.frame(alignment: .trailing)//no effect
}
}
Code of underlying view:
var body: some View {
ZStack {
Capsule(style: .continuous)
.stroke(isSelected ? Color.red : Color.cyan, lineWidth: 6)
.background(isSelected ? selectedBackgroundColor: Color.clear)
.clipped()
.clipShape(Capsule())
HStack{
Image(systemName: isSelected ? "checkmark.circle.fill" : "circle")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: isSelected ? 24 : 20)
.padding(.trailing,8)
VStack(spacing: 0) {
Text(subscription.displayName)
.frame(maxWidth:.infinity,alignment: .leading)
HStack {
Text(subscription.description)
.frame(maxWidth:.infinity,alignment: .leading)
}
}
.frame(maxWidth:.infinity,alignment: .leading)
Spacer()
VStack{
Text(subscription.displayPrice)
.frame(alignment: .trailing)
.foregroundColor(.white)
}
}
.padding(4)
}
}
One way to superimpose the sticker over the capsule view is to show it as an overlay.
alignment: .topTrailing
for the overlay.alignmentGuide
, instead of negative padding. This way, it will adjust automatically to dynamic font sizes.Here is how it can be done this way:
CapsuleView()
.frame(height: 100)
.overlay(alignment: .topTrailing) {
StickerView(text: "purchased")
.alignmentGuide(.top) { dim in
dim[VerticalAlignment.center]
}
}
BTW, you had quite a lot of redundancy in the code, here is how the two views can be simplified:
// StickerView
var body: some View {
Text(text)
.fontWeight(.bold)
.foregroundStyle(.white)
.padding(18)
.background(.red, in: .capsule)
}
// CapsuleView
var body: some View {
ZStack {
Capsule(style: .continuous)
.fill(isSelected ? selectedBackgroundColor : .clear)
.strokeBorder(isSelected ? .red : .cyan, lineWidth: 3)
HStack {
Image(systemName: isSelected ? "checkmark.circle.fill" : "circle")
.resizable()
.scaledToFit()
.frame(width: isSelected ? 24 : 20)
.padding(.trailing, 8)
VStack(alignment: .leading, spacing: 0) {
Text(subscription.displayName)
Text(subscription.description)
}
.frame(maxWidth:.infinity,alignment: .leading)
Text(subscription.displayPrice)
.foregroundStyle(.white)
}
.padding(4)
}
}