How to *include* a model in multiple views / structs in SwiftUI xcode - swift

This is a very noob question. I'm proficient in css, but swift is new to me and so I am trying to think object based, but it's not natural yet. I have tried to understand MVVM which I think is core to the problem but I'm not sure so asking for help.
I want to create an app which has an 'index' central nav type view which I have put in contentview. Depending on what button is pressed I want it to invoke series of functionality but there are up to 9 different types of function that are entirely independent of each other. In html / css, I'd have a central nav index and 'link' to other function specific capabilities.
I don't want to repeat code, so I am trying to work out how to create an architecture that supports it. Where I am getting stuck is in the scoping of it as it is telling me 'this variable isn't in scope'. Fine. I understand the concept but not how to do it right. And I've watched hundreds of hours of video and still not found anything. As an illustration, say the contentview was main actor, and it was a navigator for topics on cats, dogs, lizards, snakes, horses, and pigs.
My thinking is that I'd keep contentview as the nav, and have separate swift files cat.swift, dogs.swift, lizards.swift etc and include them into contentview so their content was globally available. In each of those files I'd have the let catName = etc and much more content specific to that function area. But then from within cat.swift I'd also want to include dog.swift, horse.swift etc as well so the user can navigate those too. In css I'd do this via links - which is probably utter idiocy in swift.
So how do I do this in swiftUI? I don't in detail know the detailed differences between #stateObject, and #state and private var versus var etc and have tried to find a guide that says 'if you want 'catModel' to be available throughout the app define it anywhere with #makeitavailableeverywhere catModel and just trigger it into the view you want by '#include catModel'.
Not sure if this makes sense, but if someone can point me to where I can get accessible, translation into how to do this I'd be so grateful. The app is nearly complete - and I'm pleased, I just can't get the different .swifts to be in scope to each other.
Thank you!

Related

Best practice so switch between a grid and list layout at runtime

Im currently working on a project where I want to the user to be able to chose between two layouts (list and grid) at runtime. I was searching for examples in the UI5 documentation (Sample Apps) and on GitHub, I did not find examples for how to to this or best practice examples. So I thought about how I could achieve this behaviour and had multiple ideas, but somehow none of them feels like doing this would be best practice.
Idea 1 - Destroy the "old" controls and generate the new controls inside the Controller
My first idea was to destory the controls I do not longer need. For example if the user wants to switch to the grid layout, the list and every control related it to it gets destoyed. In the controller the needed controls for the grid are created and then rendered in the view. In my eyes this would mix up view and controller logic inside the controller and does not feel like best practice
Idea 2 - Create two views and switch between them
My second idea was to create two views, each for the layout I need and switch between them. This would mean a lot of code replication in both the controller and the view. Does not feel like this would be the right way.
So I would be glad if you have own experience on this or if there is really something like a best practice for such a behaviour.
Thank you and kind regards!
I would say, idea 2 because of the following reasons:
It is best practice to work according to the MVC methodology which means separating logic, view and data. Since the controls define your view it is best to instantiate your controls in the files that are meant for it (the XML Views).
Performance: Destroying all controls means that if the user decides to switch between views, the controls have to be re-instantiated by the controller every time. This is, even though you probably won't notice it, not performant.
You don't need code replication: The argument of code replication is not necessarily true. If you can execute the same actions in the list and grid-view, it should be enough to just link the controller to both views and in that case you'll hardly have to replicate any code. Just make sure that you split your logic in enough functions. That way you might need to write some extra public functions to handle events, but not much more.

Creating a List of Custom Views in Xcode

I'm currently working on developing a desktop application for MacOS for downloading batches of audio files from URLs at one time I've run into a question about UI design that I can't figure out.
I have a class called SongEntry.swift that holds information regarding the URL that was entered (e.g. url, title, length, author, etc.) and I want to create a vertically growing list of custom views that updates when a new one is added.
Where is what the base view looks like:
Inside of the big white area is where I want the list to be held.
I've tried to create a separate view controller that handles each entry but that didn't work. I know UI design for MacOS is much different from iOS, however I think what I'm looking for is a way to simulate the table views and cell prototypes from iOS but can't find a suitable option.
If anyone knows of a possible solution or can point me in the right direction, I'd greatly appreciate it!
What you want is one of the collection views. For vertical list, you'll probably use NSTableView with only one column and hide everything else like headers.
Here are roughly the steps you need:
You can use your existing view controller or create a dedicate view controller for just the table (and use the 'embed' option in Interface Builder)
This view controller will adopt the NSTableViewDataSource and NSTableViewDelegate protocols to provide the data (your SongEntry objects) and the view for each row.
You set your NSTableView's source and delegate to your view controller.
You create a view which will serve as your "cell", it will be used by each row to display the data. You can design it either in IB or in code.
The entire process is described in detail in the Table View Programming Guide for Mac.
This topic can be a bit confusing. Note that there are two main approaches: the view-based and NSCell-based tables. Don't bother with the NSCell way, it's more of a legacy leftovers.
Also note that there are some overlap of methods in both NSTableViewDataSource and NSTableViewDelegate to provide data and views that can be a bit confusing at first. Just play around with the code and samples and it will be clearer which delegate method to use when.
There are many examples both on Apple's developer site and github. Also a good tutorial on raywenderlich.com.

