SwiftUI 二维码扫描带边框角的reactangle

Myu*_*ura 4 swift swiftui

带角边框线的二维码

我的要求是在4个角线内显示二维码,扫描二维码完成。目前.overlay( RoundedRectangle 显示完整边框,但我需要在下面画一个,有什么想法吗?

CodeScannerView(codeTypes: [.qr], simulatedData: "Some simulated data", completion: self.handleScan)
                 .padding(.horizontal, 40)
                 .cornerRadius(35)
                 .overlay(
                     RoundedRectangle(cornerRadius: 20)
                         .stroke(Color.yellow, lineWidth: 5)
                 )
                 .frame(width: 350, height: 250)
                 .padding(.bottom , 50)``` 


Run Code Online (Sandbox Code Playgroud)

dav*_*dev 5

您可以使用 来实现该边界stroke()。它确实需要更多参数,例如StrokeStyle. 通过一些计算,您就可以得到这个结果。这是一个例子:

struct ContentView : View {
    var body : some View {

        Text("Hello World")
            .frame(width: 275, height: 275)
            .overlay(
                Rectangle()
                    .stroke(Color.yellow, style: StrokeStyle(lineWidth: 5.0,lineCap: .round, lineJoin: .bevel, dash: [60, 215], dashPhase: 29))
            )
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上,您必须传递一个数组dash,其中第一个数字是黄色边框的长度。是215间距。

如果您计算60*4 + 215*4,您将必须得到与计算实际视图范围相同的结果。对我来说是275*4。然后尝试一下 dashPhase,你可以获得一个很好的结果。


LN-*_*-12 5

@davidev 发布的解决方案很简单,适用于静态用例。不过,我使用路径实现了一种更灵活的方法:

struct ScanOverlayView: View {
    var body: some View {
        GeometryReader { geometry in
            let cutoutWidth: CGFloat = min(geometry.size.width, geometry.size.height) / 1.5

            ZStack {
                Rectangle()
                    .fill(Color.black.opacity(0.5))
                    
                RoundedRectangle(cornerRadius: 20)
                    .fill(Color.black)
                    .frame(width: cutoutWidth, height: cutoutWidth, alignment: .center)
                    .blendMode(.destinationOut)
            }.compositingGroup()
            
            Path { path in
                
                let left = (geometry.size.width - cutoutWidth) / 2.0
                let right = left + cutoutWidth
                let top = (geometry.size.height - cutoutWidth) / 2.0
                let bottom = top + cutoutWidth
                
                path.addPath(
                    createCornersPath(
                        left: left, top: top,
                        right: right, bottom: bottom,
                        cornerRadius: 40, cornerLength: 20
                    )
                )
            }
            .stroke(Color.blue, lineWidth: 8)
            .frame(width: cutoutWidth, height: cutoutWidth, alignment: .center)
            .aspectRatio(1, contentMode: .fit)
        }
    }
    
    private func createCornersPath(
        left: CGFloat,
        top: CGFloat,
        right: CGFloat,
        bottom: CGFloat,
        cornerRadius: CGFloat,
        cornerLength: CGFloat
    ) -> Path {
        var path = Path()

        // top left
        path.move(to: CGPoint(x: left, y: (top + cornerRadius / 2.0)))
        path.addArc(
            center: CGPoint(x: (left + cornerRadius / 2.0), y: (top + cornerRadius / 2.0)),
            radius: cornerRadius / 2.0,
            startAngle: Angle(degrees: 180.0),
            endAngle: Angle(degrees: 270.0),
            clockwise: false
        )

        path.move(to: CGPoint(x: left + (cornerRadius / 2.0), y: top))
        path.addLine(to: CGPoint(x: left + (cornerRadius / 2.0) + cornerLength, y: top))

        path.move(to: CGPoint(x: left, y: top + (cornerRadius / 2.0)))
        path.addLine(to: CGPoint(x: left, y: top + (cornerRadius / 2.0) + cornerLength))

        // top right
        path.move(to: CGPoint(x: right - cornerRadius / 2.0, y: top))
        path.addArc(
            center: CGPoint(x: (right - cornerRadius / 2.0), y: (top + cornerRadius / 2.0)),
            radius: cornerRadius / 2.0,
            startAngle: Angle(degrees: 270.0),
            endAngle: Angle(degrees: 360.0),
            clockwise: false
        )

        path.move(to: CGPoint(x: right - (cornerRadius / 2.0), y: top))
        path.addLine(to: CGPoint(x: right - (cornerRadius / 2.0) - cornerLength, y: top))

        path.move(to: CGPoint(x: right, y: top + (cornerRadius / 2.0)))
        path.addLine(to: CGPoint(x: right, y: top + (cornerRadius / 2.0) + cornerLength))

        // bottom left
        path.move(to: CGPoint(x: left + cornerRadius / 2.0, y: bottom))
        path.addArc(
            center: CGPoint(x: (left + cornerRadius / 2.0), y: (bottom - cornerRadius / 2.0)),
            radius: cornerRadius / 2.0,
            startAngle: Angle(degrees: 90.0),
            endAngle: Angle(degrees: 180.0),
            clockwise: false
        )
        
        path.move(to: CGPoint(x: left + (cornerRadius / 2.0), y: bottom))
        path.addLine(to: CGPoint(x: left + (cornerRadius / 2.0) + cornerLength, y: bottom))

        path.move(to: CGPoint(x: left, y: bottom - (cornerRadius / 2.0)))
        path.addLine(to: CGPoint(x: left, y: bottom - (cornerRadius / 2.0) - cornerLength))

        // bottom right
        path.move(to: CGPoint(x: right, y: bottom - cornerRadius / 2.0))
        path.addArc(
            center: CGPoint(x: (right - cornerRadius / 2.0), y: (bottom - cornerRadius / 2.0)),
            radius: cornerRadius / 2.0,
            startAngle: Angle(degrees: 0.0),
            endAngle: Angle(degrees: 90.0),
            clockwise: false
        )
        
        path.move(to: CGPoint(x: right - (cornerRadius / 2.0), y: bottom))
        path.addLine(to: CGPoint(x: right - (cornerRadius / 2.0) - cornerLength, y: bottom))

        path.move(to: CGPoint(x: right, y: bottom - (cornerRadius / 2.0)))
        path.addLine(to: CGPoint(x: right, y: bottom - (cornerRadius / 2.0) - cornerLength))

        return path
    }
}
Run Code Online (Sandbox Code Playgroud)

这将导致:

在此输入图像描述