I am trying through an external library to obtain the temperature of a device,
when the screen starts the temperature value is "----" when the device gives me the temperature result through a delegate I want to update the view with the value that is to save in the class (ts28bControllerDelegate) the value of the temperature and retrieve it in the view to show it, as I have my code always remains blank (Text ("\ (global.temp)"))
//
// TakeTemperatureTS28BUIView.swift
// aidicarev3UI
//
// Created by Laura Ramirez on 26/08/21.
//
import SwiftUI
struct ContentView2: View {
#State private var index = 1
#EnvironmentObject private var global: GlobalTs28b
init() {
Theme.navigationBarColors(background: .white , titleColor: UIColor( red: CGFloat(92/255.0), green: CGFloat(203/255.0), blue: CGFloat(207/255.0), alpha: CGFloat(1.0)))
}
var body: some View {
VStack{
ScrollView{
VStack{
VStack(){
Image("bluetooth-5")
.resizable()
.frame(width: UIScreen.main.bounds.width / 2, height: 140.0)
.padding()
Text("temp15Tittle")
.modifier(Fonts(fontName: .bold, size: 16))
.foregroundColor(Color("blueColor"))
.fixedSize(horizontal: false, vertical: true)
.padding(.top,30)
}
Divider()
.padding()
Text("temp1Tittle")
.frame(maxWidth: .infinity, alignment: .center)
.modifier(Fonts(fontName: .bold, size: 16))
.foregroundColor(Color("blackColor"))
.fixedSize(horizontal: false, vertical: true)
.padding(.top,10)
.padding()
HStack{
Text("\(global.temp)")
.autocapitalization(.none)
.foregroundColor(Color("blackColor"))
.padding(.leading,20)
Text("°C")
.modifier(Fonts(fontName: .bold, size: 16))
.foregroundColor(Color("blackColor"))
.padding()
}
.foregroundColor(Color("blackColor"))
.overlay(RoundedRectangle(cornerRadius: 40).stroke(Color("grayColor"), lineWidth: 1)).background(RoundedRectangle(cornerRadius: 40).fill(Color("whiteColor")))
.padding(.trailing,60)
.padding(.leading,60)
Button(action:{
SaveTemp()
}){
HStack{
Text("temp16Tittle")
.foregroundColor(Color("whiteColor"))
.modifier(Fonts(fontName: .bold, size: 16))
.frame(width: 150 , height: 10, alignment: .center)
}
.foregroundColor(Color("whiteColor"))
.modifier(Fonts(fontName: .medium, size: 16))
.padding()
.background(Color("blueColor"))
.cornerRadius(80)
.padding(.top,30)
}
}
}
.padding()
.padding()
Spacer()
MenuMain(index: self.$index)
}
.background(Color("backgroundColor"))
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .principal) {
VStack {
Text("temp7Tittle").font(.headline)
.modifier(Fonts(fontName: .light, size: 18))
.foregroundColor(Color("grayDarkColor"))
.fixedSize(horizontal: false, vertical: true)
.frame(maxWidth: .infinity, alignment: .leading)
}
}
}
.onAppear {
iHealthAuthTS28B()
}
.onDisappear {
//desconectar dispositivos
}
}
}
struct TakeTemperatureTS28BUIView_Previews: PreviewProvider {
static var previews: some View {
NavigationView{
TakeTemperatureTS28BUIView()
.navigationBarTitleDisplayMode(.inline)
.accentColor(.black)
.toolbar { // <2>
ToolbarItem(placement: .principal) { // <3>
HStack {
Text("temp7Tittle").font(.headline)
.modifier(Fonts(fontName: .light, size: 18))
.foregroundColor(Color("grayDarkColor"))
.fixedSize(horizontal: false, vertical: true)
.frame(maxWidth: .infinity, alignment: .leading)
Spacer()
}
}
}
}
}
}
struct TakeTemperatureTS28BUIView: View {
#StateObject private var global = GlobalTs28b()
var body: some View {
ContentView2()
.environmentObject(global)
}
}
func iHealthAuthTS28B() {
print("ENTRA EN AUTENTIFICACION DE IHEALTH TS28B")
let bundle = Bundle.main
let path = bundle.path(forResource: "com_aidicare_aidicarev3UI_ios", ofType: ".pem")
let cert = NSData(contentsOfFile: path!)
print(cert as Any)
let delegate = ts28bControllerDelegate.init()
IHSDKCloudUser.commandGetSDKUserInstance().commandSDKUserValidation(withLicense: cert as Data?, userDeviceAccess: {
devices in
print("--devices--")
print(devices as Any)
}, userValidationSuccess: { UserAuthenResult in
print("--UserAuthenResult--")
print(UserAuthenResult)
delegate.StartSync()
}, disposeErrorBlock: { UserAuthenResult in
print("--UserAuthenResult--")
print(UserAuthenResult)
switch (UserAuthenResult) {
case UserAuthen_InputError:
print("error")
break;
case UserAuthen_CertificateExpired:
print("certiificado expirado")
break;
case UserAuthen_InvalidCertificate:
print("certificado no valido")
break;
default:
break;
}
})
}
func Sincroniza(){
print("ENTRA EN TOMA DE TEMPERATURA TS28B")
iHealthAuthTS28B()
}
func SaveTemp(){
print("ENTRA EN GUARDAR DE TEMPERATURA")
let global = GlobalTs28b()
print("VALOR: ", global.temp)
}
class GlobalTs28b: ObservableObject {
#Published var temp: String = "----"
#Published var state: String = "----"
}
class ts28bControllerDelegate: NSObject, TS28BControllerDelegate {
var myCentralManager: CBCentralManager = CBCentralManager()
var controllerTS28B: TS28BController = TS28BController()
let user: HealthUser = HealthUser()
var device: TS28B = TS28B()
var connectedDevice: TS28B?
var global = GlobalTs28b()
override init() {
super.init()
print("ENTRA EN StartDiscoverTS28B")
controllerTS28B = TS28BController.shared()
controllerTS28B.delegate = self
}
func StartSync(){
print("empieza StartSync")
controllerTS28B.startScan()
}
// MARK: - delegate
public func controller(_ controller: TS28BController?, didDiscoverDevice device: TS28B?) {
print("The agent of the device is found")
connectedDevice = device
controller?.connectDevice(connectedDevice)
if let device = device {
print("DiscoverDevice: \(device)")
}
}
public func controller(_ controller: TS28BController?, didConnectSuccessDevice device: TS28B?) {
print("Successfully connected agent")
connectedDevice = device
if let device = device {
print("DiscoverDevice: \(device)")
}
}
public func controller(_ controller: TS28BController?, didConnectFailDevice device: TS28B?) {
print("Proxy failed to connect")
// self.recordTextView.text = #"连接失败";
}
public func controller(_ controller: TS28BController?, didDisconnectDevice device: TS28B?) {
print("Disconnected proxy")
// self.recordTextView.text = #"连接断开";
if let device = device {
print("DisConnectDevice: \(device) ")
}
}
public func controller(_ controller: TS28BController?, device: TS28B?, didUpdateTemperature value: Float, temperatureUnit unit: TemperatureUnit, measure date: Date?, measureLocation type: TemperatureType) {
print("Temperature UNIDAD:", unit)
print("Temperature:", value)
let valueFinal = ((value - 32) * 5/9)
let stringFloat = String(describing: valueFinal)
global.temp = stringFloat
print("centigadros:", global.temp)
}
}
can someone help me understand this?
thanks!
Regarding your (second) question in your comment,
here is some code that shows an approach to "send" a value from a
class (does not have to be a view) and receive that value in a View.
You could use this approach in your "ts28bControllerDelegate",
to send the temperature updates as they arrive in your ts28bControllerDelegate and
receive them in your views using .onReceive(...)
public func controller(_ controller: TS28BController?, device: TS28B?, didUpdateTemperature value: Float, temperatureUnit unit: TemperatureUnit, measure date: Date?, measureLocation type: TemperatureType) {
print("Temperature UNIDAD:", unit)
print("Temperature:", value)
let valueFinal = ((value - 32) * 5/9)
let stringFloat = String(valueFinal)
// send a message with the temp value
NotificationCenter.default.post(name: GlobalTs28b.globalMsg, object: stringFloat)
}
class GlobalTs28b: ObservableObject {
#Published var temp: String = "----"
#Published var state: String = "----"
// for testing, does not have to be in this class
static let globalMsg = Notification.Name("GlobalTs28b")
}
struct ContentView: View {
#StateObject var global = GlobalTs28b() // for testing
var body: some View {
NavigationView {
VStack (spacing: 55) {
NavigationLink("go to next view", destination: ViewTest2())
Text(global.temp).foregroundColor(.red)
}
.onReceive(NotificationCenter.default.publisher(for: GlobalTs28b.globalMsg)) { msg in
if let temp = msg.object as? String {
// update the StateObject with the new info, so the view will update
global.temp = temp
}
}
}.navigationViewStyle(.stack)
}
}
struct ViewTest2: View {
var body: some View {
VStack {
Button(action: {
// send a message to all listeners with the new temp,
// could be used in any class such as ts28bControllerDelegate
NotificationCenter.default.post(name: GlobalTs28b.globalMsg, object: "new temp")
}) {
Text("click to update temp")
}
}
}
}
I have three Views exchanging information, ContentView, TimerView and TaskView. I used #Binding in TaskView to bring data from TaskView to ContentView, now I want to use that data to pass into TimerView.
I created a #State variable in ContentView to store the data from TaskView, but when I try to use that #State variable to pass data to TimerView it isn't giving me any desirable results.
Now if you see the TasksView call in ContentView, I get the output for the print statement, but in the main TimerView, it doesn't change from the default I set as #State variable in timerInfo.
Any help is appreciated, thank you.
Code for ContentView ->
//
// ContentView.swift
// ProDActivity
//
// Created by Vivek Pattanaik on 5/27/21.
//
import SwiftUI
struct TimerInfo : Identifiable {
let id = UUID()
// let taskIndex : Int
// let taskProjectName : String
var timerTaskName : String
var timerMinutes : Float
let timerIntervals : Int
var timerPriority : String
var timerShortbreakMinute : Float
var timerLongbreakMinute : Float
var timerLongbreakInterval : Int
}
struct ContentView: View {
init() {
UITabBar.appearance().backgroundColor = UIColor.init(Color("TabBar "))
}
// #State var selection: Tab = .dasboard
#State var timerInfo = TimerInfo(timerTaskName: "Sample Task 1", timerMinutes: 30, timerIntervals: 10, timerPriority: "High Priority", timerShortbreakMinute: 5, timerLongbreakMinute: 15, timerLongbreakInterval: 3)
var body: some View {
TabView {
TimerView(defaultTimeRemaining: self.timerInfo.timerMinutes * 60, timeRemaining: self.timerInfo.timerMinutes * 60)
.tabItem {
Image(systemName: "clock.fill")
Text("Timer")
}.tag(0)
TasksView(didClickTimer: { info in
self.timerInfo.timerTaskName = info.timerTaskName
self.timerInfo.timerMinutes = info.timerMinutes
self.timerInfo.timerPriority = info.timerPriority
self.timerInfo.timerShortbreakMinute = info.timerShortbreakMinute
self.timerInfo.timerLongbreakMinute = info.timerLongbreakMinute
self.timerInfo.timerLongbreakInterval = info.timerLongbreakInterval
print("\(self.timerInfo.timerMinutes)ContentView")
})
.tabItem {
Image(systemName: "doc.plaintext.fill")
Text("Tasks")
}.tag(1)
StatisticsView()
.tabItem {
Image(systemName: "chart.pie.fill")
Text("Statistics")
}.tag(3)
SettingsView()
.tabItem {
Image(systemName: "gearshape.fill")
Text("Settings")
}.tag(4)
}
.font(.headline)
.accentColor(Color("AccentColor"))
.environment(\.colorScheme, .dark)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Code for TasksView ->
//
// TasksView.swift
// ProDActivity
//
// Created by Vivek Pattanaik on 5/30/21.
//
import SwiftUI
struct TaskLabels : Identifiable {
let id = UUID()
// let taskIndex : Int
// let taskProjectName : String
let taskName : String
let taskPriority : String
let taskIntervals : String
let taskMinutes : String
let shortBreakMinutes : String
let longBreakMinutes : String
let longBreakIntervals : String
}
struct TaskRow: View {
let tasks : TaskLabels
var body: some View {
HStack(alignment: .center, spacing: 10) {
Image(tasks.taskPriority)
.frame(width: 40, height: 40, alignment: .center)
VStack(alignment: .leading, spacing:4){
Text(tasks.taskName)
.font(.system(size: 15))
Text("\(tasks.shortBreakMinutes) Min Breaks")
.font(.system(size: 13))
}
.frame(width: 100, height: 20, alignment: .leading)
Spacer()
VStack(alignment: .trailing, spacing:4){
Text("0/\(tasks.taskIntervals)")
Text("\(tasks.taskMinutes) Min Tasks")
.font(.system(size: 13))
}
.frame(width: 90, height: 20, alignment: .trailing)
.padding()
}
}
}
struct TasksView: View {
// #Binding var timeSelected : Float
#State var addTasksModalView: Bool = false
#State var taskLabels : [TaskLabels] = []
var didClickTimer : (TimerInfo) -> ()
var body: some View {
NavigationView{
if taskLabels.count != 0 {
List{
ForEach(taskLabels) { task in
HStack {
Button(action: {
self.didClickTimer(.init(timerTaskName: task.taskName, timerMinutes: Float(task.taskMinutes)!, timerIntervals: Int(task.taskIntervals)!, timerPriority: task.taskPriority, timerShortbreakMinute: Float(task.shortBreakMinutes)!, timerLongbreakMinute: Float(task.longBreakMinutes)!, timerLongbreakInterval: Int(task.longBreakIntervals)!))
print(task.taskMinutes)
}, label: {
TaskRow(tasks: task)
})
}
}
.onDelete(perform: self.deleteRow)
}
.navigationBarTitle("Tasks")
.navigationBarItems(trailing: Button(action: {
self.addTasksModalView = true
}, label: {
Image(systemName: "plus.square.on.square")
.resizable()
.frame(width: 26, height: 26, alignment: .leading)
.foregroundColor(Color.accentColor)
}))
.sheet(isPresented: $addTasksModalView, content: {
AddTasks(addTaskPresented: $addTasksModalView) { tasks in
taskLabels.append(tasks)
}
})
} else {
Text("")
.navigationTitle("Tasks")
.navigationBarTitle("Tasks")
.navigationBarItems(trailing: Button(action: {
self.addTasksModalView = true
}, label: {
Image(systemName: "plus.square.on.square")
.resizable()
.frame(width: 26, height: 26, alignment: .leading)
.foregroundColor(Color.accentColor)
}))
.sheet(isPresented: $addTasksModalView, content: {
AddTasks(addTaskPresented: $addTasksModalView) { tasks in
taskLabels.append(tasks)
}
})
}
}
.environment(\.colorScheme, .dark)
}
private func deleteRow(at indexSet: IndexSet){
self.taskLabels.remove(atOffsets: indexSet)
}
}
//struct TasksView_Previews: PreviewProvider {
// static var previews: some View {
// TasksView()
// }
//}
TimerView Code ->
//
// TimerView.swift
// ProDActivity
//
// Created by Vivek Pattanaik on 5/27/21.
//
import SwiftUI
struct TimerView: View {
let lineWidth : CGFloat = 11
let radius : CGFloat = 150
// to pass into the struct
// #State var taskTime = 300
#State var defaultTimeRemaining : Float
#State var timeRemaining : Float
#State private var isActive = false
#State private var showButtons = false
#State private var stopAlert = false
#State private var pausePressed = false
#State private var stopPressed = false
// #State private var timeRemainingSeconds : CGFloat = 25
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
// self.defaultTimeRemaining = timerInfo.timerMinutes
VStack(spacing : 60) {
ZStack{
RoundedRectangle(cornerRadius: 7)
.frame(width: 300, height: 70)
.foregroundColor(Color("TabBar "))
}
ZStack(alignment: Alignment(horizontal: .center, vertical: .center)) {
Circle()
.stroke(Color.gray, style: StrokeStyle(lineWidth: lineWidth, lineCap: .round))
.opacity(0.2)
Circle()
.trim(from: 1 - CGFloat(((defaultTimeRemaining-timeRemaining)/defaultTimeRemaining)), to: 1 )
.stroke(Color.accentColor, style: StrokeStyle(lineWidth: lineWidth, lineCap: .round))
.rotationEffect( .degrees(-90))
.animation(.easeInOut)
// VStack for the timer and seesions
VStack {
// Text("\(Int(timeRemaining)):\(Int(timeRemainingSeconds))")
Text("\(timeString(time: Int(timeRemaining)))")
.font(.system(size: 50)).fontWeight(.medium)
Text("0 of 5 Sessions")
.font(.system(size: 20)).fontWeight(.medium)
}
}.frame(width: radius*2, height: radius*2)
// BEGIN, STOP, PAUSE BUTTONS
HStack(spacing: 25){
if showButtons == false {
Button(action: {
}, label: {
ZStack {
Rectangle()
.frame(width: 176, height: 55, alignment: .center)
.foregroundColor(Color.accentColor)
.cornerRadius(5)
Button(action: {
self.showButtons.toggle()
isActive.toggle()
}, label: {
Text("BEGIN")
.foregroundColor(Color.white)
.font(.system(size: 23).weight(.medium))
.frame(width: 176, height: 55, alignment: .center)
})
}
})
} else if showButtons == true {
HStack {
ZStack {
Rectangle()
.frame(width: 152, height: 55, alignment: .center)
.foregroundColor(Color("LightDark"))
.cornerRadius(5)
.border(Color.accentColor, width: 2)
Button(action: {
self.stopPressed.toggle()
self.pausePressed = true
if isActive == true {
isActive.toggle()
self.stopAlert = true
} else {
self.stopAlert = true
}
}, label: {
Text("STOP")
.foregroundColor(Color.accentColor)
.font(.system(size: 23).weight(.medium))
.frame(width: 152, height: 55, alignment: .center)
})
.alert(isPresented: $stopAlert) {
Alert(title: Text("Are you sure you want to stop?"),
message: Text("This will stop the timer and task associated with it."),
primaryButton: .destructive(Text("Yes"), action: {
self.showButtons = false
timeRemaining = defaultTimeRemaining
}),
secondaryButton: .cancel({
isActive = false
pausePressed = true
})
)
}
}
ZStack {
Rectangle()
.frame(width: 152, height: 55, alignment: .center)
.foregroundColor(pausePressed ? Color.accentColor : Color("LightDark"))
.cornerRadius(5)
.border(pausePressed ? Color.accentColor : Color.accentColor, width: 2)
Button(action: {
pausePressed.toggle()
if pausePressed == true {
isActive = false
} else {
isActive = true
}
}, label: {
Text("\(pausePressed ? "RESUME" : "PAUSE")")
.foregroundColor(pausePressed ? Color("TabBar ") : Color.accentColor)
.font(.system(size: 23).weight(.medium))
.frame(width: 152, height: 55, alignment: .center)
})
}
}
}
}
}.onReceive(timer, perform: { _ in
guard isActive else {return}
if timeRemaining > 0 {
timeRemaining -= 1
} else {
isActive = false
showButtons = false
self.timer.upstream.connect().cancel()
}
})
}
func timeString(time: Int) -> String {
let minutes = Int(time) / 60 % 60
let seconds = Int(time) % 60
return String(format:"%02i:%02i", minutes, seconds)
}
}
//struct TimerView_Previews: PreviewProvider {
// static var previews: some View {
// TimerView()
// }
//}
//func buttonChange(){
//
//}
I'm trying to create my own PhoneTextField in and I have found a tutorial in here it's working fine if don't call it inside ZStack let's see the code example as below
countryCode View
struct CountryCodes: View {
#Binding var countryCode : String
#Binding var countryFlag : String
#Binding var y : CGFloat
var body: some View {
GeometryReader { geo in
List(self.countryDictionary.sorted(by: <), id: \.key) { key , value in
HStack {
Text("\(self.flag(country: key))")
Text("\(self.countryName(countryCode: key) ?? key)")
Spacer()
Text("+\(value)").foregroundColor(.secondary)
}.background(Color.white)
.font(.system(size: 20))
.onTapGesture {
self.countryCode = value
self.countryFlag = self.flag(country: key)
withAnimation(.spring()) {
self.y = 350
}
}
}
.padding(.bottom)
.frame(width: geo.size.width, height: 500)
.position(x: geo.frame(in: .global).midX, y: geo.frame(in: .global).maxY - -200)
}
}
let countryDictionary = ["AF":"93","AL":"355","DZ":"213","US":"1",
"AD":"376","AO":"244","AI":"1","AG":"1","AR":"54",
"AM":"374","AW":"297","AU":"61","AT":"43","AZ":"994",
"BS":"1","BH":"973","BD":"880","BB":"1","BY":"375",
"BE":"32","BZ":"501","BJ":"229","BM":"1","BT":"975",
"BA":"387","BW":"267","BR":"55","IO":"246","BG":"359",
"BF":"226","BI":"257","KH":"855","CM":"237","CA":"1",
"CV":"238","KY":"345","CF":"236","TD":"235","CL":"56","CN":"86",
"CX":"61","CO":"57","KM":"269","CG":"242","CK":"682","CR":"506",
"HR":"385","CU":"53","CY":"537","CZ":"420","DK":"45","DJ":"253",
"DM":"1","DO":"1","EC":"593","EG":"20","SV":"503","GQ":"240",
"ER":"291","EE":"372","ET":"251","FO":"298","FJ":"679","FI":"358",
"FR":"33","GF":"594","PF":"689","GA":"241","GM":"220","GE":"995",
"DE":"49","GH":"233","GI":"350","GR":"30","GL":"299","GD":"1",
"GP":"590","GU":"1","GT":"502","GN":"224","GW":"245","GY":"595","HT":"509",
"HN":"504","HU":"36","IS":"354","IN":"91","ID":"62","IQ":"964",
"IE":"353","IL":"972","IT":"39","JM":"1","JP":"81","JO":"962",
"KZ":"77","KE":"254","KI":"686","KW":"965","KG":"996","LV":"371",
"LB":"961","LS":"266","LR":"231","LI":"423","LT":"370","LU":"352",
"MG":"261","MW":"265","MY":"60","MV":"960","ML":"223",
"MT":"356","MH":"692","MQ":"596","MR":"222","MU":"230","YT":"262",
"MX":"52","MC":"377","MN":"976", "ME":"382","MS":"1","MA":"212",
"MM":"95","NA":"264","NR":"674","NP":"977","NL":"31","NC":"687",
"NZ":"64","NI":"505","NE":"227","NG":"234","NU":"683",
"NF":"672","MP":"1","NO":"47","OM":"968","PK":"92","PW":"680",
"PA":"507","PG":"675","PY":"595","PE":"51","PH":"63","PL":"48",
"PT":"351","PR":"1","QA":"974","RO":"40","RW":"250","WS":"685",
"SM":"378","SA":"966","SN":"221","RS":"381","SC":"248",
"SL":"232","SG":"65","SK":"421","SI":"386","SB":"677",
"ZA":"27","GS":"500","ES":"34","LK":"94","SD":"249","SR":"597",
"SZ":"268","SE":"46","CH":"41","TJ":"992","TH":"66","TG":"228",
"TK":"690","TO":"676","TT":"1","TN":"216","TR":"90",
"TM":"993","TC":"1","TV":"688","UG":"256","UA":"380",
"AE":"971","GB":"44","AS":"1","UY":"598","UZ":"998",
"VU":"678","WF":"681","YE":"967","ZM":"260",
"ZW":"263","BO":"591","BN":"673","CC":"61",
"CD":"243","CI":"225","FK":"500","GG":"44",
"VA":"379","HK":"852","IR":"98","IM":"44",
"JE":"44","KP":"850","KR":"82","LA":"856",
"LY":"218","MO":"853","MK":"389","FM":"691",
"MD":"373","MZ":"258","PS":"970","PN":"872",
"RE":"262","RU":"7","BL":"590","SH":"290","KN":"1",
"LC":"1","MF":"590","PM":"508","VC":"1","ST":"239",
"SO":"252","SJ":"47","SY":"963","TW":"886","TZ":"255",
"TL":"670","VE":"58","VN":"84","VG":"284","VI":"340"]
func countryName(countryCode: String) -> String? {
let current = Locale(identifier: "en_US")
return current.localizedString(forRegionCode: countryCode)
}
func flag(country:String) -> String {
let base : UInt32 = 127397
var flag = ""
for v in country.unicodeScalars {
flag.unicodeScalars.append(UnicodeScalar(base + v.value)!)
}
return flag
}
}
RegistrationView
//
// RegisterView.swift
// Instagram
//
// Created by Admin on 4/4/21.
//
import SwiftUI
import Combine
struct RegistrationView: View {
#State var isEditing: Bool = false
// navigate to verification view
#State private var selection: String? = nil
#State private var email:String = ""
#State private var phone:String = ""
#State private var fullname = ""
#State private var username = ""
#State private var password = ""
#State private var selectedImage:UIImage?
#State private var image:Image?
#Environment(\.presentationMode) var mode
#State var imagePickerPresented = false
#EnvironmentObject var viewModel: AuthViewModel
#State var isVerification = false
#State var phoneNumber = ""
#State var y : CGFloat = 350
#State var countryCode = ""
#State var countryFlag = ""
#State var isInputPhoneNumber = true
#State var isInputEmail = false
#State var tempData = DataTempo()
#State var isShowSignInButton = true
// var successClosure: (Bool) -> Void {
//
// }
#EnvironmentObject var mobileVerificationViewModel: MobileVerificationNvm
var body: some View {
ZStack {
LinearGradient(gradient: Gradient(colors: [Color.purple, Color("PrimaryColor")]), startPoint: .top, endPoint: .bottom)
.ignoresSafeArea()
VStack{
// Spacer()
VStack(spacing:20){
VStack(alignment:.leading){
Text("Sign Up")
.font(.largeTitle)
.bold()
.foregroundColor(.white)
}.padding(.horizontal,32).frame(width: UIScreen.main.bounds.width, alignment: .leading)
Toggle( isInputEmail ? "Use Email" : "Use Phone Number", isOn: $isInputEmail)
.foregroundColor(.white)
.toggleStyle(SwitchToggleStyle(tint: Color(#colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1))))
.padding(.horizontal,32)
if isInputEmail == true {
CustomTextField(text: $email, placeholder: Text("Email"), imageName: "envelope")
.padding()
.background(Color(.init(white: 1, alpha: 0.15)))
.cornerRadius(10)
.foregroundColor(.white)
.padding(.horizontal,32)
.onChange(of: email) {
// self.autocomplete($0) // like this
if viewModel.isValidEmail(testStr: $0){
print("email")
//phone number
}
}
}
if isInputEmail == false{
ZStack(alignment:.center) {
HStack (spacing: 0) {
Text(countryCode.isEmpty ? "🇹🇭 +66" : "\(countryFlag) +\(countryCode)")
.frame(width: 100, height: 50)
// .background(Color.secondary.opacity(0.2))
.background(Color(.init(white: 1, alpha: 0.15)))
.cornerRadius(10)
// .foregroundColor(countryCode.isEmpty ? .secondary : .black)
.foregroundColor(.white)
.onTapGesture {
isShowSignInButton = false
withAnimation (.spring()) {
self.y = 0
}
}
TextField("Phone Number", text: $phone)
.onChange(of: phone) { newValue in
if !phone.isEmpty {
self.isShowSignInButton = true
if viewModel.validatePhoneNumber(value:newValue){
print("phone")
//phone number
self.isInputPhoneNumber = true
self.isInputEmail = false
}
}
else{
self.isShowSignInButton = false
}
}
.frame(width: 250, height: 50)
.keyboardType(.phonePad)
.background(Color(.init(white: 1, alpha: 0.15)))
.foregroundColor(.white)
}
CountryCodes(countryCode: $countryCode, countryFlag: $countryFlag, y: $y)
.offset(y: y)
RoundedRectangle(cornerRadius: 10).stroke()
.frame(width: 350, height: 50)
.foregroundColor(.white)
} .zIndex(1).frame( height: 50, alignment: .center)
}
CustomTextField(text: $username, placeholder: Text("Username"), imageName: "person")
.padding()
.background(Color(.init(white: 1, alpha: 0.15)))
.cornerRadius(10)
.foregroundColor(.white)
.padding(.horizontal,32)
CustomTextField(text: $fullname, placeholder: Text("Full Name"), imageName: "person")
.padding()
.background(Color(.init(white: 1, alpha: 0.15)))
.cornerRadius(10)
.foregroundColor(.white)
.padding(.horizontal,32)
CustomSecureField(text: $password, placeholder: Text("Password"))
.padding()
.background(Color(.init(white: 1, alpha: 0.15)))
.cornerRadius(10)
.foregroundColor(.white)
.padding(.horizontal,32)
}
.alert(isPresented: $isInputPhoneNumber, content: {
Alert(title: Text("Message"), message: Text("you're using phone number to register"), dismissButton: .default(Text("Bye alert!"), action: {
isInputPhoneNumber = true
}))
})
.alert(isPresented: mobileVerificationViewModel.alertBinding) {
Alert(title: Text(mobileVerificationViewModel.errorMessage ?? "(unknown)"), message: nil, dismissButton: .cancel())
}
HStack{
Spacer()
Button(action: /*#START_MENU_TOKEN#*/{}/*#END_MENU_TOKEN#*/, label: {
Text("Forgot Password")
})
.font(.system(size: 13, weight: .semibold))
.foregroundColor(.white)
.padding(.top)
.padding(.trailing,28)
}
ZStack{
NavigationLink(destination:VerificationView { (pin, successClosure) in
print(pin)
mobileVerificationViewModel.codeVerification(phoneNumber: isInputEmail ? tempData.email : tempData.phone, pinCode: pin, email: email, password: password, fullname: fullname, username: username)
//navigation back
self.mode.wrappedValue.dismiss()
// print(successClosure)
}, tag: "verification", selection: $selection) { EmptyView() }
Button(action: {
self.selection = "verification"
var phoneWithCountryCode = ""
// if countryCode == "" {
// phoneWithCountryCode = "+66\(phone)"
// }
// if countryCode != ""{
// phoneWithCountryCode = "+\(countryCode)\(phone)"
// }
//
// // "+\(countryCode == "" ? "66" : countryCode + phone)"
// if (!email.isEmpty || !phone.isEmpty) && !password.isEmpty{
//
// if isInputEmail {
// MobileVerificationNvm.shared.sendVerification(phoneNumber:email)
// isVerification = true
// tempData.email = email
// }
//
// else{
// DispatchQueue.main.async {
// // print("phone:\(phoneWithCountryCode)")
// MobileVerificationNvm.shared.sendVerification(phoneNumber: phoneWithCountryCode)
// isVerification = true
// tempData.phone = phone
// }
//
// }
//
// }
// viewModel.register(withEmail: email, password: password,image: selectedImage,fullname: fullname,username: username)
}, label: {
Text("Sign Up")
}).zIndex(0)
// Spacer()
}
.font(.headline)
.frame(width: 360, height: 50)
.foregroundColor(.white)
.background(Color(#colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1)))
// .clipShape(Capsule())
.clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous))
.padding()
.alert(isPresented: $isInputEmail, content: {
Alert(title: Text("Message"), message: Text("Now! you're using Email to register but you also register with email just swtich on togle button"), dismissButton: .default(Text("Bye alert!"), action: {
isInputEmail = true
}))
})
Button(action: {
mode.wrappedValue.dismiss()
// isVerification = true
}, label: {
Text("Already have an account? ")
.font(.system(size: 14))
+ Text("Sign In")
.font(.system(size: 14, weight: .bold))
})
.foregroundColor(.white)
.padding(.bottom,32)
}
}
.ignoresSafeArea()
}
}
extension RegistrationView{
func loadImage() {
guard let selectedImage = selectedImage else {
return
}
image = Image(uiImage: selectedImage)
}
}
//
struct RegistrationView_Previews: PreviewProvider {
static var previews: some View {
RegistrationView()
}
}
this is my issue when I tap on country code to choose the country code you will see the button sign in over countries code list
you also can check from [here]:github.com/PhanithNoch/SwiftUIPhoneTextField this is the repo that I tried to separate code from my real project as an example
I stuck with this a few days ago hope anyone can help, please.