IOS SwiftUI Reconnect TCP Connection - swift

i create a TCP Server in C and i want a communication between an Iphone and PC.
That work. But when i close the Server or connection lost i must restart the APP on Iphone to make a new connection a simple start() don´t work, the error ist, "Cannot set state changed handler after cancel".
The second problem is, i create two Textfields for IP Adress and Port, how can i give this values to my network class and make new connection?
Thanks for help, here ist my code:
RMTApp.swift
//
// RMTApp.swift
// RMT
//
// Created by Erik on 13.07.21.
//
import SwiftUI
#main
struct RMTApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
ContentView.swift
//
// ContentView.swift
// RMT
//
// Created by Erik on 13.07.21.
//
import SwiftUI
import UserNotifications
class State_button: ObservableObject
{
#Published var strg_value: String = ""
#Published var temp_cnt: Int32 = 0
func requst_notification()
{
}
func test()
{
}
func button_connect()
{
strg_value = "Verbinden..."
}
func button_disconnect()
{
strg_value = ""
}
func counter()
{
temp_cnt = temp_cnt + 1;
}
}
struct ContentView: View {
#State private var IP_ADRESS: String = "192.168.5.1"
#State private var PORT: String = "1234"
#ObservedObject var state_button = State_button()
#StateObject var network = Network(hostName: "192.168.178.28", port: 1234)
#State private var switch_connect = false
#State private var isEditing = false
#State private var textfield: String = "Du bist ein String"
let generator = UINotificationFeedbackGenerator()
var body: some View {
Color.black
.ignoresSafeArea()
.overlay(
VStack()
{
HStack
{
Image("AG")
.resizable()
.scaledToFit()
.frame(width: 32.0, height: 32.0)
Text(" TCP TEST ")
.font(.largeTitle)
.fontWeight(.bold)
.foregroundColor(Color.white)
.multilineTextAlignment(.leading)
.padding()
//.padding(.bottom, 50)
.background(Color.black)
//.border(Color.white, width: 5)
Image("AG")
.resizable()
.scaledToFit()
.frame(width: 32.0, height: 32.0)
}
HStack
{
Group
{
TextField("IP Adress", text: $IP_ADRESS)
{
isEditing in
self.isEditing = isEditing
}
onCommit:
{
print("Eingegeben: \(IP_ADRESS)")
self.generator.notificationOccurred(.success)
}
.autocapitalization(.none)
.disableAutocorrection(true)
.border(Color.white)
.foregroundColor(.white)
.font(Font.system(size: 30, design: .default))
.multilineTextAlignment(.center)
//Text(test)
// .foregroundColor(isEditing ? .red : .blue)
TextField("Port", text: $PORT)
{
isEditing in
self.isEditing = isEditing
}
onCommit:
{
print("Eingegeben: \(PORT)")
self.generator.notificationOccurred(.success)
}
.autocapitalization(.none)
.disableAutocorrection(true)
.border(Color.white)
.foregroundColor(.white)
.font(Font.system(size: 30, design: .default))
.multilineTextAlignment(.center)
//Text(test)
// .foregroundColor(isEditing ? .red : .blue)
}//VSTACK EA field
}//Group
Toggle("Verbinden", isOn: $switch_connect)
.foregroundColor(Color.white)
.toggleStyle(SwitchToggleStyle(tint: network.connection_status ? Color.green : Color.red))
.padding(6)
//.position(x: 180, y: 60)
.border(Color.white, width: 1)
.font(Font.system(size: 30, design: .default))
.onChange(of: switch_connect)
{ value in
self.generator.notificationOccurred(.success)
if switch_connect
{
if network.connection_status == false
{
network.start()
}
}
else { }
//network.start()
}
Text("Empfangen:")
.foregroundColor(Color.white)
.font(Font.system(size: 30, design: .default))
ScrollView()
{
VStack()
{
Text(String(network.textstorage))
.lineLimit(nil)
//printf("Item \($0)")
}
.frame(maxWidth: .infinity)
}
.border(Color.blue)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 200)
.foregroundColor(Color.white)
.background(Color.black)
.font(Font.system(size: 15, design: .default))
.lineLimit(5)
//.multilineTextAlignment(.trailing)
Spacer()
Button(action:{
let vibrate = UIImpactFeedbackGenerator(style: .heavy)
vibrate.impactOccurred()
network.stop()
network.start()
})
{
Text("Test")
.font(.headline)
.fontWeight(/*#START_MENU_TOKEN#*/.bold/*#END_MENU_TOKEN#*/)
.foregroundColor(Color.black
)
}
.padding(10)
.padding(.trailing, 100) //right
.padding(.leading, 100) //left
.multilineTextAlignment(.center)
.cornerRadius(8)
.background(RoundedRectangle(cornerRadius: 8).fill(Color.blue))
HStack
{
Button(action:{
network.cc()
let testx = " DasIstEinTest"
self.network.rec_val_state = false
if network.textstorage.count > 50
{
for _ in 1...testx.count
{
network.textstorage.remove(at: network.textstorage.startIndex)
}
}
network.textstorage = network.textstorage + testx;
let vibrate = UIImpactFeedbackGenerator(style: .heavy)
vibrate.impactOccurred() })
{
Text("Verbinden")
.font(.headline)
.fontWeight(/*#START_MENU_TOKEN#*/.bold/*#END_MENU_TOKEN#*/)
.foregroundColor(Color.black
)
.padding(5)
.multilineTextAlignment(.center)
.cornerRadius(5)
.background(RoundedRectangle(cornerRadius: 8).fill(Color.green))
//.position(x: 60, y: 100)
}
//.buttonStyle(BorderlessButtonStyle());
Button(action:{network.textstorage = "";
self.network.rec_val_state = false;
let vibrate = UIImpactFeedbackGenerator(style: .heavy)
vibrate.impactOccurred()
network.stop()
})
{
Text("Löschen")
.font(.headline)
.fontWeight(/*#START_MENU_TOKEN#*/.bold/*#END_MENU_TOKEN#*/)
.foregroundColor(Color.black
)
} //Button disconnect
.padding(5)
.multilineTextAlignment(.center)
.cornerRadius(5)
.background(RoundedRectangle(cornerRadius: 8).fill(Color.red))
//.position(x: 30, y: 100)
Button(action:{ network.send(line: "Was geht ab??");
let vibrate = UIImpactFeedbackGenerator(style: .heavy)
vibrate.impactOccurred()
})
{
Text("Test")
.font(.headline)
.fontWeight(/*#START_MENU_TOKEN#*/.bold/*#END_MENU_TOKEN#*/)
.foregroundColor(Color.black
)
}
.padding(5)
.padding(.trailing, 35) //right
.padding(.leading, 35) //left
.multilineTextAlignment(.center)
.cornerRadius(0)
.background(RoundedRectangle(cornerRadius: 8).fill(Color.blue))
//.position(x: 30, y: 100)
}//HSTACK
}//VSTACK
)//Color Black
}//body view
}//Struct
struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Network.swift
//
// Network.swift
// RMT
//
// Created by Erik on 15.07.21.
//
import Foundation
import Network
class Network : ObservableObject {
init(hostName: String, port: Int) {
let host = NWEndpoint.Host(hostName)
let port = NWEndpoint.Port("\(port)")!
self.connection = NWConnection(host: host, port: port, using: .tcp)
}
var connection: NWConnection
var rec_val : String = "" //Rec Network Data
var textstorage : String = "" //Saves complete Network Data
let textstorage_max : Int = 250 //Max size of textStorage
#Published var rec_val_state = false //Variable set when Data is aviable to show on view
#Published var connection_status = false //When connect true else false
var IP_ADRESS : String = "192.168.178.28"
func start() {
NSLog("will start")
self.connection.stateUpdateHandler = self.didChange(state:)
self.startReceive()
self.connection.start(queue: .main)
}
func stop() {
self.connection.cancel()
NSLog("did stop")
}
func cc()
{
print("XTREAME")
self.connection = NWConnection(host: NWEndpoint.Host(IP_ADRESS), port: 1234, using: .tcp)
//self.connection.restart()
}
private func didChange(state: NWConnection.State) {
switch state {
case .setup:
break
case .waiting(let error):
NSLog("is waiting: %#", "\(error)")
case .preparing:
break
case .ready:
connection_status = true
break
case .failed(let error):
NSLog("did fail, error: %#", "\(error)")
connection_status = false
self.stop()
case .cancelled:
NSLog("was cancelled")
connection_status = false
self.stop()
#unknown default:
break
}
}
private func startReceive() {
self.connection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { data, _, isDone, error in
if let data = data, !data.isEmpty {
self.rec_val = String(data: data, encoding: .utf8)!
if self.textstorage.count > self.textstorage_max
{
for _ in 1...self.rec_val.count
{
self.textstorage.remove(at: self.textstorage.startIndex)
}
}
self.textstorage = self.textstorage + self.rec_val
self.rec_val_state = true
print(self.rec_val)
}
if let error = error {
NSLog("did receive, error: %#", "\(error)")
self.stop()
return
}
if isDone {
NSLog("did receive, EOF")
self.stop()
return
}
self.startReceive()
}
}
func send(line: String) {
let data = Data("\(line)\r\n".utf8)
self.connection.send(content: data, completion: NWConnection.SendCompletion.contentProcessed { error in
if let error = error {
NSLog("did send, error: %#", "\(error)")
self.stop()
} else {
NSLog("did send, data: %#", data as NSData)
}
})
}
static func run() -> Never {
let m = Network(hostName: "192.168.5.1", port: 1234)
m.start()
let t = DispatchSource.makeTimerSource(queue: .main)
var counter = 20
t.setEventHandler {
m.send(line: "\(counter) bottles of beer on the wall.")
counter -= 1
if counter == 0 {
m.stop()
exit(EXIT_SUCCESS)
}
}
t.schedule(wallDeadline: .now() + 1.0, repeating: 1.0)
t.activate()
dispatchMain()
}
}
Greetings!