NSTableView cuts off content

I'm building in content inside of a NSTableView, but when I compile and run, it cuts off the top half of all the content within the NSTableView. I'm brand new to the Swift language so I am quite lost here. I can provide further examples as necessary. Is there something simple I am missing first or is this more specific to my use case?
I can quickly give you a few directions to go looking for help.
Firstly the Apple Documentation for it. https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TableView/PopulatingView-TablesProgrammatically/PopulatingView-TablesProgrammatically.html
You may note that there are essentially two ways of populating the table view, programmatically by implementing the methods of NSTableViewDataSource and NSTableViewDelegate protocols. And by using Cocoa Bindings. I recommend, as a beginner, to use the first option and look at either example code or videos that use these protocols.
Secondly, this may be just a UI issue in your storyboard, make sure your constraints are set properly. You may just have some weird behavior going on here with other views.
Unfortunately, I cannot give you more help without code snippets or more information

create a viewcontroller for each view screen?

Do you create a Viewcontroller per view screen? or should you share a viewcontrollers? (ie in the example below Should there be 3 controllers or just 1 controller?)
Example
Screens are related
Screen1 (input information),
Screen2 (Review and confirm Information),
Screen3 (thank you / status response).
You should code according to the MVC paradigm. Parcel out your code and separate it based on overrarching function. Here is a high level overview of MVC
(Data) Model: contains all of your app data, objects that are passed around and used to populate the views
View: everything that is some sort of visual output
Controller: Classes that make the models and views work together.
What this is saying, in iPhone development parlance, is don't just jam a bunch of code into your UIViewController subclass. If you want to change the way part of the system works, having one huge class with a ton of code in it is a lot harder to edit and fix, than several smaller classes with a specialized use.
To answer your question, you should most definitely use one controller for each view function, but going beyond that, you should create specialized classes that take the inputs and manipulate that data, create specialized classes that then use the data to send it back to the user in an output.
Don't put all of your code into one class. It might work, but if you ever need to tweak it, or, just like when the iPad came out, it has to be adapted to use on another platform, it will be easier to manage if you only have to change something small to make it work
In your case you definitely don't need separate controllers. In fact you don't even need separate views. You can create a single view to take information, process it in the same controller and show the result in a UIAlertView.

Iphone sdk - How to setup a 'template'

I've been working on a Cook Book App and I've been making each page individually which takes a really long time to do, I asked a question similar to this and it was brought to my attention that you can setup a way to automate the design process so all you need to do is input your data.
Can someone please explain in as much detail as possible how you setup your xcode files/code to automate such a process
So for example I would just enter the page text and it would automatically put my standard background picture in and add a scroll view and appropriate buttons etc.
Thanks
You could make one master view that contains all the controls that you need: standard background picture, scroll view, appropriate buttons, etc, and make any subsequent views that you create inherit from this view, so that they all contain those controls.
You could also use just one view and work with multiple instances of it, one instance per page. Just make sure to have a Text property on it, or a constructor that takes in your text string, so that you could set it to a different text on each page.
Xcode project templates and file templates are pretty easy to make, with a few caveats.
Check the answers to these questions:
Add new templates in Xcode
Change templates in XCode
Also take a gander at these handy tutorials:
Custom Xcode Templates
Xcode: How to customize the existing project templates
It sounds to me like your putting your data into your views (pages). That's a big design error. You need to employ the Model-View-Controller design pattern and separate your data from your views. That will make it easy to create one view (template) that you can reload with data to display each individual recipe.
The first thing to do is to separate your data from the view. You need to have the recipes stored in an array, dictionary, Core Data etc and then wrap that data in a dedicated object. The second thing to do is to create a dedicated view to display all the recipes. As the user moves from recipe to recipe the app will simply remove and add information to the same view as needed.
I would recommend Cocoa Recipes for Mac OS X: The Vermont Recipes, Second Edition because it addresses these issues and it uses a recipe type app as its example. It's for Cocoa but the basic principles apply to iPhone apps as well.