CIFilter の BarcodeGenerator を使うときに注意すること

最小高さと最小幅に気をつける

CleanShot 2023-02-02 at 18.32.11@2x.png

CICode128BarcodeGenerator | Apple Developer Documentation

struct BarcodeView_Previews: PreviewProvider {
    static var previews: some View {
        let widths: [CGFloat] = [100, 200, 300]
        let heights: [CGFloat] = [20, 30, 40, 50, 60, 100]

        HStack(spacing: 20) {
            ForEach(widths, id: \.self) { width in
                VStack {
                    ForEach(heights, id: \.self) { height in
                        codeWithText(width: width, height: height)
                    }
                }
            }
        }
        .previewLayout(.sizeThatFits)
        .scaledToFit()
        .padding()
    }

    @ViewBuilder static func codeWithText(width: CGFloat, height: CGFloat) -> some View {
        VStack(spacing: 4) {
            BarcodeView(encodedString: "12345678901234")
                .frame(width: width, height: height)
                .border(.red, width: 2)

            Text("w: \(Int(width)), h: \(Int(height))")
                .font(.caption)
        }
    }
}

SwiftUI で使う際の注意点

Image(uiImage: barcode(from: code))

何故か、これだとバーコードが透明になってしまう。
SwiftUI: Image with barcode doesn't show up - Stack Overflow

UIViewRepresentable で wrapping する必要がある。

enum BarcodeGenerator {
    static func generateBarcode(from string: String) -> UIImage? {
        guard let data = string.data(using: String.Encoding.ascii) else { return nil }

        let filter = CIFilter.code128BarcodeGenerator()
        filter.message = data
        filter.barcodeHeight = 10
        filter.quietSpace = 0

        guard let output = filter.outputImage else {
            assertionFailure("Couldn't produce barcode output image")
            return nil
        }
        return UIImage(ciImage: output)
    }
}

SwiftUI UIKit CIFilter