Related

Swift: reload view after midnight or when a widget refreshes?

My app uses CoreData to store one quote for each day. There's a widget, the timeline of which is set to update after midnight and fetch the quote for that particular date. This works fine. However, I noticed that when I click on the widget with the new day's quote, the app - which has remained in the background - still shows the previous day's quote. Removing the app from the list of open ones and reopening it shows the correct information.
Is there a way to force a refresh of the DailyQuoteView and make sure that there isn't leftover data?
EDIT: Here's the daily quote struct that I'd like to always show the relevant data when brought from the background.
import SwiftUI
struct DailyQuoteView: View {
#Environment(\.scenePhase) var scenePhase
#State var id: UUID = .init()
#EnvironmentObject var unsplashModel: UnsplashModel
let managedObjectContext = CoreDataStack.shared.managedObjectContext
#FetchRequest(
sortDescriptors: [NSSortDescriptor(key: "date", ascending: true)],
predicate: NSPredicate(
format: "date >= %# AND date <= %#",
argumentArray: [
Calendar.current.startOfDay(for: Date()),
Calendar.current.date(byAdding: .minute, value: 1439, to: Calendar.current.startOfDay(for: Date()))!
]
)
) var quote: FetchedResults<QuoteEntity>
#FetchRequest(
sortDescriptors: [NSSortDescriptor(key: "date", ascending: false)]
) var quotes: FetchedResults<QuoteEntity>
#State var shouldPresentSheet = false
#State var animateCard = false
#Binding var cardOffset: Double
#Binding var coverImageSize: Double
#State var showAboutScreen = false
// MARK: - ELEMENTS
var coverImage: some View {
Image(uiImage: UIImage(data: quote.first?.image ?? Data()) ?? UIImage())
.resizable()
.scaledToFill()
}
var aboutButton: some View {
Button {
showAboutScreen.toggle()
} label: {
Image(systemName: "info")
.foregroundColor(.primary)
.padding(10)
.background(Circle().fill(Color("background")))
.font(.title3)
}
.padding()
.shadow(radius: 5)
}
var titleView: some View {
Text(quote.first?.title ?? "")
.font(.largeTitle)
.multilineTextAlignment(.center)
.bold()
.minimumScaleFactor(0.5)
}
var contentsBox: some View {
ScrollView {
VStack (alignment: .leading, spacing: 10) {
Text(quote.first?.summary ?? "")
.font(.body)
.multilineTextAlignment(.leading)
.padding(.bottom, 20)
if let username = quote.first?.imageUserName {
HStack(spacing: 0) {
Text("Photo: ")
Link(
destination: URL(string: "https://unsplash.com/#\(username)?utm_source=quote_of_the_day&utm_medium=referral")!,
label: {
Text((quote.first?.imageUser)!)
.underline()
})
Text(" on ")
Link(
destination: URL(string: "https://unsplash.com/")!,
label: {
Text("Unsplash")
.underline()
})
Spacer()
}
.font(.caption)
.italic()
.foregroundColor(.gray)
.padding(.vertical, 3)
}
}
.font(.subheadline)
}
}
var buttonRow: some View {
HStack {
Menu(
content: {
Button {
shouldPresentSheet.toggle()
} label: {
Text("as image")
Image(systemName: "photo")
}
ShareLink(item: quote.first!.title, message: Text(quote.first!.summary)) {
Text("as text")
Image(systemName: "text.justify.left")
}
},
label: {
HStack {
Image(systemName: "square.and.arrow.up")
Text("Share")
}
.padding(10)
.background(RoundedRectangle(cornerRadius: 10).fill(Color("whitesand")))
.tint(Color(.secondaryLabel))
}
)
Spacer()
Link(destination: URL(string: quote.first!.link)!) {
Image(systemName: "book")
Text("Read more")
}
.padding(10)
.background(RoundedRectangle(cornerRadius: 10).fill(Color("vpurple")))
.tint(Color(.white))
}
.frame(height: 60)
.sheet(isPresented: $shouldPresentSheet) {
QuoteShare(quote: quote.first!)
}
}
var cardView: some View {
Rectangle()
.fill((Color("background")))
.cornerRadius(50, corners: [.topLeft, .topRight])
.overlay{
VStack{
titleView
.padding(.top, 30)
contentsBox
Spacer()
buttonRow
}
.padding(.horizontal, 20)
.frame(maxWidth: 600)
}
}
// MARK: - BODY
var body: some View {
ZStack{
GeometryReader{ proxy in
coverImage
.ignoresSafeArea()
.frame(width: UIScreen.main.bounds.width, height: proxy.size.height * (animateCard ? 0.30 : 1.0))
.animation(.easeInOut(duration: 1), value: animateCard)
}
GeometryReader { proxy in
aboutButton
.frame(width: 30, height: 30)
.position(x: proxy.frame(in: .global).maxX - 30, y: proxy.frame(in: .global).minY)
}
GeometryReader{ proxy in
VStack(spacing: 0){
Spacer()
cardView
.frame(height: proxy.size.height * 0.8)
.offset(y: animateCard ? 0 : cardOffset)
.animation(.spring().delay(0.2), value: animateCard)
}
}
}
.id(id)
.blur(radius: shouldPresentSheet ? 5.0 : 0.0)
.brightness(shouldPresentSheet ? -0.2 : 0.0)
.animation(.easeIn, value: shouldPresentSheet)
.onAppear {
if !imagesLoaded {
unsplashModel.loadData(imageCount: quotes.count)
imagesLoaded = true
}
animateCard = true
}
.onChange(of: unsplashModel.dailyImageData) { _ in
if unsplashModel.dailyImageData.count == quotes.count {
updateDailyImages()
}
}
.onChange(of: scenePhase, perform: { newValue in
if newValue == .active {
id = .init()
}
})
.task {
NotificationManager.shared.scheduleNotifications(notificationText: quote.first?.title ?? "")
}
}
}
EDIT 2: Code updated with lorem ipsum's suggestion below (.id and onChange of scenePhase). However, this seems to interfere with the card animation in .onAppear { withAnimation { animateCard = true } }

