I am developing an app which has one screen showing a list of items, and when the user taps on one item another screen opens up which displays the details of the tapped item.
I'm using the Scoped Model architecture, so the screens are StatelessWidget's which use the same instance of a concrete Model.
My problem is that I'm not sure which is the best way to pass information about which item to display to the detail screen.
One way to go is to set a member of the model, e.g. selectedItem, to the selected item. This has the advantage of being solely model-based, but it doesn't really feel clean, since the selectedItem member is useless when not in detail mode (and could potentially contain old data).
Another way would be to pass the selected item (or some type of identifier for it) to the StatelessWidget constructor and use it to retrieve the correct item from the model in the detail screen. However, this would mean that the StatelessWidget wouldn't really be stateless, since it would need to store the parameter passed in the constructor in itself...
Is there a third and better way to do it?
Related
I am new to programming iOS and I am not sure on how to implement multiple/relational drop down pickers into my design.
I have a search form in my app that works like a panel-menu. If you click on the search icon then the panel slides in with the search form.
But what is the best way to implement multiple/relational drop down pickers for my search form?
The pickers are relational. First you select a state then you must select a city. Once you selected a state in dropdown1 then dropdown2 should get populated depending on what you selected in dropdown1.
So is there any good solution for this when it comes to design?
I would like to show both pickers at all time. Kinda like a datepicker when year / month / day always is shown.
But if anyone has a good resource example on relational pickers please share.
Thanks in advance,
You can set this up with nested UITableViewControllers.
These types of projects are generally called Master/Detail.
The Master tableView would display the list of categories.
Once the user has selected a category, the specific category is passed to the detail View controller. It queries all the subcategories for that category.
This can all by done in Storyboard, using Auto Layout, self-sizing cells, and a combination of show and unwind segues.
A show segue pushes a (table) view controller onto the navigation controller stack. In your case, the category controller would push a subcategory controller. prepareForSegue:sender: is where the category controller would provide the category to the subcategory controller.
An unwind segue returns from a view controller, popping it off the navigation stack. In your case, the subcategory controller would return (with the selected subcategory information) to the category controller, or a previous view controller.
It may sound like a lot to digest, but if you read up on recent (i.e. for iOS 8) walkthroughs which use these concepts, you'll have learned some acceptable practices for how information and control should flow within an app.
There's one more thing I didn't mention, called Core Data. Core Data, and NSFetchedResultsController would be a great tool to learn and use for the app. It's probably more complex than anything I previously mentioned, but once you get a handle on it, you will really appreciate it, and may end up using it in many apps!
Don't get too bogged down with how your app should look. Focus on how the model and view controllers are written, and get a good understanding of the underlying frameworks. That's more important right now, than any fancy transition/animation.
The design of any app will evolve as you use it. You'll discover what works well, and what doesn't, so don't get too attached to any one way of organizing the data!
Hope that helps! Enjoy programming for iOS, it's a great platform!
In my iOS app, there are various Core Data entities that represent things like Appointments, Notes and Contacts.
I'd like the user to be able to edit selected attributes of each entity via a UITableView. Similar to the iOS Calendar app, when you click 'Edit', you're presented with a UITableView with editable values for Start Time, End Time, etc.
It's occurred to me that there could be a large amount of code re-use going on here, so I'm now considering creating a generic class, ManagedObjectEditorViewController that takes a managed object, displays selected attribute values within a table view, formatted according to their type, and allows them to be edited.
I can think of several neat ways of doing this, but before I spend a long time on this, I'm wondering if there's already something out there to accomplish this task? It seems like such a frequently used approach that I can't believe there isn't already some open source code out there.
Anyone heard of, or used anything similar?
I am about to do the same thing. Just started and works so far. A table that represents an NSManagedObject (Detail to a master view controller, has aspects of a master view controller itself.).
The whole table represents one NSManagedOjbect. There are fields and other controls that correspond with the simple properties.
There are to-one references where the referenced object is just displayed but can be changed.
There are to-one references which are editable NSObjects itself where 1 and exactly 1 of them exists.
There are to-many references which can be added, deleted and edited. Pretty similar to the calendar app or the address book app. (from a functional point of view. It looks different though).
For that I establish a delegate between the table cells and the view controller. This is mainly because I try to stick on the MVC pattern.
E.G. the cell serves as delegate for UITextViews, UITextFields or as target for Buttons etc.
The (Detail-) View controller which owns the NSManagedObject and all related objects serves as my delegate for the cells. It provides methods similar to IBActions to the cells so that the cell can 1) inform about the event and 2) hand over a related view, if required (I need that to display some popups accordingly) and 3) the object itself e.g. the object that is to be deleted or a person-object for which the data is to be fetched from the address book etc.
The View controller can then does its very own duties which is invoking other view controllers (Send Mail, select from Address Book, present a popover with options for the user to choose from, ...).
I just built that up yesterday evening. (It is a free-time project of mine).
I am happy so far but the concept is not really proven yet :) .
What is your current favorite approach?
having a bit of panic and really really need some help with this!
I'm making an app to fill in forms. The layout of the forms are created on a web server, and then the ipad app syncs with it, copies the form database, and then runs it locally.
One type of text field is a UITextView where the user can input text either by writing directly to the field, or by using one of many pre-defined texts (also defined on the web server).
To use a pre-defined text, the user touches/selects the tablecell that is containing the UITextView, and then a category-picker-view is pushed on the screen. On selection of category, the user gets a list of texts, and upon selection of text, the user gets a simple uitextview to edit it before insert. With a save button, the user then gets moved back to the original view where the chosen text is now added.
Flowchart:
root view with input fields-> category picker -> text picker -> editor
/\ |
'------------------------------save text------------------------'
The problem is that when any other view loads, all other input fields are emptied! The value of the selected field is passed via prepareForSegue, so that one is kept.
I have a save function which saves all fields to the database. I tried to put a call for it inside the prepareforsegue call, but it either crashes or does nothing.
Question: Where could i put the save function? Could/should I do it another way? Thought about putting all tag's values in a dictionary inside my appDelegate instead of running the save-function, but how could i update it every time an input field is edited?
Also - would putting the categorypicker etc in some kind of popover/modal/popup-view instead of the push segue prevent the values from clearing? I've got no experience from such views, could someone give a good starting point? (perhaps a good tutorial rather than heavy apple docs :)
I have a deadline for this tomorrow, with LOADS of more things to complete as well, so I'm very very grateful for ANY help!!
Thank you for your time!!
/Dave
I think your problem is caused by an absence of a model (in terms of the model-view-controller pattern). A model that represents your form data (e.g., custom object, NSArray, NSDictionary) should be updating the view and should be passed in prepareForSegue, not an input field's value.
Specifically, create a new property that maintains the latest data. When the user makes an edit or selects a category for some field, update the model. Then, when you return to your form view controller, use viewDidAppear to update the input fields to their latest values.
At the moment I'm using a Singleton class to do some work but I'm wondering if there is something better.
I have an app that has a completely dynamic work flow. It uses a navigation controller but the order of the view controllers depends entirely on some data that is downloaded from our server.
The entire workflow is downloaded and saved in an array.
The "main menu" screen of the app has several choices (settings, recent, etc...) these are fixed but one of them is the dynamic one. It always starts with the same type of view controller but from then on it depends on what you choose.
Description
There are 4 different types of these dynamic controllers.
Table View Controller with single selection and detail indicators.
Table View Controller with multiple selection and checkmarks.
View Controller with a text field and keyboard.
View Controller (with other related VCs) used for searching for accounts on the server.
When you press the option "New Event" on the main menu the menu then goes off to the singleton (EventManager) and tells it to start a new event.
The singleton then pushes a single selection dynamic view on the nav controller and gives it the initial options.
From here on the singleton picks up all the selections and works out what type of view is required next.
I hope this is making sense
Anyway, I don't like the singleton pattern here as I don't think it should be a singleton.
What I would like is a class that I can create from a ViewController and this class will then control the pushing and popping and flow of data between a load of different view controllers. Then when you go back to the main menu this class can go away so I create a new class each time.
Is there a pattern that I can look at that will do this? Or should I stick with a singleton like I am now?
I hope this makes sense.
EDIT
Could I use a UIPageViewController for this? Then the datasource/delegate object of the UIPageViewController will take the place of the Singleton I am currently using... or something?
ADDING PHOTO FROM TWITTER REQUEST
Each VC along the flow has no idea what cam before it or what comes next. All they do is call back to the singleton to say "This value was selected" or "This text was entered" etc...
The singleton then stores that info and works out what comes next and pushes the next VC onto the stack.
It needs to be able to move back along the stack so the user can go back to change something etc...
It's all working as it is I just don't like the use of the singleton.
Lots of comments here in order of importance.
Everything you've described here sounds really good, even down to the naming. "EventManager" sort of sounds like it manages all "events" in the system (so I'd expect there to be a class called Event, but that's a tiny quibble and the name is likely still very good). There are other good designs, but I wouldn't have any problem with yours.
I agree that this does look like a good fit for UIPageViewController. You should certainly investigate that to see if it's the right fit. It's always nice to use a built-in controller if you can.
There's no reason to strongly avoid singletons. They are a natural part of iOS development and fairly common in good Cocoa design. They should be "shared" singletons generally (never create "strict" singletons that override +allocWithZone:). This just creates an easy-to-access instance rather than a true "singleton." This is the way things like NSNotificationCenter work and is often a very good pattern.
Singletons are best when many random pieces of the system need to access them directly and passing them around to everyone would be a lot of overhead (especially if many of the pieces you'd have to pass the object to don't need it themselves). Again, think NSNotificationCenter. If the users of it are mostly contiguous (i.e. most objects you would pass it to actually need it themselves), then just create one at the start of the program and pass it around. That sounds like your situation, so your intuition about it seems good. Just de-singleton it and pass it. Easy change.
But I'd definitely dig into UIPageViewController. It could match your problem very well.
Not sure I'm designing this correctly (guidence is appreciated!), but I have a search view which is called from many places. Search screen has has it's own ViewModel. When a user selects something from the search screen (after searching :), I need to send the selection to whatever view requested the search to take place (search screen is a pop-up).
I have a view locator that pops up the screen screen when I send it a message. The message is sent from a ViewModel (MVVM Light) to the view locator.
Do I register a call back? Broadcast a message? Set a Property? Dynamically Bind the "Select" button on the search screen back to the view model that initiated the call?
mmmm so many questions, so little time...
Regards,
Richard
I am not sure if MVVM Light has anything equivalent to an EventAggregator, but this is the best way I can think of for you to broadcast this event.
Another option would be to use the Reactive Extensions (Rx) and make the receiver subscribe to the event using a filter before you open the search view, then pass the filter to the search view so that the actual operation is called using that filter, so even when the search view model requested the search is the other view model that will receive the event.
I had a similar issue and here is how I did it.
I had a difference ViewModel for my Pop Up window and the view model took a parameter of the object you want to return e.g. You have you MainViewModel and a property Customer. In the PopupViewModel constructor I passed the Customer from MainViewModel. When I did my search and found the Customer you are looking for, assign that customer to the Customer reference from MainViewModel. Assuming you have implemented INotifyPropertyChange interface, it will show up in your main screen as soon as you select a customer. Let me know if you understand or I will post you an example.
Hope this helps.
I recommend that you pass the reference to the interface element making the call forward to your search. All of this is taking place at the view-model layer as far as I can tell.
The other option is to set a flag in the search result or search object that registers which interface made the call. I'm not sure how you would go about making a callback in this case.