SwiftUI - New Page - view

Let's say my application has two pages; Login Page and Main Page. I created these two with SwiftUI View separately. How will I make the transition between them. I tried NavigationView but the second page opens with a NavigationBar (with the First Page named arrow). In summary, how can I switch between two views cleanly?

you can do this simply with switch or if/else :)
class Wnd : View {
#State var firstShown: Bool
var body: some View {
if firstShown {
FirstView(firstShown: $firstShown)
}
else
{
SecondView(firstShown: $firstShown)
}
}
}
firstView and secondView have Binding to firstShown var
Another one solution is to use handlesExternalEvents for switching views.
sample of usage: https://stackoverflow.com/a/65415593/4423545
Another solution is to hide NavigationBar:
.navigationBarHidden(true)

Related

How do I stop double clicking a NavigationLink opening a second window view?

Writing a Macos app. The following code just puts up a simple navigation list. Everything is fine with single clicking the Row links and displaying the Detail row.
If you double click the NavigationLink, another window opens with only the Text view on it. During my testing, there was a button to dismiss the view on the detail window, and if clicked, the original window would close leaving this stripped down view open.
I have to assume that no one else is seeing this since I cannot see anything from other people.
Does anyone have any ideas what would cause this to happen?
import SwiftUI
struct ContentView: View {
var body: some View {
HStack {
NavigationView {
List(0..<100) { row in
NavigationLink(destination: Text("Detail \(row)")) {
Text("Row \(row)")
}
}
}
}
}
}
Just use sidebar list style explicitly
List(0..<100) { row in
// ... content here
}
.listStyle(SidebarListStyle()) // << here !1
Tested with Xcode 13.2 / macOS 12.1

Xcode 12.3 puts any new piece of content in a new preview

import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello")
Text("World")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
The code above results in two preview windows: one with text "Hello", second window holds "World"
Every time I add something like Text() or whatever, it appears in the second preview window. Adding more elements automatically leads to new preview windows. THe code in the PreviewProvider remains the same, so it's not duplicate previews, it just the separate previews for EACH element...
I tried to restart Xcode, change simulator devices, create new projects - nothing changes.
It started after I added duplicate preview in one project and then deleted it by removing appropriate lines in the PreviewProvider. After that all new projects or all new files in old projects show this strange behaviour.
The body by default is a #ViewBuilder in SwiftUI 2.0, so it just generate a group of views inline, thus having two Text element you got two previews. If you want just one Preview your body should have the one top view, like
struct ContentView: View {
var body: some View {
HStack {
Text("Hello")
Text("World")
}
}
}
You have to put the two Text elements into a Container, like e.g. a VStack.

Xcode - How can i programmatically embed/change view controller within a container view?

I am trying to programmatically set / or change the embedded View Controller inside a Controller View.
I have 3 different View Controllers, that I would like to show in the Container View, all depending on if the user is logged in or not.
I have looked around and tried a bunch of code, I found one that worked, but the code changed the self view, and not the view containers view.
A lot of the code I have tried have also not been in Swift 3, so as a new app developer, this has been quite stressful, as I tried to convert it to Swift 3.
Can anyone provide a solution for changing the embedded view controller inside a view container? Thanks.
I might have found a solution for this. I'm answering here, in case it can help anyone else in my situation.
What I did was add a new View Controller and then embed it to the View Container - This will work as a "master view" - I then use this blank view controller to decide which other view controller should be changed within the self of the blank.
Here's some code I have in the blank view controller, but I suppose the blank view controller can also be used as a master view controller (in my case for "Account"), and then it can add the login/register view as a child.
override func viewDidLoad() {
super.viewDidLoad()
updateView()
}
private lazy var loginViewController: loginViewController = {
// Load Storyboard
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
// Instantiate View Controller
var viewController = storyboard.instantiateViewController(withIdentifier: "loginViewController") as! loginViewController
// Add View Controller as Child View Controller
self.add(asChildViewController: viewController)
return viewController
}()
private lazy var registerViewController: registerViewController = {
// Load Storyboard
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
// Instantiate View Controller
var viewController = storyboard.instantiateViewController(withIdentifier: "registerViewController") as! registerViewController
// Add View Controller as Child View Controller
self.add(asChildViewController: viewController)
return viewController
}()
private func add(asChildViewController viewController: UIViewController) {
// Add Child View Controller
addChildViewController(viewController)
// Add Child View as Subview
view.addSubview(viewController.view)
// Configure Child View
viewController.view.frame = view.bounds
viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// Notify Child View Controller
viewController.didMove(toParentViewController: self)
}
private func remove(asChildViewController viewController: UIViewController) {
// Notify Child View Controller
viewController.willMove(toParentViewController: nil)
// Remove Child View From Superview
viewController.view.removeFromSuperview()
// Notify Child View Controller
viewController.removeFromParentViewController()
}
private func updateView() {
add(asChildViewController: registerViewController)
/*
if segmentedControl.selectedSegmentIndex == 0 {
remove(asChildViewController: sessionsViewController)
add(asChildViewController: summaryViewController)
} else {
remove(asChildViewController: summaryViewController)
add(asChildViewController: sessionsViewController)
}
*/
}
Credit to this guy: https://cocoacasts.com/managing-view-controllers-with-container-view-controllers/
The easiest way to do that is to have 3 container views in Storyboard above each other, each one of them is connected to a different view controller, then in your code, make 2 of these 3 container views hidden and leave one visible based on your business needs.
This is described in detail in this blog post. Hope this helps!

Simple displaying of second window: OS X & Swift

I'm trying to find how to bring up a second view/window after pushing a button on my primary window. I have read about segues and I can get the first window to display the second but the second is not connected to a view controller so I can't add any code to any controls on the second view. Try as I might I cannot create a SecondViewController.swift file and connect it to a window controller or a view controller. The tutorials I have found all deal with iOS and I want OS X which means there are just enough differences to keep me from figuring this out.
Can anyone show me how to do this?
Ta,
A.
First make new file like:
After that, put these codes in your classes and that should do it.
class SecondWindowController: NSWindowController {
convenience init() {
self.init(windowNibName: "SecondWindowController")
}
}
class ViewController: NSViewController {
private var secondWindowController: SecondWindowController?
#IBAction func showSecondWindow(sender: AnyObject) {
if secondWindowController == nil {
secondWindowController = SecondWindowController()
}
secondWindowController?.showWindow(self)
}
}

How to control instance in another view controller

I'm new to Swift and OS X programming.
I am creating a desktop application with two view controllers, which are in a split view controller. How can I get access to the instances in another controller and change its attributes?
An example:
We have a drawing application, one view is canvas, the other is tools. There is a 'clear' button in tool view, how to set the canvas clear when click on this button?
You can try to use singleton pattern in your code. When you create the view controller, put the var out of the class like:
var fooViewController = FooViewController(...)
class FooViewController{
...
}
Then you can use the fooViewController anywhere in your project.
If you are working with storyboard, you can try some code like this:
var story = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
var view:MainTabViewController = story.instantiateViewControllerWithIdentifier("MainTab") as MainTabViewController
Hope this can be helpful.
You can use delegates and protocols! Link to Official Apple Documentation
Heres a quick example:
protocol toolsProtocol {
func pressedClear()
}
var delegate : toolsProtocol
In your canvas class
class Canvas: UIViewController, toolsProtocol {
Tools.delegate = self
func pressedClear() {
// Insert stuff happens here
}
}

Resources