Why the init() is called when the wifi is turned off and on

When I turn the wifi on and off the mainChatView init is called again but not the landingView init. Why?
So when the wifi is toggled in the console it is printed main chat init again
this is the code of the landingView:
struct LandingView: View {
#State private var selection:Int = 2
#State var connected: Bool = true
#State var supposeToBeConnected: Bool = true
#StateObject var networkReachability = NetworkReachability()
var timer = Timer()
init(){
print("landing page init")
}
var body: some View {
if connected {
content
}else{
connectingView()
}
}
var content: some View {
ZStack{
VStack{
TabView(){
MainChatView()
.tabItem {
Image(systemName: "message")
}
HomeView()
.tabItem {
Image(systemName: "house.fill")
}
yourGroups()
.tabItem {
Image(systemName: "rectangle.3.group.fill")
}
AccontView()
.tabItem {
Image(systemName: "person.fill")
}
}
.padding(.all, -2.0)
.onAppear() {
UITabBar.appearance().barTintColor = .black
Auth.auth().addStateDidChangeListener { auth, user in
if let user = user {
if user != nil {
self.connected = true
self.supposeToBeConnected = true
}else{
self.supposeToBeConnected = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
if !supposeToBeConnected{
print("cont changed")
self.connected = false
}
}
}
}
}
OnligneStatus()
Timer.scheduledTimer(withTimeInterval: 60, repeats: true, block: { _ in
OnligneStatus()
})
}
.statusBar(hidden: true)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.edgesIgnoringSafeArea(.all)
}
.frame(maxWidth: .infinity, maxHeight: .infinity,alignment: .top)
.ignoresSafeArea(.all)
.padding(.all, -1.0)
}
}
func OnligneStatus(){
print("online")
let db = Firestore.firestore()
if Auth.auth().currentUser != nil{
db.collection("users").document(Auth.auth().currentUser!.uid).updateData([
"onLine":Date()])
}
}
}
And this is the init:
init(){
print("main chat init")
}
Thanks for helping me this bug caused image loading errors and text loading bugs

How use global Variables in views and classes?

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")
}
}
}
}

iOS | SwiftUI | Undesirable result to exchange items between TimerView and TaskView through ContentView, #State isn't delivering results

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(){
//
//}

SwiftUI Problem GeometryReader with Zstack

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.