how to get multiple parameter in swift - swiftui

I am new to swift and I am doing a project to create a qr code generator with multiple parameters. I have tried add a parameter with date and it worked.
I don't know how to add more parameters in swift for qr code generator and i want to add more than 4 parameters. When i tried to add parameter, func generateqrcode (default: String, num: Int, time: Date, address: String)-> UIImage {....} after I added the parameters which I have wrotten above sentences, what should i write for the body?
My Orignal Code:
import Foundation
import SwiftUI
import CoreImage.CIFilterBuiltins
struct GenerateQRCode: View {
#State var default = "A1"
#Binding var time: Date
#State var address = "abcdefgh"
#Binding var num: Int
let filter = CIFilter.qrCodeGenerator()
let cont = CIContext()
var dateFormatter: DateFormatter {
let df = DateFormatter()
df.dateFormat = "HH:mm"
return df
}
var body: some View {
NavigationView{
Image(uiImage: imageGenerate(default: default, address: address, time: time, num: num))
.interpolation(.none)
.resizable()
.frame(width: 150, height: 150, alignment: .center)
}.navigationBarBackButtonHidden(true)
}
func generateqrcode(default: String, address: String, time: Date, num: Int)-> UIImage {
let str = dateFormatter.string(from: start)
let data = str.data(using: .utf8)
filter.setValue(data, forKey: "inputMessage")
if let qr = filter.outputImage {
if let qrImage = cont.createCGImage(qr, from: qr.extent){
return UIImage(cgImage: qrImage)
}
}
return UIImage(systemName: "xmark") ?? UIImage()
}
}
What should I add or change for the body? I have tried in my code.
Orignal Version:
func generateqrcode (_ time: Date)-> UIImage {
let str = dateFormatter.string(from: start)
let data = str.data(using: .utf8)
filter.setValue(data, forKey: "inputMessage")
if let qr = filter.outputImage {
if let qrImage = cont.createCGImage(qr, from: qr.extent){
return UIImage(cgImage: qrImage)
}
}
return UIImage(systemName: "xmark") ?? UIImage()
}
Updated Version(Body didn't change same as original version):
func generateqrcode(default: String, address: String, time: Date, num: Int)-> UIImage {
let str = dateFormatter.string(from: start)
let data = str.data(using: .utf8)
filter.setValue(data, forKey: "inputMessage")
if let qr = filter.outputImage {
if let qrImage = cont.createCGImage(qr, from: qr.extent){
return UIImage(cgImage: qrImage)
}
}
return UIImage(systemName: "xmark") ?? UIImage()
}

Related

how to convert muliple int number to string in qr code generator with swiftui

I have made a qr code generator with date and I want to add another picker for hours, and I have tried to conver Int to String, there isn't any problem, when I tried to convert multiple Int to string and it doesn't work and also i want to change the Int format to something like this 12 02:11, first is integer space and time. how could I do that?
My Code:
struct GenerateQRCode: View {
#Binding var time: Date
#Binding var hours: Int
let hour = ["3","6","9","12"]
let filter = CIFilter.qrCodeGenerator()
let cont = CIContext()
var dateFormatter: DateFormatter {
let df = DateFormatter()
df.dateFormat = "HH:mm"
return df
}
var body: some View {
NavigationView{
Image(uiImage: imageGenerate(times:time, hours: hours))
.interpolation(.none)
.resizable()
.frame(width: 150, height: 150, alignment: .center)
}.navigationBarBackButtonHidden(true)
}
func imageGenerate(hours: Int, times: Date)-> UIImage { //<--here how to add integer parameter?
let str = dateFormatter.string(from: start)
let ts = String(hours)
let com = ts + str
let data = com.data(using: .utf8)
filter.setValue(data, forKey: "inputMessage") //
if let qr = filter.outputImage {
if let qrImage = cont.createCGImage(qr, from: qr.extent){
return UIImage(cgImage: qrImage)
}
}
return UIImage(systemName: "xmark") ?? UIImage()
}
}
Preview:
import Foundation
import SwiftUI
import CoreImage.CIFilterBuiltins
struct DatePicker: View {
#State var Time = Date()
#State var sHours = Int()
#State var navigated = false
let hour = ["3", "6", "9", "12"]
var body: some View {
NavigationView{
VStack{
Section{
Text("Please Select Time")
DatePicker("", selection: $startTime, displayedComponents: [.hourAndMinute])
.datePickerStyle(.wheel)
}
Section{
Text("Please Select Minutes")
Picker(selection: $sMinutes, label: Text("Please Select Minutes"))
{
ForEach(0 ..< minutes.count) {
index in Text(self.minutes[index]).tag(index)
}
}
}
Section
{
NavigationLink(destination: GenerateQRCode(start: $Time, minutes: $sHours), isActive: self.$navigated)
{
Text("Complete")
}
}.padding(100)
}.navigationBarTitle("Visitor")
}
}
}
struct DatePicker_Previews: PreviewProvider {
static var previews: some View {
DatePicker()
}
}
Output: "012:30"
what i expected output, should be like this: "3 12:30" first should be hours and then time. i don't know why it only shows 0 if my picker turns to 3. How can i solve it out?

How to make qr code generator with multiple info in swiftui

I Have created a qr code generator with swiftui. i used uiimage to create qr code with datepicker, i want to create with multipile info with qr code generator, I want to add a integer as a picker to combine with the datepicker, what do i need to add for the function to make multiple info.
Here is my orginial code.
import Foundation
import SwiftUI
import CoreImage.CIFilterBuiltins
struct ContentView: View {
#State var start = Date()
var body: some View {
VStack {
DatePicker("", selection: $start, displayedComponents: [.hourAndMinute])
.datePickerStyle(.wheel)
Generate(start: $start)
}
}
}
struct GenerateQRCode: View {
#Binding var start: Date
let filter = CIFilter.qrCodeGenerator()
let cont = CIContext()
var dateFormatter: DateFormatter {
let df = DateFormatter()
df.dateFormat = "HH:mm"
return df
}
var body: some View {
NavigationView{
Image(uiImage: imageGenerate(start))
.interpolation(.none)
.resizable()
.frame(width: 150, height: 150, alignment: .center)
}.navigationBarBackButtonHidden(true)
}
func imageGenerate(_ start: Date)-> UIImage {
let str = dateFormatter.string(from: start)
let data = str.data(using: .utf8)
filter.setValue(data, forKey: "inputMessage")
if let qr = filter.outputImage {
if let qrImage = cont.createCGImage(qr, from: qr.extent){
return UIImage(cgImage: qrImage)
}
}
return UIImage(systemName: "xmark") ?? UIImage()
}
}

How to set a date picker for QR Code to select in XCode SwiftUI

I have created a qr code generator and i want to do time set in the qr code, so i used a date picker for time and it only shows hours and minutes. i want to use the date picker to show the result in qr code like this (12 34).
I have tried with the string but i don't know to do with the datetime
Code for string(Is working in XCode)
import Foundation
import SwiftUI
import CoreImage.CIFilterBuiltins
struct Generate: View {
#State var start = String
let filter = CIFilter.qrCodeGenerator()
let cont = CIContext()
var body: some View {
Image(uiImage: imageGenerate(start))
.interpolation(.none)
.resizable()
.frame(width: 150, height: 150, alignment: .center)
}
func imageGenerate(_ start: Int?)-> UIImage {
let data = Data(start)
filter.setValue(data, forKey: "inputMessage")
if let qr = filter.outputImage {
if let qrImage = cont.createCGImage(qr, from: qr.extent){
return UIImage(cgImage: qrImage)
}
}
return UIImage(systemName: "xmark") ?? UIImage()
}
}
Code for datetime(not working)
import Foundation
import SwiftUI
import CoreImage.CIFilterBuiltins
struct Generate: View {
#State var start = Timer()
let filter = CIFilter.qrCodeGenerator()
let cont = CIContext()
var body: some View {
Image(uiImage: imageGenerate(start))
.interpolation(.none)
.resizable()
.frame(width: 150, height: 150, alignment: .center)
}
func imageGenerate(_ start: Timer)-> UIImage {
let data = Data(start.[not utf8, don't know what should it be?])
filter.setValue(data, forKey: "inputMessage")
if let qr = filter.outputImage {
if let qrImage = cont.createCGImage(qr, from: qr.extent){
return UIImage(cgImage: qrImage)
}
}
return UIImage(systemName: "xmark") ?? UIImage()
}
}
Update Part
code for date picker
#State private var startTime = Date()
var body: some View {
Form{
Section {
VStack{
Text("Please Select Start Time")
.padding(.bottom, 10)
.font(.system(size:20))
.bold()
DatePicker("", selection: $startTime, displayedComponents: .hourAndMinute)
.labelsHidden()
.datePickerStyle(.wheel)
}
VStack{
Picker(selection: $sMinutes, label: Text("Please Select Minutes"))
{
ForEach(0 ..< minutes.count) {
index in Text(self.minutes[index]).tag(index)
}
}
}
}
Button("Complete"){
self.showflag.toggle()
}
.font(.system(size:20))
.bold()
.foregroundColor(Color.blue)
.frame(maxWidth: .infinity)
}
Try this example code to show a qr code using a date picker.
The code uses a DatePicker to select the hours and minutes.
Then a DateFormatter to convert those into a string for the qr code generator.
struct ContentView: View {
#State var start = Date()
var body: some View {
VStack {
DatePicker("", selection: $start, displayedComponents: [.hourAndMinute])
.datePickerStyle(.wheel)
Generate(start: $start)
}
}
}
struct Generate: View {
#Binding var start: Date // <-- here
let filter = CIFilter.qrCodeGenerator()
let cont = CIContext()
var dateFormatter: DateFormatter { // <-- here
let df = DateFormatter()
df.dateFormat = "HH:mm"
return df
}
var body: some View {
Image(uiImage: imageGenerate(start))
.interpolation(.none)
.resizable()
.frame(width: 150, height: 150, alignment: .center)
}
func imageGenerate(_ start: Date)-> UIImage {
let str = dateFormatter.string(from: start) // <-- here
let data = str.data(using: .utf8) // <-- here
filter.setValue(data, forKey: "inputMessage")
if let qr = filter.outputImage {
if let qrImage = cont.createCGImage(qr, from: qr.extent){
return UIImage(cgImage: qrImage)
}
}
return UIImage(systemName: "xmark") ?? UIImage()
}
}
EDIT-1:
to put the qr code generation into a function, try this:
struct ContentView: View {
#State var start = Date()
#State var img: UIImage = UIImage() // <-- here
var body: some View {
VStack {
DatePicker("", selection: $start, displayedComponents: [.hourAndMinute])
.datePickerStyle(.wheel)
Button("Show QR code", action: {
img = imageGenerate(start) // <-- here
})
Image(uiImage: img)
.interpolation(.none)
.resizable()
.frame(width: 150, height: 150, alignment: .center)
}
}
func imageGenerate(_ start: Date) -> UIImage {
let filter = CIFilter.qrCodeGenerator()
let cont = CIContext()
let dateFormatter = DateFormatter() // <-- here
dateFormatter.dateFormat = "HH:mm" // <-- here
let str = dateFormatter.string(from: start) // <-- here
let data = str.data(using: .utf8) // <-- here
filter.setValue(data, forKey: "inputMessage")
if let qr = filter.outputImage {
if let qrImage = cont.createCGImage(qr, from: qr.extent){
return UIImage(cgImage: qrImage)
}
}
return UIImage(systemName: "xmark") ?? UIImage()
}
}

ImagePicker in array

I am trying to make a dynamic image selection with the help of an array, but the problem I have is that I select the first position and the photo loads in the first position, but if I select another position, the image always loads in the first position.
I am occupying a single .sheet within the foreach, it is worth mentioning that what I want to achieve is a number of images, not a fixed size
code:
import SwiftUI
struct Research {
var id: Int
var name: String
var date: String
var aux: Int
var imagen1: UIImage
var imagen2: UIImage
var imagen3: UIImage
var imagen4: UIImage
var imagen5: UIImage
var imagen6: UIImage
}
struct ContentView: View {
#State var dataResearch : [Research] = []
#State var aux: Int = 0
#State var showPicker: Bool = false // I imagine that this variable must be unique per element
#State var sourceType: UIImagePickerController.SourceType = .photoLibrary
var body: some View {
VStack{
ForEach($dataResearch, id: \.aux) { $i in
VStack{
Image(uiImage: i.imagen1)
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
.edgesIgnoringSafeArea(.all)
.onTapGesture(){
showPicker = true
}
Image(uiImage: i.imagen2)
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
.edgesIgnoringSafeArea(.all)
.onTapGesture(){
showPicker = true
}
}
.sheet(isPresented: $showPicker) {
ImagePicker(sourceType: sourceType, selectedImage: $i.imagen1)
.ignoresSafeArea()
}
}
}
.onAppear(){
getRequest()
}
}
func getRequest(){
let image1: UIImage = UIImage(named: "default_image")!
let image2: UIImage = UIImage(named: "default_image")!
let image3: UIImage = UIImage(named: "default_image")!
let image4: UIImage = UIImage(named: "default_image")!
let image5: UIImage = UIImage(named: "default_image")!
let image6: UIImage = UIImage(named: "default_image")!
let row = Research(id: 0, name: "", date: "", aux: aux, imagen1: image1, imagen2: image2, imagen3: image3, imagen4: image4, imagen5: image5, imagen6: image6)
dataResearch.append(row)
aux = aux + 1
}
}
IMAGE PICKER
import UIKit
import SwiftUI
struct ImagePicker: UIViewControllerRepresentable {
var sourceType: UIImagePickerController.SourceType = .photoLibrary
#Binding var selectedImage: UIImage
//#Binding var selectedImage: SelectImage
#Environment(\.presentationMode) private var presentationMode
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = false
imagePicker.sourceType = sourceType
imagePicker.delegate = context.coordinator
return imagePicker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var parent: ImagePicker
init(_ parent: ImagePicker) {
self.parent = parent
print("aqui vemos-- ", parent)
print("aqui vemos-- ", parent.selectedImage)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
parent.selectedImage = image
//var row1 = SelectImage(id: 0, uiImage: image ,name:"")
//parent.selectedImage.uiImage = image
}
parent.presentationMode.wrappedValue.dismiss()
}
}
}
This was a little bit complicated because of the structure of Research and the fact that it has so many image fields (that aren't in an array). I'd suggest that it's possible that your model could use a refactor, but since I don't have any information about what the end goal is, I don't know exactly what that would involve yet.
With your current code, you can set a selected item and then set an additional variable that determines which imagen(X) property it should be bound to:
struct ContentView: View {
#State private var dataResearch : [Research] = []
#State private var aux: Int = 0
#State private var pickerItem : Binding<Research>? // the item from ForEach
private enum SelectedImage {
case imagen1, imagen2
}
#State private var selectedImage : SelectedImage? //which image gets selected
var body: some View {
VStack{
ForEach($dataResearch, id: \.aux) { $i in
VStack{
Image(uiImage: i.imagen1)
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
.edgesIgnoringSafeArea(.all)
.onTapGesture(){
pickerItem = $i
selectedImage = .imagen1
}
Image(uiImage: i.imagen2)
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
.edgesIgnoringSafeArea(.all)
.onTapGesture(){
pickerItem = $i
selectedImage = .imagen2
}
}
}
.sheet(item: $pickerItem) { [selectedImage] item in
VStack {
if let selectedImage = selectedImage {
switch selectedImage {
case .imagen1:
ImagePicker(selectedImage: item.imagen1)
case .imagen2:
ImagePicker(selectedImage: item.imagen2)
}
}
}
.ignoresSafeArea()
}
}
.onAppear(){
getRequest()
}
}
func getRequest(){
let image1: UIImage = UIImage(systemName: "pencil")!
let image2: UIImage = UIImage(systemName: "pencil")!
let image3: UIImage = UIImage(systemName: "pencil")!
let image4: UIImage = UIImage(systemName: "pencil")!
let image5: UIImage = UIImage(systemName: "pencil")!
let image6: UIImage = UIImage(systemName: "pencil")!
let row = Research(id: 0, name: "", date: "", aux: aux, imagen1: image1, imagen2: image2, imagen3: image3, imagen4: image4, imagen5: image5, imagen6: image6)
dataResearch.append(row)
aux = aux + 1
}
}

SwiftUI VideoPlayer

Do YouTube URL's not work with SwiftUI's VideoPlayer. I'm attempting to use VideoPlayer(player: AVPlayer(url: URL(string: "https://www.youtube.com/watch?v=ID_HERE")!)). Is there any workarounds to this? Just shows a black screen.
You need to extract the YouTube video ID, try this:
import WebKit
struct WebView: UIViewRepresentable {
let videoID: String
func makeUIView(context: Context) -> WKWebView {
return WKWebView()
}
func updateUIView(_ uiView: WKWebView, context: Context) {
guard let youTubeURL = URL(string:"https://www.youtube.com/embed/\(videoID)") else { return }
uiView.scrollView.isScrollEnabled = false
uiView.load(URLRequest(url: youTubeURL))
}
}
extension String {
func extractYoutubeID() -> String? {
let pattern = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"
let regex = try? NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let range = NSRange(location: 0, length: self.count)
guard let result = regex?.firstMatch(in: self, range: range) else { return nil }
return (self as NSString).substring(with: result.range)
}
}
#State private var youTubeURL: String = "YOUR VIDEO URL"
#State private var youTubeVideoID: String = ""
#State private var validYouTubeURL = false
var body: some View {
VStack {
if validYouTubeURL {
WebView(videoID: self.youTubeVideoID)
.frame(width: 500, height: 500)
}
}.onAppear {
if let videoID = self.youTubeURL.extractYoutubeID() {
self.youTubeURL = ""
self.youTubeVideoID = videoID
self.validYouTubeURL = true
} else {
self.youTubeURL = ""
}
}
}