SwiftUI: как наложить на изображение несколько форм и зависимое позиционирование

Я хотел бы разместить несколько фигур (прямоугольников) поверх изображения, но прямоугольники должны иметь фиксированные позиции на изображении. Таким образом, независимо от размера или ориентации экрана, прямоугольник всегда должен покрывать одно и то же содержимое изображения. Итак, на следующем изображении я, например, хотел бы, чтобы прямоугольник покрыл ноги, другой - руки, а третий - пресс и спину.

Мой ImageView выглядит так:

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)

        }
    }
}

И вместе с прямоугольниками он встроен в мой основной вид:

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)
                }
            }
        }
    }
}

В настоящее время я жестко кодирую размер и положение прямоугольников, например, ног:

Rectangle().foregroundColor(.blue)
    .frame(width: size.width, height: size.height/7)
    .position(x: size.width/2, y: size.height/2+80)

Но, очевидно, это не сработает, как только изменится размер / ориентация экрана.

Как лучше всего настроить размер и положение прямоугольников на изображении?

//ОБНОВИТЬ

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()
}

Приводя к следующему результату:

поэтому я предполагаю, что позиционирование выполняется по всему экрану, а не по положению самого изображения..

2 ответа

Размещение представления относительно изображения (в примере 90% ширины / высоты):

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)
                }
            )
    }
}

Вы также можете использовать relativeWidth/height, которые существовали некоторое время назад и которые показаны здесь https://vmanot.com/reimplementing-swiftui-s-deprecated-relative-view-sizing-functions как повторная реализация

Другие вопросы по тегам