Reputation: 934
I'd like to place several shapes(Rectangles) over an image but the rectangles should have fixed positions on the image. So no matter what screen-size or screen-orientation, a rectangle should always cover the same content of the image. So in the following image, I for instance would like a rectangle covering the legs, another one covering the arms and a third one covering the abs and back.
My ImageView looks like that:
struct ImageView: View {
@ObservedObject var imageName: ImageName
var size: CGSize
var body: some View {
VStack {
Image(self.imageName.name)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: size.width, height: size.width, alignment: .center)
}
}
}
And together with the rectangles it is embedded in my main view:
struct MuscleGuy: View {
@ObservedObject var imageName = ImageName()
var body: some View {
VStack(alignment: .center) {
Spacer()
ZStack(alignment: .center) {
GeometryReader { geometry in
RectangleView( imageName: self.imageName).zIndex(10)
ImageView(imageName: self.imageName, size: geometry.size).zIndex(2)
.position(x: geometry.size.width/2, y: geometry.size.height/2)
}
}
}
}
}
Currently, I'm kind of hardcoding the size and position of the rectangles, for instance the legs:
Rectangle().foregroundColor(.blue)
.frame(width: size.width, height: size.height/7)
.position(x: size.width/2, y: size.height/2+80)
But obviously that doesn't work as soon as the screen size/orientation changes.
What's the best attempt to adjust the size and position of the rectangles to the image?
//UPDATE
VStack {
Spacer()
ZStack {
Rectangle()
.frame(width:self.imageProperties.width, height: self.imageProperties.height/2)
.border(Color.pink, width: 3)
.zIndex(20)
.foregroundColor(Color.clear)
.position(x: self.imageProperties.minX, y: self.imageProperties.maxY)
ImageView(imageName: self.imageName, imageProps: self.imageProperties).zIndex(2)
}
Spacer()
}
Leading to the following outcome:
so I assume, the positioning is done according to the whole screen, and not the image position itself..
Upvotes: 0
Views: 6989
Reputation: 8116
you could also use relativeWidth/height, which existed some time ago and which is shown here https://vmanot.com/reimplementing-swiftui-s-deprecated-relative-view-sizing-functions as reimplentation
Upvotes: 0
Reputation: 4092
Placing a View relative to an Image (at 90% of the width/height in the example):
struct RelativePositionExampleView: View {
var body: some View {
Image("cookies")
.resizable()
.aspectRatio(contentMode: .fit)
.overlay(
GeometryReader { geometry in
Text("Hello")
.background(Color.red)
.position(x: geometry.size.width * 0.9, y: geometry.size.height * 0.9)
}
)
}
}
Upvotes: 1