The attached code works as expected on the Playgrounds simulator for the Mac but the States don't register a view update when the same code runs on an iPad. Does anyone know of a known issue/fix/workaround?
import SwiftUI
import PlaygroundSupport
struct MathGame: View
{
#State var showAnswer = false
#State var answer = ""
#State var x = Int.random(in: 0...100)
#State var y = Int.random(in: 0...100)
var body: some View
{
VStack
{
Text(x.description)
Text(y.description)
if showAnswer
{
let z = x + y
Text(z.description)
} else
{
Text(" ")
}
Button("Next Question")
{
showAnswer = false
x = Int.random(in: 0...100)
y = Int.random(in: 0...100)
}
Spacer()
Toggle(isOn: $showAnswer)
{
Text("Show Answer")
}
}.padding().font(.system(size: 64))
}
}
PlaygroundPage.current.setLiveView(MathGame())
I faced the same issue and I just found out that setting « Show results » to false was fixing it.
My iPad runs on iOS 14.6. I hope that the new Swift playgrounds with iOS 15 will fix this issue definitely.
Related
I'm trying to present multiple modals on top of my home view, but when I try to dismiss all modals, there is only the first one that close...
(I know, there is a lot of subject about this, but I didn't found any solution that was working for me...)
Any ideas?
Here is my testing code:
struct ContentView: View {
#State var presentA = false
var body: some View {
Button("Present A") { presentA = true }
.sheet(isPresented: $presentA) { ContentViewA(presentAll: $presentA) }
}
}
struct ContentViewA: View {
#Binding var presentAll: Bool
#State var presentB = false
var body: some View {
Button("Present B") { presentB = true }
.sheet(isPresented: $presentB) { ContentViewB(presentAll: $presentAll) }
}
}
struct ContentViewB: View {
#Binding var presentAll: Bool
var body: some View {
Button("Close all") {
presentAll = false
}
}
}
So when I touch the "Close all" button, I go back to the ContentViewA instead of the ContentView...
In my memory this was working with the previous version of SwiftUI but it seems that's not working anymore...
What am I doing wrong?
I don't think it is a valid user flow and SwiftUI does not handle it. The possible workaround is the same as for UIKit
Tested with Xcode 14b3 / iOS 16
var body: some View {
Button("Close all") {
UIApplication.shared.keyWindow?
.rootViewController?
.dismiss(animated: false, completion: nil) // false is important !!
}
}
Hello I am running into a problem here and I do not have a consistent behavior between my .sheet() view when running on ios13 or ios14
I got a view like this :
#State private var label: String = ""
#State private var sheetDisplayed = false
///Some code
var body: some View {
VStack {
Button(action: {
self.label = "A label"
self.isDisplayed = true
}) {
Text("test")
}
}.sheet(isPresented: $sheetDisplayed, onDismiss: {
self.label = ""
}) {
Text(self.label)
}
}
On ios 13 this work as expected btn click -> set label -> call sheet -> display "A label" in a Text view.
On ios14 I got an empty string in self.label when in sheet closure, hence it does not display anything.
Did I missed something ? Is it an iOS 14 bug or did I had it wrong on ios13 and that got corrected.
PS: I have a couple of other variables that are passed in the closure I simplified it.
Your code have expectation of view update/creation order, but in general it is undefined (and probably changed in iOS 14).
There is explicit way to pass information inside sheet - use different sheet creator, ie. .sheet(item:...
Here is working reliable example. Tested with Xcode 12 / iOS 14
struct ContentView: View {
#State private var item: Item?
struct Item: Identifiable {
let id = UUID()
var label: String = ""
}
var body: some View {
VStack {
Button(action: {
self.item = Item(label: "A label")
}) {
Text("test")
}
}.sheet(item: $item, onDismiss: {
self.item = nil
}) {
Text($0.label)
}
}
}
This is some really strange behaviour in iOS 14, which doesn't appear to be documented.
Using the other answer here and the comment on this thread, I used #Binding to solve the issue as it seemed the cleanest and most SwiftUI-esq solution.
I have no idea why this behaviour has changed, and it seems less intuitive than before, so I'm assuming its a bug!
An example:
struct MainView: View {
#State private var message = ""
#State private var showSheet = false
var body: some View {
Button(action: {
self.message = "This will display the correct message"
self.showSheet = true
}, label: {
Text("Test Button")
})
.sheet(isPresented: self.$showSheet) {
SheetView(message: self.$message)
}
}
}
struct SheetView: View {
#Binding var message: Int
var body: some View {
Text(self.message)
}
}
The behaviour changed with SwiftUI 2.0, so it affects MacOS 11 as well, just adding a binding to the view fixes it even when that binding is never used, which makes me think this is an implementation bug.
Additionally just using the details state variable in a Text() within the body of the view also fixes it.
struct MyViewController : View {
#State var details: String?
#State var showDetails = false
// #Binding var havingAbindingFixesIt: String?
var body: some View {
VStack {
// Text(details ?? "")
Text("Tap here for details")
.onTapGesture {
self.details = "These are the details"
self.showDetails.toggle()
}
.sheet(isPresented: $showDetails) { Text(details ?? "") }
}
}
}
Hello I am running into a problem here and I do not have a consistent behavior between my .sheet() view when running on ios13 or ios14
I got a view like this :
#State private var label: String = ""
#State private var sheetDisplayed = false
///Some code
var body: some View {
VStack {
Button(action: {
self.label = "A label"
self.isDisplayed = true
}) {
Text("test")
}
}.sheet(isPresented: $sheetDisplayed, onDismiss: {
self.label = ""
}) {
Text(self.label)
}
}
On ios 13 this work as expected btn click -> set label -> call sheet -> display "A label" in a Text view.
On ios14 I got an empty string in self.label when in sheet closure, hence it does not display anything.
Did I missed something ? Is it an iOS 14 bug or did I had it wrong on ios13 and that got corrected.
PS: I have a couple of other variables that are passed in the closure I simplified it.
Your code have expectation of view update/creation order, but in general it is undefined (and probably changed in iOS 14).
There is explicit way to pass information inside sheet - use different sheet creator, ie. .sheet(item:...
Here is working reliable example. Tested with Xcode 12 / iOS 14
struct ContentView: View {
#State private var item: Item?
struct Item: Identifiable {
let id = UUID()
var label: String = ""
}
var body: some View {
VStack {
Button(action: {
self.item = Item(label: "A label")
}) {
Text("test")
}
}.sheet(item: $item, onDismiss: {
self.item = nil
}) {
Text($0.label)
}
}
}
This is some really strange behaviour in iOS 14, which doesn't appear to be documented.
Using the other answer here and the comment on this thread, I used #Binding to solve the issue as it seemed the cleanest and most SwiftUI-esq solution.
I have no idea why this behaviour has changed, and it seems less intuitive than before, so I'm assuming its a bug!
An example:
struct MainView: View {
#State private var message = ""
#State private var showSheet = false
var body: some View {
Button(action: {
self.message = "This will display the correct message"
self.showSheet = true
}, label: {
Text("Test Button")
})
.sheet(isPresented: self.$showSheet) {
SheetView(message: self.$message)
}
}
}
struct SheetView: View {
#Binding var message: Int
var body: some View {
Text(self.message)
}
}
The behaviour changed with SwiftUI 2.0, so it affects MacOS 11 as well, just adding a binding to the view fixes it even when that binding is never used, which makes me think this is an implementation bug.
Additionally just using the details state variable in a Text() within the body of the view also fixes it.
struct MyViewController : View {
#State var details: String?
#State var showDetails = false
// #Binding var havingAbindingFixesIt: String?
var body: some View {
VStack {
// Text(details ?? "")
Text("Tap here for details")
.onTapGesture {
self.details = "These are the details"
self.showDetails.toggle()
}
.sheet(isPresented: $showDetails) { Text(details ?? "") }
}
}
}
This question already has an answer here:
iOS14 introducing errors with #State bindings
(1 answer)
Closed 2 years ago.
This code has the following issue: The first click on any list item will show the sheet with "This is sheet 0" - meaning that #State property "var example: Int" is not updated as part of the button code (exit live preview and start it again, will reproduce the issue).
Any idea what is happening here !?
Code:
import SwiftUI
struct testing2: View {
#State private var showSheet = false
#State var example: Int = 0
var computedItem: String {
"This is sheet \(example)"
}
var body: some View {
List(0 ..< 5) { item in
Button("List item: \(item)") {
self.example = item
showSheet.toggle()
}
}
.sheet(isPresented: $showSheet, content: {
Text("\(computedItem)")
})
}
}
Not sure whether this would be the best answer, but this worked for me:
struct ContentView: View {
#State private var showSheet = false
#State var example: Int = 0
#State var computedItem: String = ""
var body: some View {
List(0 ..< 5) { item in
Button("List item: \(item)") {
self.example = item
self.computedItem = "This is sheet " + String(self.example)
showSheet.toggle()
}
}
.sheet(isPresented: $showSheet) {
sheetView(computedItem: $computedItem)
}
}
}
struct sheetView: View {
#Binding var computedItem: String
var body: some View {
Text(self.computedItem)
}
}
I am new in Swift UI, I am trying to convert a value what I get from a textfiled and picker to convert that in days, minutes or seconds, this is from the tutorial 100 days with swiftUI i am lost because I dont understand how do the operations if someone can help me and explain me a little the code please, thank you.
this is my code
struct ContentView: View {
#State private var convertir = 2
let tipConverciones = ["segundos","minutos","horas","dias"]
#State private var convertirselection = 2
let convertirA = ["segundos","minutos","horas","dias"]
#State var cantidadconvertir = ""
var convertidormetodo: Double{
//Funcion que calcula el total de personas
let conteocantidad = Double(cantidadconvertir) ?? 0
let convertirSeleccion = (convertirA)
return 0
}
var body: some View {
NavigationView{
Form {
Section (header: Text("Convertir")) {
Picker ("Convertir de", selection: $convertir){
ForEach(0 ..< tipConverciones.count){
Text("\(self.tipConverciones[$0])")
}//ForEach
}//Picker
.pickerStyle(SegmentedPickerStyle())
}//Seccion3
Section (header: Text("Ingresar Cantidad a convertir")) {
TextField("Ingresa la cuentidad", text: $cantidadconvertir)
.keyboardType(.decimalPad)
}//seccion5
Section (header: Text("Convertir a")) {
Picker ("Convertir de", selection: $convertir){
ForEach(0 ..< tipConverciones.count){
Text("\(self.tipConverciones[$0])")
}//ForEach
}//Picker
.pickerStyle(SegmentedPickerStyle())
}//Seccion4
Section{//seccion 4
Text("La cantidad convertida es: \(convertidormetodo)")
}//seccion 4
}//Form
.navigationBarTitle("Convertidor SwiftUI")
}//Navigation View
}//body
}//view
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
an example of a user input and the desired output would help. But I think what you're looking for is either the dateFormatter or numberFormatter:
https://developer.apple.com/documentation/foundation/dateformatter
https://developer.apple.com/documentation/foundation/numberformatter