SwiftUI Position Overlay при предварительном просмотре камеры - PullRequest
1 голос
/ 04 февраля 2020

Я пытаюсь добавить объектоподобный оверлей к предварительному просмотру фотографий в приложении, которое использует портрет на одних устройствах и пейзаж на других. Я могу установить координаты вручную, но не смог получить правильные координаты кадра предварительного просмотра камеры.

Это приложение SwiftUI, поэтому я выполняю работу с камерой в UIViewControllerRepresentable. Вот что у меня есть и, очевидно, целевой круг всегда неверен, когда устройство и / или ориентация меняются. Кажется, я не могу запечатлеть кадр модального вида, где есть предварительный просмотр камеры. Я бы согласился, чтобы иметь возможность указать рамку и местоположение предварительного просмотра камеры на модальном виде.

struct CaptureImageView: View {
    @Binding var isShown: Bool
    @Binding var image: Image?
    @Binding var newUIImage: UIImage?
    @Binding var showSaveButton: Bool

    func makeCoordinator() -> Coordinator {
        return Coordinator(isShown: $isShown, image: $newUIImage, showSaveButton: $showSaveButton)
    }
}

extension CaptureImageView: UIViewControllerRepresentable {

    func makeUIViewController(context: UIViewControllerRepresentableContext<CaptureImageView>) -> UIImagePickerController {

        let vc = UIImagePickerController()

        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera) {
            vc.sourceType = .camera
            vc.allowsEditing = true
            vc.delegate = context.coordinator

            let screenSize: CGRect = UIScreen.main.bounds
            let screenWidth = screenSize.width
            let screenHeight = screenSize.height

            vc.cameraOverlayView = CircleView(frame: CGRect(x: (screenWidth / 2) - 50, y: (screenWidth / 2) + 25, width: 100, height: 100))

            return vc
        }
        return UIImagePickerController()
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<CaptureImageView>) {
    }
}

Вот идея - но цель всегда должна быть центрирована:

enter image description here

И целевой файл:

class CircleView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.clear
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ rect: CGRect) {
        if let context = UIGraphicsGetCurrentContext() {
            context.setLineWidth(3.0)
            UIColor.red.set()

            let center = CGPoint(x: frame.size.width / 2, y: frame.size.height / 2)
            let radius = (frame.size.width - 10) / 2

            context.addArc(center: center, radius: radius, startAngle: 0.0, endAngle: .pi * 2.0, clockwise: true)
            context.strokePath()
        }
    }
}

Любое руководство будет оценено. Версия Xcode 11.3.1 (11C504)

Ответы [ 2 ]

1 голос
/ 15 февраля 2020

Хотя я все еще хотел бы найти ответ на вопрос, как получить кадр камеры, моя цель может быть в основном достигнута путем создания кругового обзора в VStack, например:

if showCaptureImageView {
    ZStack {
        CaptureImageView(isShown: $showCaptureImageView, image: $myImage, newUIImage: $newUIImage, showSaveButton: $showSaveButton)

        Circle()
            .stroke(Color.red, style: StrokeStyle(lineWidth: 10 ))
            .frame(width: 100, height: 100)
            .offset(CGSize(width: 0, height: -50.0))
    }
}//if show
0 голосов
/ 04 мая 2020

Как отмечает GrandSteph, лучшим подходом было бы обернуть изображение с камеры в считывателе геометрии. Вот один из подходов:

if showCaptureImageView {
    ZStack {
        VStack {
            Rectangle()//just to show that the circle below can be centered
                    .frame(width: 300, height: 150)
                    .background(Color.blue)

            GeometryReader { geo in
                CaptureImageView(isShown: self.$showCaptureImageView, image: self.$image)
                .onAppear {
                    self.cameraWindowWidth = geo.size.width
                    self.cameraWindowHeight = geo.size.height
                }
            }//geo
        }//v

        Circle().frame(width: 50, height: 50)
        .position(x: self.cameraWindowWidth / 2, y: (self.cameraWindowHeight / 2) + 150)
        .foregroundColor(.red)

    }//z
}//if show
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...