首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI LazyVStack重叠图像

SwiftUI LazyVStack重叠图像
EN

Stack Overflow用户
提问于 2021-06-20 10:23:33
回答 1查看 175关注 0票数 0

我试图在一个嵌入在滚动视图中的LazyVStack中显示两列图像,但是第二行图像与上面的行部分重叠。我不确定这是LazyVStack本身的问题还是Photo.swift视图的问题。

输出如下所示

这两个视图文件

ContentView.swift

代码语言:javascript
复制
struct ContentView: View {
    @State private var image: Image?
    @State private var showingCustomCamera = false
    @State private var inputImage: UIImage?
    @State private var photos: [UIImage] = []
    
    func addImageToArray() {
        guard let inputImage = inputImage else { return }
        image = Image(uiImage: inputImage)
        
        let ciImage = CIImage(cgImage: inputImage.cgImage!)

        let options = [CIDetectorAccuracy: CIDetectorAccuracyHigh]
        let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: options)!

        let faces = faceDetector.features(in: ciImage)

        if let face = faces.first as? CIFaceFeature {
            print("Found face at \(face.bounds)")

            print(face.faceAngle)
            print(face.hasSmile)
            print(face.leftEyeClosed)
            print(face.rightEyeClosed)
            
            if face.leftEyeClosed {
                print("Left Eye Closed \(face.leftEyePosition)")
            }

            if face.rightEyeClosed {
                print("Right Eye Closed \(face.rightEyePosition)")
            }

            if face.hasSmile {
                print("Person is smiling \(face.mouthPosition)")
            }
        }
        
        photos.append(inputImage)
    }
    
    let columns = [
        GridItem(.flexible(), spacing: 20),
        GridItem(.flexible(), spacing: 20)
    ]
    
    var body: some View {
        NavigationView {
            VStack{
                ScrollView {
                    LazyVGrid(columns: columns, spacing: 20) {
                        AddPhoto(showCamera: $showingCustomCamera)
                        
                        ForEach(photos, id: \.self) { photo in
                            PassportPhoto(img: photo)
                        }
                    }
                    .padding()
                }
                
                HStack {
                    Button(action: {
                        //
                    }, label: {
                        Image(systemName: "printer.fill.and.paper.fill")
                        Text("Print")
                    })
                    .padding()
                    .foregroundColor(.primary)
                    
                    Button(action: {
                        //
                    }, label: {
                        Image(systemName: "externaldrive.fill.badge.icloud")
                        Text("Digital Upload")
                    })
                    .padding()
                    .foregroundColor(.primary)
                }
            }
            .sheet(isPresented: $showingCustomCamera, onDismiss: addImageToArray) {
                CustomCameraView(image: self.$inputImage)
            }
            .navigationTitle("Add Photos")
        }
    }
}

Photo.swift

代码语言:javascript
复制
struct Photo: View {
    var img: UIImage
    @State private var overlay: Bool = false
    
    var body: some View {
        GeometryReader { geometry in
            VStack {
                ZStack(alignment: .top) {
                    Image(uiImage: img)
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(width: geometry.size.width, height: geometry.size.width * 1.29, alignment: .top)
                        .clipped()
                        .cornerRadius(10)
                        .onTapGesture {
                            self.overlay.toggle()
                        }
                    
                    if overlay {
                        Template()
                    }
                }
            }
        }
    }
}

有谁知道吗?我觉得我漏掉了一些明显的东西。

CustomCameraView.swift (根据请求)

代码语言:javascript
复制
import SwiftUI
import AVFoundation
 
struct CustomCameraView: View {
    @Binding var image: UIImage?
    @State var didTapCapture: Bool = false
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        VStack(alignment: .center) {
            CustomCameraRepresentable(image: self.$image, didTapCapture: $didTapCapture)
                .overlay(Template(),alignment: .center)
                .overlay(
                    CaptureButtonView().onTapGesture {
                        self.didTapCapture = true
                    }
                    , alignment: .bottom)
                .overlay(
                    Button(action: {
                        presentationMode.wrappedValue.dismiss()
                    }, label: {
                        Image(systemName: "multiply")
                            .scaleEffect(2)
                            .padding(20)
                            .onTapGesture {
                                presentationMode.wrappedValue.dismiss()
                            }
                    })
                    .foregroundColor(.white)
                    .padding()
                    , alignment: .topTrailing)
        }
    }
    
}


struct CustomCameraRepresentable: UIViewControllerRepresentable {
    
    @Environment(\.presentationMode) var presentationMode
    @Binding var image: UIImage?
    @Binding var didTapCapture: Bool
    
    func makeUIViewController(context: Context) -> CustomCameraController {
        let controller = CustomCameraController()
        controller.delegate = context.coordinator
        return controller
    }
    
    func updateUIViewController(_ cameraViewController: CustomCameraController, context: Context) {
        
        if(self.didTapCapture) {
            cameraViewController.didTapRecord()
        }
    }
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, UINavigationControllerDelegate, AVCapturePhotoCaptureDelegate {
        let parent: CustomCameraRepresentable
        
        init(_ parent: CustomCameraRepresentable) {
            self.parent = parent
        }
        
        func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
            
            parent.didTapCapture = false
            
            if let imageData = photo.fileDataRepresentation() {
                parent.image = UIImage(data: imageData)
            }
            parent.presentationMode.wrappedValue.dismiss()
        }
    }
}

class CustomCameraController: UIViewController {
    
    var image: UIImage?
    
    var captureSession = AVCaptureSession()
    var backCamera: AVCaptureDevice?
    var frontCamera: AVCaptureDevice?
    var currentCamera: AVCaptureDevice?
    var photoOutput: AVCapturePhotoOutput?
    var cameraPreviewLayer: AVCaptureVideoPreviewLayer?
    
