Skip to content

Commit

Permalink
view: add qrcodeview
Browse files Browse the repository at this point in the history
  • Loading branch information
reez authored Sep 28, 2023
1 parent 5946aa5 commit bfaa26f
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
79 changes: 79 additions & 0 deletions Sources/BitcoinUI/QRCodeView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//
// QRCodeView.swift
//
//
// Created by Matthew Ramsden on 9/28/23.
//

import SwiftUI
import CoreImage.CIFilterBuiltins

enum QRCodeType {
case bitcoin(String)
case lightning(String)

var qrString: String {
switch self {
case .bitcoin(let address):
return "bitcoin:\(address)"
case .lightning(let invoice):
return "lightning:\(invoice)"
}
}
}

struct QRCodeView: View {
@State private var viewState = CGSize.zero
let screenBounds = UIScreen.main.bounds
var qrCodeType: QRCodeType

var body: some View {
Image(uiImage: generateQRCode(from: qrCodeType.qrString))
.interpolation(.none)
.resizable()
.scaledToFit()
.padding()
.applyFidgetEffect(viewState: $viewState)
.gesture(dragGesture())
}

private func generateQRCode(from string: String) -> UIImage {
let context = CIContext()
let filter = CIFilter.qrCodeGenerator()
let data = Data(string.utf8)
filter.setValue(data, forKey: "inputMessage")

if let outputImage = filter.outputImage {
if let cgimg = context.createCGImage(outputImage, from: outputImage.extent) {
return UIImage(cgImage: cgimg)
}
}
return UIImage(systemName: "xmark.circle") ?? UIImage()
}

private func dragGesture() -> some Gesture {
DragGesture()
.onChanged(handleDragChanged(_:))
.onEnded(handleDragEnded(_:))
}

private func handleDragChanged(_ value: DragGesture.Value) {
let translation = value.translation
let multiplier: CGFloat = 0.05
viewState.width = -translation.width * multiplier
viewState.height = -translation.height * multiplier
}

private func handleDragEnded(_ value: DragGesture.Value) {
withAnimation {
self.viewState = .zero
}
}
}

#Preview {
QRCodeView(qrCodeType: .bitcoin("bitcoinqrcode"))
}
#Preview {
QRCodeView(qrCodeType: .lightning("lightingqrcode"))
}
12 changes: 12 additions & 0 deletions Sources/BitcoinUI/Utilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import Foundation
import SwiftUI

extension CGFloat {

Expand All @@ -20,3 +21,14 @@ extension CGFloat {
}

}

extension View {
func applyFidgetEffect(viewState: Binding<CGSize>) -> some View {
self
.offset(x: -viewState.wrappedValue.width, y: -viewState.wrappedValue.height)
.rotation3DEffect(
.degrees(viewState.wrappedValue.width),
axis: (x: 0, y: 1, z: 0)
)
}
}

0 comments on commit bfaa26f

Please sign in to comment.