Как настроить размер фигур по размеру экрана и выровнять их по центру? - PullRequest
0 голосов
/ 06 августа 2020

В приложении, над которым я работаю, я использовал PocketSVG для чтения путей, хранящихся в файле .svg, следующим образом (init):

class ColoringImageViewModel: ObservableObject {
    @Published var shapeItemsByKey = [UUID: ShapeItem]()
    var shapeItemKeys: [UUID] = []
    
    init(selectedImage: String) {
        let svgURL = Bundle.main.url(forResource: selectedImage, withExtension: "svg")!
        let _paths = SVGBezierPath.pathsFromSVG(at: svgURL)
        for (index, path) in _paths.enumerated() {
            let scaledBezier = ScaledBezier(bezierPath: path)
            let shapeItem = ShapeItem(path: scaledBezier)
            shapeItemsByKey[shapeItem.id] = shapeItem
            shapeItemKeys.append(shapeItem.id)
        }
    }
}

struct ShapeItem: Identifiable {
    let id = UUID()
    var color: Color = Color.white
    var path: ScaledBezier
    init(path: ScaledBezier) {
        self.path = path
    }
}

После прочтения путей я преобразовываю их в формы и поместите каждую фигуру как ShapeView в ZStack:

struct ShapeView: View {
    @Binding var shapeItem: ShapeItem?
    var body: some View {
        ZStack {
            shapeItem!.path
                .fill(shapeItem!.color)
            shapeItem?.path.stroke(Color.black)
            
        }
    }
}



struct ColoringImageView: View {
...
    var body: some View {
            GeometryReader {
                geometry in
                ZStack {
                    ForEach(coloringImageViewModel.shapeItemKeys, id: \.self){ id in
                        ShapeView(shapeItem: $coloringImageViewModel.shapeItemsByKey[id])
                    }
                }
                .frame(width: geometry.size.width, height: geometry.size.height, alignment: .center)
                .background(Color.white)
                .contentShape(Rectangle())
                .edgesIgnoringSafeArea(.all)
            }
            
        }
...
}

На экране пути расположены, как показано ниже:

enter image description here

Instead, I would like to place an arbitrary vector image (split to paths) in the middle of the screen and scale it such that it fits the screen as shown below:

enter image description here

I would appreciate any suggestion to modify the code or implement the additional logic in order to fit the screen and align the image.

Edit

After replacing

.frame(width: geometry.size.width, height: geometry.size.height, alignment: .center)

with

.frame(maxWidth: .infinity, maxHeight: .infinity)

the image is placed as shown below:

введите описание изображения здесь

Кажется, что по вертикали изображение центрировано, хотя я не уверен, так как по горизонтали оно не кажется центрированным. Кроме того, я не нашел решения для размещения изображения на экране (изображение в примере не умещается на экране).

1 Ответ

0 голосов
/ 07 августа 2020

Вместо GeometryReader используйте максимальный кадр для ZStack следующим образом

var body: some View {
    ZStack {
        Color.clear   // this gives full screen ZStack

        ForEach(coloringImageViewModel.shapeItemKeys, id: \.self){ id in
            ShapeView(shapeItem: $coloringImageViewModel.shapeItemsByKey[id])
        }
    }
    .background(Color.white)
    .contentShape(Rectangle())
    .edgesIgnoringSafeArea(.all)
}
...