CIFilter の BarcodeGenerator を使うときに注意すること
最小高さと最小幅に気をつける
- バーコードにおいて、最も注意したいのはバーコードが見切れてしまうこと。
- 万が一 View から横幅がはみ出ている状態で clip でもしてしまったら、情報が欠落することになる。
- CIFilter で作成したバーコードには最小幅と最小高さがある。
- 適当なプロジェクトで幅と高さを色々変えてみた。
- 赤枠は指定した frame を表示している
- この画像を見ると、大体最小高さは 30 pt で、最小幅は 100pt ちょいになっている。
- 最小幅はデータによって変わってくるので、制御のしようがない。
- 対して最小高さは CIFilter のプロパティで変更可能。
CICode128BarcodeGenerator | Apple Developer Documentation
- ちなみに ↑ の画像は以下の Preview で作成した。
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)
}
}