The keyboard of a TextField doesn't show when I tap it in SwiftUI - keyboard

The keyboard of a TextField doesn't show when I tap it on a physical device and I don't know why, here is my code:
VStack {
HStack {
Image(colorScheme == .light ? "user" : "userDark")
.resizable()
.frame(width: 30, height: 30)
Text(localName)
.font(.system(size: 20))
Spacer()
}.padding(.horizontal)
ZStack {
HStack {
TextField("Change name", text: $name)
.textFieldStyle(PlainTextFieldStyle())
.padding(.leading, 5)
.font(.system(size: 20))
.autocapitalization(.none)
.disableAutocorrection(true)
.zIndex(1)
if self.name != "" {
Spacer()
Button(action: {
// update name
})
{
Text("Update")
.padding()
}.padding()
}
}.padding(.horizontal)
}
}
Thank you in advance!

Related

Aligning Text within ZStack based on rotation in SwiftUI

I'm having some trouble aligning Text inside a ZStack...more specifically, if I rotate the device after I started the app...
I want the Text to be aligned to the top leading of the View, but below you can see images of what's happening...
If I open the app with the device in portrait, the alignment is correct...
Alignment with app started in portrait
...but if I rotate the device to landscape, the text moves to the top center...
Alignment after rotation to landscape
Same thing if I start the app with the device in landscape, all aligned correctly...
Alignment with app started in landscape
...but if I rotate the device to portrait, the text almost disappear completely...
Alignment after rotation to portrait
This is the code for the ContentView:
import SwiftUI
let furl = URL(fileURLWithPath: "path")
struct ContentView: View {
#State private var selected = 0
var body: some View {
TabView(selection: $selected) {
NavigationView {
HomeView()
}
.navigationViewStyle(StackNavigationViewStyle())
.tabItem {
Image(systemName: (selected == 0 ? "house.fill" : "house"))
Text("Home")
}.tag(0)
NavigationView {
CategoryView(dm: DownloadManager())
}
.navigationViewStyle(DoubleColumnNavigationViewStyle())
.tabItem {
Image(systemName: (selected == 1 ? "text.justify" : "text.justify"))
Text("Categorie")
}.tag(1)
NavigationView {
GalleryView(dm: DownloadManager())
}
.navigationViewStyle(DoubleColumnNavigationViewStyle())
.tabItem {
Image(systemName: (selected == 2 ? "photo.fill" : "photo"))
Text("Galleria")
}.tag(2)
NavigationView {
FavoritesView()
}
.navigationViewStyle(DoubleColumnNavigationViewStyle())
.tabItem {
Image(systemName: (selected == 3 ? "star.fill" : "star"))
Text("Preferiti")
}.tag(3)
NavigationView {
InfoView()
}
.navigationViewStyle(StackNavigationViewStyle())
.tabItem {
Image(systemName: (selected == 4 ? "info.circle.fill" : "info.circle"))
Text("Informazioni")
}.tag(4)
}
.accentColor(.white)
.onAppear() {
UINavigationBar.appearance().barTintColor = UIColor(red: 112.0/255.0, green: 90.0/255.0, blue: 143.0/255.0, alpha: 1.0)
UITabBar.appearance().barTintColor = UIColor(red: 112.0/255.0, green: 90.0/255.0, blue: 143.0/255.0, alpha: 1.0)
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
This is the code for the HomeView (where I have the problem):
import SwiftUI
struct HomeView: View {
#State private var showAlertSheet = false
#ObservedObject var monitor = NetworkMonitor()
var body: some View {
ZStack {
Image("vivibusso_home")
.resizable()
.aspectRatio(contentMode: .fill)
.clipped()
VStack(alignment: .leading) {
Text("Benvenuto")
.font(.largeTitle)
.fontWeight(.bold)
.padding(.leading)
Text("a Busso!")
.font(.largeTitle)
.fontWeight(.bold)
.padding(.leading)
}
.frame(maxWidth: UIScreen.main.bounds.width, maxHeight: UIScreen.main.bounds.height, alignment: .topLeading)
.padding(.top)
}
.navigationTitle(Text("ViviBusso"))
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(trailing:
Button (action: {
self.showAlertSheet = true
}) {
Image(systemName: monitor.isConnected ? "wifi" : "wifi.slash")
})
.alert(isPresented: $showAlertSheet) {
if monitor.isConnected {
return Alert(title: Text("Tutto OK!"), message: Text("ViviBusso funziona correttamente!"), dismissButton: .default(Text("OK")))
}
return Alert(title: Text("Attenzione!"), message: Text("ViviBusso ha bisogno della connessione Internet per funzionare!"), dismissButton: .default(Text("OK")))
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
How can I solve this?
Thank you!
ZStack(alignment:.topLeading) { //<= here
GeometryReader { proxy in //<= here
Image("vivibusso_home")
.resizable()
.aspectRatio(contentMode: .fill)
.border(Color.black)
.frame(width: proxy.size.width, height: proxy.size.height)// <= here
}
VStack(alignment: .leading) {
Text("Benvenuto")
.font(.largeTitle)
.fontWeight(.bold)
.padding(.leading)
Text("a Busso!")
.font(.largeTitle)
.fontWeight(.bold)
.padding(.leading)
}
//<=here
.padding(.top)
}
.navigationTitle(Text("ViviBusso"))
...

UIView Top Point is Lower Then Expected

I have a format problem. How I want is the 2nd picture but for some reason, my view starts a little bit lower. You can see the gap between the pictures. I want to solve this problem without offset. Might be because of .navigationBarHidden(true) but I do not want navigation bar.
I added NavigationView to my code because I have a button down-right to add a new task.
Plus for some reason, this button is not clickable. Would be good if you give a hand to that problem.
import SwiftUI
struct TaskListView: View {
#State private(set) var data = ""
#State var isSettings: Bool = false
#State var isSaved: Bool = false
var body: some View {
NavigationView {
ZStack {
Color(#colorLiteral(red: 0.9333333333, green: 0.9450980392, blue: 0.9882352941, alpha: 1)).edgesIgnoringSafeArea(.all)
VStack {
TopBar()
HStack {
CustomTextField(data: $data, tFtext: "Find task", tFImage: "magnifyingglass")
Button(action: {
self.isSettings.toggle()
}, label: {
ZStack {
RoundedRectangle(cornerRadius: 15)
.frame(width: 50, height: 50, alignment: .center)
.foregroundColor(Color(#colorLiteral(red: 0.4274509804, green: 0.2196078431, blue: 1, alpha: 1)))
Image("buttonImage")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}
.padding(.horizontal, 15)
})
}
CustomSegmentedView()
ZStack {
TaskFrameView()
Button( action: {
self.isSaved.toggle()
}, label: {
ZStack {
RoundedRectangle(cornerRadius: 20)
.foregroundColor(Color(#colorLiteral(red: 1, green: 0.7137254902, blue: 0.2196078431, alpha: 1)))
Text("+")
.foregroundColor(.white)
.font(.title)
.fontWeight(.bold)
}
.frame(width: 40, height: 40)
.offset(x: 150, y: 220)
})
NavigationLink(
destination: NewTaskView(),
isActive: $isSaved,
label: {
Text("")
})
}
}
}
Spacer()
}
.navigationBarHidden(true)
}
}
struct TopBar: View {
var body: some View {
HStack {
Image("avatar")
.resizable()
.frame(width: 100, height: 100)
VStack(alignment: .leading){
DateView()
.font(Font.custom("SFCompactDisplay", size: 20))
.foregroundColor(.gray)
.padding(.vertical, 5)
Text("Hi, Random")
.font(Font.custom("SFCompactDisplay", size: 20))
}
Image(systemName: "ellipsis")
}
}
}
It is navigation view bar. The navigationBarHidden modifier should be inside NavigationView, like
}
.navigationBarHidden(true) // << here !!
Spacer()
} // end of NavigationView

SwiftUI Picker VALUE

I've been trying to program something with swiftui recently,
it's difficult, how can I transfer the value of the picker into the
text field, I'm desperate!
and why can I not work with the value $ khValue directly as in the text field?
I've already spent hours searching the internet… I haven't found anything yet, swiftUI is completely different from swift
import SwiftUI
struct KH_aus_Co2: View {
#State private var kh_Picker : String = ""
#State private var ph_Picker: String = ""
var kh_vol = [Int](0..<21)
var ph_vol = [Int](0..<10)
init(){
UITableView.appearance().backgroundColor = .clear
}
#State private var khWert: String = ""
#State private var phWert: String = ""
#State private var phco2Wert: String = ""
var calculation: String {
guard khWert.isEmpty == false, phWert.isEmpty == false else { return "" }
guard let kh = Double(khWert), let ph = Double(phWert) else { return "Error" }
let product = kh/2.8 * pow(10,7.90-ph)
return String(format: "%.2f", product)
}
var body: some View {
VStack() {
Text("Co2 = \(calculation) mg/ltr")
.font(.largeTitle)
.multilineTextAlignment(.center)
.foregroundColor(Color.green)
.frame(width: 300, height: 60, alignment: .center)
.border(Color.green)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
HStack {
TextField("KH Wert", text: $khWert)
.border(Color.green)
.frame(width: 120, height: 70, alignment: .center)
.textFieldStyle(RoundedBorderTextFieldStyle())
// .textContentType(.oneTimeCode)
.keyboardType(.numberPad)
TextField("PH Wert", text: $phWert)
.border(Color.green)
.frame(width: 120, height: 70, alignment: .center)
.textFieldStyle(RoundedBorderTextFieldStyle())
// .textContentType(.oneTimeCode)
.keyboardType(.numberPad)
}
GeometryReader { geometry in
HStack {
Picker(selection: self.$kh_Picker, label: Text("")) {
ForEach(0 ..< self.kh_vol.count) { index in
Text("\(self.kh_vol[index])").tag(index)
//
}
}
.frame(width: geometry.size.width/3, height: 100, alignment: .center) .clipped()
Picker(selection: self.$ph_Picker, label: Text("")) {
ForEach(0 ..< self.ph_vol.count) { index in
Text("\(self.ph_vol[index])").tag(index)
}
}
.frame(width: geometry.size.width/3, height: 100, alignment: .center) .clipped()
}
}
}
.navigationBarTitle(Text("Co2 aus KH & PH"))
.font(/*#START_MENU_TOKEN#*/.title/*#END_MENU_TOKEN#*/)
}
}
struct KH_aus_Co2_Previews: PreviewProvider {
static var previews: some View {
Co2_aus_KH()
}
}
big thanks for your help
Jürgen....................................
If I understand you correctly, you want the pickers to update the values in the textfields. If so, then you want to bind the same value to the picker that the textfield is using. Since that value is a String, you will want to use String values in your picker.
Use .map(String.init) to turn the kh_vol and ph_vol ranges into arrays of String, and use \.self as the id::
Picker(selection: self.$khWert, label: Text("")) {
ForEach(self.kh_vol.map(String.init), id: \.self) { index in
Text(index)
}
}
.frame(width: geometry.size.width/3, height: 100, alignment: .center)
.clipped()
Picker(selection: self.$phWert, label: Text("")) {
ForEach(self.ph_vol.map(String.init), id: \.self) { index in
Text(index)
}
}
.frame(width: geometry.size.width/3, height: 100, alignment: .center)
.clipped()

Same image being shown when showing a modal via .sheet after iterating array

In a swiftui app, I am iterating an array of entities and showing thumbmnail images and have it set up that when one is tapped, a detail view is shown with that particular full size image. The problem is that it's always the most recent image being shown when going to the detail screen.
Main view:
if documents.count > 0 {
ScrollView(.horizontal, showsIndicators: true) {
HStack {
ForEach(documents, id: \.self.id) {(doc: Document) in
Image(uiImage: UIImage(data: doc.image)!)
.resizable()
.frame(width: 40, height: 50, alignment: .center)
.clipShape(Rectangle())
.cornerRadius(8)
.scaledToFit()
.onTapGesture {
self.showImageDetail = true
}
.padding(.all, 5)
.sheet(isPresented: self.$showImageDetail, content: {
ImageViewDetail(image: UIImage(data: doc.image)!)
})
}
}
}
}
When ImageDetailView is shown, it's alway the most recent image saved. Below is the detail view code:
import SwiftUI
struct ImageViewDetail: View {
#Environment(\.presentationMode) var presentationMode
#State var image: UIImage
#State var scale: CGFloat = 1.0
var body: some View {
VStack {
Image(uiImage: image)
.resizable()
.padding()
.scaledToFit()
.scaleEffect(scale)
.cornerRadius(8)
.gesture(MagnificationGesture()
.onChanged {value in
self.scale = value.magnitude
}
)
HStack {
Button("Back") {
self.presentationMode.wrappedValue.dismiss()
}
.buttonStyle(FillStyle(width: 86, height: 32))
.padding(.trailing, 10)
Button("Delete") {
}
.buttonStyle(FillStyle(width: 86, height: 32))
.padding(.leading, 10)
}
}
.navigationBarTitle("Image", displayMode: .inline)
}
}
Any help would be greatly appreciated - I can't seem to see why the right image is not displayed by the ImageDetailView? Many thanks in advance.
Replace the Bool state with a Document? state:
#State var selectedDocument: Document?
var body: some View {
HStack {
ForEach(documents, id: \.self.id) {(doc: Document) in
Image(uiImage: UIImage(data: doc.image)!)
.onTapGesture {
self.selectedDocument = doc
}
}
}
}
.sheet(item: $selectedDocument) {
ImageViewDetail(image: UIImage(data: $0.image)!)
}
}
Sheet can be only one in view hierarchy, so below it is relocated for HStack and it is needed to add member currentImage
Here is scratchy approach... (not tested - might be needed take care of optionals)
#State private var currentImage: UIImage = UIImage() // < needed optionals?
...
ScrollView(.horizontal, showsIndicators: true) {
HStack {
ForEach(documents, id: \.self.id) {(doc: Document) in
Image(uiImage: UIImage(data: doc.image)!)
.resizable()
.frame(width: 40, height: 50, alignment: .center)
.clipShape(Rectangle())
.cornerRadius(8)
.scaledToFit()
.onTapGesture {
self.currentImage = UIImage(data: doc.image) ?? UIImage() // < current
self.showImageDetail = true
}
.padding(.all, 5)
}
}
.sheet(isPresented: self.$showImageDetail, content: { // < one sheet
ImageViewDetail(image: self.currentImage)
})
}

SwiftUI - Unable to reference #Published value outside Struct

I am new to SwiftUI and am hoping for some assistance with a project I am developing.
I am unable to reference #published value outside a struct.
All values are correctly functioning within the struct using:
#ObservableObject
#Publihsed
#ObservedObject
I have a Struct within ContentView which is linked to another View where I would like to display Quantity and Costs.
I have attempted various ways to access the values as can be seen in the struct NewOrders, but I keep getting zero and not getting the updated value.
Am I missing a step or executing code incorrectly?
Thanks in advance
class MealOrders: ObservableObject {
//Jollof Rice - Published
#Published var jollof = 0
//Swallow - Published
#Published var swallow = 0
//Pepper Soup - Published
#Published var pepperSoup = 0
}
struct ContentView: View {
var body: some View {
VStack {
NavigationView {
Section {
VStack(alignment: .leading) {
NavigationLink(destination: MenuOption()) {
Text("Meal Options")
}
Spacer()
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight:
.infinity, alignment: .topLeading)
}.padding() //Vstack End
}
Section {
VStack {
Image("africanfoods")
.resizable()
.frame(width: 275.0, height: 250.0)
.clipShape(Circle())
.overlay(Circle().stroke(Color.black, lineWidth: 5))
.scaledToFit()
}
} //Section End
Section { //Social Media
VStack {
Spacer()
HStack {
Spacer()
Image("facebook")
.resizable()
.frame(width:40, height: 40)
.scaledToFit()
.padding()
Image("instergram")
.resizable()
.frame(width:40, height: 40)
.scaledToFit()
.padding()
Image("youtube")
.resizable()
.frame(width:40, height: 40)
.scaledToFit()
.padding()
Image("twitter")
.resizable()
.frame(width:40, height: 40)
.scaledToFit()
.padding(.horizontal, 50)
}
} //Vstack End
} //Social Media
.navigationBarTitle(Text("African Foods Center"))
} //NavView End
} //VStack End
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct MenuOption: View {
//Object Observed Declarations
#ObservedObject var meals = MealOrders()
//Meal Prices
#State private var jolloRiceUnitCost = 14.95 //Jollof Rice Unit Cost
#State private var swallowUnitCost = 12.50 //Swallow Unit Cost
#State private var pepperSoupUnitCost = 13.50 //Pepper Soup Unit Cost
#State private var deliveryCost = 5.99 //Delivery Cost
#State private var menuItem = 0
var menuItems = ["Rice Meals", "Swallow Meals", "Pepper Soups"]
//Meals Calculator
var calculateMeal: Double {
var orderCost = 0.0
//Jollof Rice
if menuItems[menuItem] == "Rice Meals" {
orderCost = self.jolloRiceUnitCost * Double(self.meals.jollof)
return orderCost
//Swallow - Pounded Yam / Eba
} else if menuItems[menuItem] == "Swallow Meals" {
orderCost = self.swallowUnitCost * Double(self.meals.swallow)
} else if menuItems[menuItem] == "Pepper Soups" {
orderCost = self.pepperSoupUnitCost * Double(self.meals.pepperSoup)
}
return orderCost
}
var body: some View {
VStack(alignment: .leading) {
Section(header: Text("Select Meal").padding(.horizontal, 25)) {
Picker("Select Item", selection: $menuItem) {
ForEach(0 ..< menuItems.count) {
Text(self.menuItems[$0])
}
}.pickerStyle(SegmentedPickerStyle())
.padding(.horizontal, 25)
if menuItems[menuItem] == "Rice Meals" {
Text("Rice Meals:")
.foregroundColor(.black)
.padding(.horizontal, 25)
Spacer().frame(height:20)
`Text("Rice meals consist of Jollof Rice, Rice and Stew, Fried
Rice. You can option in meat, fish and or plantain with any of the meals")`
.foregroundColor(.blue)
.lineLimit(nil)
.padding(.horizontal, 25)
Spacer().frame(height:60)
//Insert image - Jollof Rice
Image("jollofRice")
.resizable()
.frame(width:250, height: 250)
.scaledToFit()
.border(Color.black, width: 4)
.padding(.horizontal, 100)
Spacer().frame(height:20)
HStack {
Stepper("Quantity (Max 5)",value: $meals.jollof, in: 0...5)
.padding(.horizontal, 45)
Text("\(meals.jollof): £\(calculateMeal, specifier: "%.2f")")
.padding()
}.padding()
Section { //Button Order
VStack {//Add Stepper for Quantity
Spacer()
HStack(alignment: .center, spacing: 140) {
Spacer()
Button(action: {}) {
NavigationLink(destination: Text("Jollof:: \(meals.jollof), £\(calculateMeal, specifier: "%.2f")")) {
Text("Create Order")
.font(.system(size: 14))
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(6)
}.padding()
Spacer()
}
}
} //Vstack End
} //Button Section End
} else if menuItems[menuItem] == "Swallow Meals" {
Text("Swallow")
.foregroundColor(.green)
.padding(.horizontal, 25)
Spacer().frame(height:20)
`Text("Swallow is the colloqual word for Pounded Yam, Eba, Fufu or Amala. This is complemented with soups, such as Egusi, Okra etc. You could have this meal with either meat or fish")`
.foregroundColor(.blue)
.lineLimit(nil)
.padding(.horizontal, 25)
Spacer().frame(height:60)
//Inset Image
Image("poundedYamEgusi")
.resizable()
.frame(width:250, height:250)
.scaledToFit()
.border(Color.black, width: 4)
.padding(.horizontal, 100)
HStack {//Add Stepper for Quantity
Stepper("Quantity (Max 5)",value: $meals.swallow, in: 0...5)
.padding(.horizontal, 45)
Text("\(meals.swallow): £\(calculateMeal, specifier: "%.2f")")
.padding()
}.padding()
//Insert Order Button
Section {
VStack {
Spacer()
HStack(alignment: .center, spacing: 140) {
Spacer()
Button(action: {}) {
NavigationLink(destination: Text("Swallow: \(meals.swallow), £\(calculateMeal, specifier: "%.2f")")) {
Text("Create Order")
.font(.system(size: 14))
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(6)
}.padding()
Spacer()
}
}
} //VStack End
} //Section End
} else if menuItems[menuItem] == "Pepper Soups" {
Text("Pepper Soup")
.foregroundColor(.red)
.padding(.horizontal, 25)
Spacer().frame(height:20)
`Text("Pepper soup is normally taken after one has had either Pounded Yam or rice meals. Depending on the audeience, the soup can be lightly spicy to very hot. Pepper soup can be had with either fish or meat")`
.foregroundColor(.blue)
.lineLimit(nil)
.padding(.horizontal, 25)
Spacer().frame(height:60)
//Insert Image
Image("pepperSoupYam")
.resizable()
.frame(width:250, height:250)
.scaledToFit()
.border(Color.black, width: 4)
.padding(.horizontal, 100)
HStack {//Add Stepper Quantity for Pepper Soup
Stepper("Quantity (5 Max)",value: $meals.pepperSoup, in: 0...5)
.padding(.horizontal, 45)
Text("\(meals.pepperSoup): £\(calculateMeal, specifier: "%.2f")")
.padding()
}.padding()
//Inset Order Button
Section {
VStack {
Spacer()
HStack(alignment: .center, spacing: 140) {
Spacer()
Button(action: {}) {
NavigationLink(destination: NewOrders()) {
Text("Create Order")
.font(.system(size: 14))
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(6)
}.padding()
Spacer()
}
}
}
}
}
Spacer()
}.font(.system(size: 14))
.foregroundColor(.purple)
} //Vstack Ending
} //View Ending
}
//This sis going to be the Orders Struct
struct NewOrders: View {
#ObservedObject var orderUpdatedV2 = MealOrders()
#State private var orderUpdate = MenuOption().meals.jollof
var body: some View {
//let mealsU: ContentView
NavigationView{
VStack {
List {
Text("")
}
}
}.navigationBarTitle("Meal Order")
}
}
This line below is incorrect because creates new value, that's why you have nil
#State private var orderUpdate = MenuOption().meals.jollof
instead you need to have (as far as I understood your code)
#Binding var orderUpdate: Int
and pass it in place of creating
NavigationLink(destination: NewOrders(orderUpdate: $meals.jollof)) {
Note: This is the idea, I'm not sure copy/paste will work, because provided your code snapshot is not compilable at my side.

Resources