    //DELEGATE
    var delegate: AVCapturePhotoCaptureDelegate?
    
    func didTapRecord() {
        
        let settings = AVCapturePhotoSettings()
        photoOutput?.capturePhoto(with: settings, delegate: delegate!)
        
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setup()
    }
    func setup() {
        setupCaptureSession()
        setupDevice()
        setupInputOutput()
        setupPreviewLayer()
        startRunningCaptureSession()
    }
    func setupCaptureSession() {
        captureSession.sessionPreset = AVCaptureSession.Preset.photo
    }
    
    func setupDevice() {
        let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera],
                                                                      mediaType: AVMediaType.video,
                                                                      position: AVCaptureDevice.Position.unspecified)
        for device in deviceDiscoverySession.devices {
            
            switch device.position {
            case AVCaptureDevice.Position.front:
                self.frontCamera = device
            case AVCaptureDevice.Position.back:
                self.backCamera = device
            default:
                break
            }
        }
        
        self.currentCamera = self.backCamera
    }
    
    
    func setupInputOutput() {
        do {
            
            let captureDeviceInput = try AVCaptureDeviceInput(device: currentCamera!)
            captureSession.addInput(captureDeviceInput)
            photoOutput = AVCapturePhotoOutput()
            photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
            captureSession.addOutput(photoOutput!)
            
        } catch {
            print(error)
        }
        
    }
    func setupPreviewLayer()
    {
        let rect = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.width * 1.29)
        
        self.cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        self.cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
        self.cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
        self.cameraPreviewLayer?.frame = rect
        self.view.layer.insertSublayer(cameraPreviewLayer!, at: 0)
        
    }
    func startRunningCaptureSession(){
        captureSession.startRunning()
    }
}


struct CaptureButtonView: View {
    @State private var animationAmount: CGFloat = 1
    var body: some View {
        Image(systemName: "camera").font(.largeTitle)
            .padding(30)
            .background(Color.red)
            .foregroundColor(.white)
            .clipShape(Circle())
            .overlay(
                Circle()
                    .stroke(Color.red)
                    .scaleEffect(animationAmount)
                    .opacity(Double(2 - animationAmount))
                    .animation(Animation.easeOut(duration: 1)
                        .repeatForever(autoreverses: false))
        )
            .padding(.bottom)
            .onAppear
            {
                self.animationAmount = 2
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2021-06-20 16:39:49

你不应该在ScrollView中使用GeometryReader,它会给你带来麻烦。相反,在VStack下面的顶层定义它,并将proxy向下传递到照片视图以设置Frame。

检查以下代码-:

代码语言:javascript
复制
import SwiftUI


struct Test1: View {
    @State private var image: Image?
    @State private var showingCustomCamera = false
    @State private var inputImage: UIImage?
    @State private var photos: [UIImage] = []
    
    func addImageToArray() {
        guard let inputImage = inputImage else { return }
        image = Image(uiImage: inputImage)
        
        let ciImage = CIImage(cgImage: inputImage.cgImage!)
        
        let options = [CIDetectorAccuracy: CIDetectorAccuracyHigh]
        let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: options)!
        
        let faces = faceDetector.features(in: ciImage)
        
        if let face = faces.first as? CIFaceFeature {
            print("Found face at \(face.bounds)")
            
            print(face.faceAngle)
            print(face.hasSmile)
            print(face.leftEyeClosed)
            print(face.rightEyeClosed)
            
            if face.leftEyeClosed {
                print("Left Eye Closed \(face.leftEyePosition)")
            }
            
            if face.rightEyeClosed {
                print("Right Eye Closed \(face.rightEyePosition)")
            }
            
            if face.hasSmile {
                print("Person is smiling \(face.mouthPosition)")
            }
        }
        
        photos.append(inputImage)
    }
    
    let columns =
        [GridItem(.flexible(),spacing: 20),
         GridItem(.flexible(),spacing: 20)]
    
    
    var body: some View {
        NavigationView {
            VStack{
                GeometryReader { geometry in
                    ScrollView {
                        LazyVGrid(columns: columns, spacing: 20) {
                            // AddPhoto(showCamera: $showingCustomCamera) // Uncomment in your case
                            
                            
                            ForEach(0..<50, id: \.self) { photo in
                                Photo(img: "ABC", proxy: geometry) // Pass photo as you were doing
                                
                            }
                        }
                        .padding()
                    }
                }
                
                HStack {
                    Button(action: {
                        //
                    }, label: {
                        Image(systemName: "printer.fill.and.paper.fill")
                        Text("Print")
                    })
                    .padding()
                    .foregroundColor(.primary)
                    
                    Button(action: {
                        //
                    }, label: {
                        Image(systemName: "externaldrive.fill.badge.icloud")
                        Text("Digital Upload")
                    })
                    .padding()
                    .foregroundColor(.primary)
                }
            }
            .sheet(isPresented: $showingCustomCamera, onDismiss: addImageToArray) {
                // CustomCameraView(image: self.$inputImage)
            }
            .navigationTitle("Add Photos")
        }
    }
}

struct Photo: View {
    var img: String
    var proxy:GeometryProxy
    @State private var overlay: Bool = false
    
    var body: some View {
        //  GeometryReader { geometry in
        VStack {
            ZStack(alignment: .top) {
                Image(img)
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    // .frame(width: 170, height: 200)
                    .frame(width: proxy.size.width * 0.4, height: proxy.size.width * 0.5, alignment: .top)
                    .clipped()
                    .cornerRadius(10)
                    .onTapGesture {
                        self.overlay.toggle()
                    }
                
                if overlay {
                    // Template()
                }
            }
        }
        //}
    }
} 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68052176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档