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?
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!
Every single time I need to create a simply tableview that is populated by a simple data set retrieved from my web server which has its code executed like this: SELECT * FROM table I find myself spending two blady whole hours trying to get the new view controller up and running as I try to update some variable names, copy and paste the required code from my previous view controllers. etc its ridiculous.
This is the end result for all my view controller pages where each will contain different data sets depending on the web service urlĀ being called:
Here is a link:
Link to downloading staple code .h .m and .xib files
This view controller contains a few simple elements seen throughout all data viewing pages:
UITableView
Titled header views
table indices.
refresh table control feature
data connection retrieval code
data connection succeeded
data connection failed
setting up all my bloody delegate and data source methods.
I find myself having to copy and paste all the staple code, functions, variables, properties, and IBOutlets; and to be frank, its getting ridiculously paintaking to have to repeat the same procedure over and over again but changing variable names between the different view controllers.
This is why I believe people create simple component like structures that make it easy for users to get tables setup and up and running.
How can I reduce this big chunk of code:
to something that will allow me at most do this:
Create a new view controller
Setup xib file
create appropriate IBOutlets, and hook them up to the xib.
Here's where it needs to change
I need to now simply able to write something like this the next time I am goin to create another data viewing View Controller:
[self setupTableForDataSetType:]; //This will make sure the tableView knows which data set its dealing with and so therefor know which DataModel classes to use
[self retrieveDataWithWebServerURL:]; //of course so that the connection code can make the right server connection with the URL given for the data set required.
Thats it. So that it is super easy for me to create the tableView pages desired and show the results quickly! Atm I have the same code everywhere in different view controllers.
Whats the best way to go about doing this?
Create a viewcontroller with all your customizable values as properties and reuse changing its values.
Well, subclassing is probably the best (maybe only) way. I've done something like this for tables with an index, since they're a bit of a pain to set up. I created a IndexedTableViewController that handles almost all the load. I make my app table view controller a subclass of that controller, and then I only need to feed a simple array of custom objects to the method, convertArray:usingSectionKey:secondarySortKey:(implemented in the IndexedTableViewController) which creates the sections and the index. The only other method I have to implement in my app table view controller is cellForRowAtIndexPath:(though I would have to implement more, especially didSelectRowAtIndexPath:, if I were doing more things with this table).
Your needs sound a bit more ambitious than this, so it would take quite a bit of work to make a superclass that would be general enough to work with most of your apps. A method like setupTableForDataSetType: could be quite complicated if it needs to handle many different data types.
I'm making a sample app to learn iOS dev, and I have the app create default items to populate the tableview originally, and you can add further ones as well.
If I tap on the default ones (well, there's only one) and segue to the detail view it shows all the details (Name, Location and Date) as intended. But if I add a new one, it comes up with those fields being Empty.
I can't figure out why. I have seemingly all the view refreshing methods set, and it should be setting the detail view's data object which then feeds the labels.
Could anyone help? I'd supply further code if requested, I just don't know what to supply now as I'm not sure exactly where the problem is. It's a rather simple app, though.
Project available here: http://cl.ly/3N0o272M3y1K
Ok this took a bit longer than planned - but it is a good way to learn.
I have attached the project in a zip file.
The code is a bit different then what you posted, but if you compare them side by side, you will see how they are planned and build differently.
It shows the Segue working within the Storyboard.
There where 2 big problems with your project outside of your misuses of the methods.
You need something like Core Data if you want your data to be persistant. In the example I have given you I have used Plist, this will do the trick, but is not persistant in this case.
Also your detailViewController had no labels for the text to appear, so you will need to look into Custom Cells for that - to match your design.
Good Luck and I hope this is useful:-)
Updated Project
I created an iOS app that allowed me to enter data into database and then display in tableview (using NSFetchedResultsController & tableView cellForRowAtIndexPath). This worked. Now, I added 3 one-to-many relationships and another entity and I need to load up the entity (on the one side of the one-to-many) from the db instead of pulling it directly from the db so that the data can be used in the relationships. Do I still use NSFetchedResultsController?
relationshipEntity2 is the one-to-many relationship between Entity1 & Entity2. The many point to Entity2
I know I'm supposed to use:
Entity2 *entity2 = [[self.entity1.relationshipEntity2 allObjects]
objectAtIndex:indexPath.row];
I am new to iOS development and even newer to Core Data but I must learn it. Any bit of help or pointing to a book or tutorial I haven't come across yet would be greatly appreciated. I haven't had much luck finding anything that does what I'm supposed to be doing.
Thanks and have a great week!
-------added for more description on project-------
I'm given the task of having a View Controller with a 3-part segmented button. There is also an add UIButton that pops up a view (bringing subview to the front, not a popover segue) with a UITextField for input to add to the table view on the view controller. There are 2 entities and three 1-to-many relationships. There is 1 relationship for each button on the segmented button. If the user, has the first part of the segmented button selected, adding a value to the popup textbox, should only add it to the table view seen when the first segmented button is selected. I have the CoreDataGeneratedAccessors created. I had this project saving data to database and fetching data to present in the table view but that was before the segmented part was added. Now I have to figure out out to separate the data into "collections" and then show all of say the first collection when the first segment of the segmented button is chosen. I'm just learning and just figured it out without the segmented part and now it's changed on me. I've worked with relational databases but in iOS it seems like it's new again.
Your question is by no means clear. You are not describing any problem, nor do you explain intelligibly what you want to accomplish.
Trying to infer your meaning: yes, you would continue to use your fetchedResultsController. This controller gives you the right object for each indexPath. When building your cell contents, you can easily get to the relationship entities with entity.relationship.
The code above will not work because entity.relationship returns an NSSet which is an unordered group of objects. (The additional allObjects does nothing and is redundant.) Therefore, objectAtIndex will not work (this only works for NSArray objects).
Hope this helps.
I want to have two tables and a webview in one iPad screen from the following:
The first table will parse items from an RSS feed, and will have an option for a
checkmark
The second table will be comprised of all checked items
The webview will be the content from didSelectRowAtIndexPath from the first table (so basically the first table gives the opportunity to display content from didSelectRow, AND check a box (or whatever) to create the secondary table.
I am told for the second table, I should have the checks write to a plist with NSMutableDictionary, and then the second table will just be a table of the plist...but really, what's the code for this?...where do I put it?...etc etc etc. And if the user unchecks the items, the line in the plist will be cleared, right???
I PRESUME I can show all three classes in one screen with something like
[viewController.view addSubview:someOtherViewControler.view];
Is there any reason why I should not do this??
Thanks so much!
XOXO
There is no reason you shouldn't do this, and you will be happier with your proposed approach than you would be if you tried to do it all with one view controller.
Organizing with design patterns is done to simplify design and maintenance of your software. What you have described is clearly three independent data sources each with their own independent views. You can use the MVC design pattern independently on each one of them. This independence lends itself to having separate view controllers that are easy to design and maintain.
The fact that they are collected into one main view for your application is outweighed by the simplification in maintainability that you will obtain with separate view controllers.