How can I switch the View directly with a function call in SwiftUI?
Since you already have a Bool
all you need is a conditional.
If you want it in the Navigation Stack (with a Back button) use the NavigationLink
constructor with isActive
and use your Bool
to make the View
active.
import SwiftUI
struct SwitchScreen: View {
@State var animate = false
@State var endSplash = false
var body: some View {
NavigationView{
switch endSplash{
case false:
ZStack{
Color.blue
Image(systemName: "checkmark").resizable().renderingMode(.original).aspectRatio(contentMode: animate ? .fill : .fit)
.frame(width: animate ? nil : 85, height: animate ? nil: 85)
.colorInvert().scaleEffect(animate ? 3 : 1).frame(width: UIScreen.main.bounds.width)
}.ignoresSafeArea(.all, edges: .all).onAppear(perform: {
animateSplash()
}).opacity(endSplash ? 0:1)
case true:
Text("Done")
}
}
}
func animateSplash(){
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5){
withAnimation(Animation.easeOut(duration: 0.45)){
animate.toggle()
}
withAnimation(Animation.linear(duration: 0.35)){
endSplash.toggle()
//Switch to another View here I guess ?
}
}
}
}
struct SwitchScreen_Previews: PreviewProvider {
static var previews: some View {
SwitchScreen()
}
}
How to go to another page from a sheet view in SwiftUI?
NavigationLink
should be in same view hierarchy of NavigationView
to work, but .sheet
introduces another different view hierarchy, so the solution would be to leave (hidden) navigation link in previous view, but activate it programmatically from view in sheet.
Here is a demo (tested with Xcode 12 / iOS 14)
struct FirstView: View {
@State fileprivate var isShowingSheet: Bool = false
@State private var showThirdView = false
var body: some View {
Button(action: {
isShowingSheet = true
}) {
Text("Show the sheet")
}
.sheet(isPresented: $isShowingSheet, content: {
SecondView(showNext: $showThirdView)
})
.background(
NavigationLink(destination: ThirdView(), isActive: $showThirdView) {
EmptyView()
}
)
}
}
struct SecondView: View {
@Environment(\.presentationMode) var presentationMode
@Binding var showNext: Bool
var body: some View {
Button("Show the third view.") {
self.presentationMode.wrappedValue.dismiss()
DispatchQueue.main.async {
self.showNext = true
}
}
}
}
SwiftUI Change Observed Object From Another View
It is changing the value. The problem is you are instantiating an instance of GlobalValue locally in your struct. It has no life outside of the struct. I you want to use an Observable Object
as a global store like that, you need to create it once and use that instance.
The easiest way to do this is to addstatic let shared = GlobalValue()
in your class, and in your struct use globalValue = GlobalValue.shared
which essentially gives you a singleton. You will have one instance that all the views can read and write to.
Go to a new view using SwiftUI
The key is to use a NavigationView and a NavigationLink:
import SwiftUI
struct ContentView : View {
var body: some View {
NavigationView {
VStack {
Text("Hello World")
NavigationLink(destination: DetailView()) {
Text("Do Something")
}
}
}
}
}
How can I execute some function when a Link is clicked in SwiftUI?
you could also try this using a button as @aheze suggested:
struct ContentView: View {
@Environment(\.openURL) var openURL
var body: some View {
Button(action: openSesame) {
Text("open url")
}
}
func openSesame() {
// do something here
print("---> about to open duckduckgo ")
openURL(URL(string: "https://duckduckgo.com/")!)
// or/and do something here
print("---> after openning duckduckgo ")
}
}
SwiftUI send action from a page to the PageViewController
OK, I figured it out. Not intuitive at first, I have to say. Coming from traditional event based programming, it's quite a different way of thinking
I used a @State
variable in the main instance of the view.
I used @Binding
variables to deal with the state both upstream (ViewControllers, Controls) and downstream (subviews). So, for example, I used a variable to tell the dataSource
of the UIPageViewController
if or not to return a view controller before/after the current one.
For the dismissing the modally presented controller I used
@Environment(\.presentationMode) var presentationMode
...
func dismiss() {
self.presentationMode.wrapptedValue.dismiss()
}
Similarly,
...
@Binding var currentPage: int
...
Button(action: next) { Text("Next Page") }
...
...
func next() {
currentPage += 1
}
There were a few caveats in deciding how to nest the views and what variables to pick for the bindings, but it is clear to me now. The biggest problem was ultimately where the "source of truth" should be anchored. It turned out, right in the "middle", i.e. below the controller and above the particular views.
Hope this is useful for others looking for something similar.
Related Topics
How to Stop an Infinitely Rotating Image? and How Does One Implement Removeallanimations
Tube Physics Body Acting Like Scncylinder, But How to Make It Act Like Scntube
Convert Swift Encodable Class Typed as Any to Dictionary
Xctest Unit Test Data Response Not Set in Test After Viewdidload
Ternary Operator Inside Navigationlink Swiftui
Printed Double Value Differs from Originally Set Value
How Could I Request Text from a Website in Swift
How to Change the Order of Functions Triggered
How to Get All Characters of the Font with Ctfontcopycharacterset() in Swift
Macos Playground: How Can Change the Background Color
Swift Nsunknownkeyexception - Setvalue:Forundefinedkey
Swift Generic Func Cannot Convert Value of Type to Expected Argument Type
What Is a Good or Common Way to Structure a Cli Appliction in Swift
Expanding Uitextview Inside a Stack View with Scrolling Enabled
How to Ensure Make Sure I'm Not Accessing Data Until It's Loaded In
Uitextview Linktextattributes Font Attribute Not Applied to Nsattributedstring