How can I change a ViewController list (by changing predicate) without popping and pushing? - iphone

I have a ViewController whose view results from data from a fetch request with Predicate 1. I'd like to repeat the fetch request with a more restrictive Predicate 2 that will give a SUBSET of the data using Predicate 1.
Then I'd like to update (and possibly animate) that view on the iPhone screen by pressing a toggle button, so that the old and new views expand and collapse the rows. (I don't want to do this modally, as I'd like the user to see which rows came from the old rows.)
I'm thinking of something like the Phone application on the iPhone. Under the "Recents" tab, you'll see "All" and "Missed" buttons. When you press these buttons, it switches between showing all calls and just the missed ones by expanding/collapsing the rows. As far as I can tell, this is not a modal transition.
Can someone give me pointers as to how to do this?

If your view is a UITableView, you can use a combination of
-deleteRowsAtIndexPaths:withRowAnimation:
and
-deleteSections:withRowAnimation:
as well as the corresponding -insert methods, if applicable. You can batch multiple changes (so they animate at the same time) with -beginUpdates and -endUpdates.
I'm not aware of any way you'll be able to do this that doesn't involve iterating over one of the two sets and repeatedly calling -indexForObject on the other, though.

I found a way to expand/collapse rows by changing the heights of each cell, using tableView:heightForRowsAtIndexPath:indexPath:, as in:
http://www.alexandre-gomes.com/?p=482
Hope that's helpful to someone!

Related

How Do You Filter and Sort Data in a CollectionView

I have a CollectionView on a page that is displaying data from a List<> of items. I do sorting and filtering in a code behind on the page by changing the List with LINQ, and then setting the BindingContext of the view, like this:
MyView.BindingContext = FilteredData;
On IOS this works fine, every time, no problem. On Android, I can change the data a few times (it varies - normally three to five) and then the page doesn't display any data. In the debugger I can check and still see the ItemsSource has all of the items, but nothing is displayed. I then "switch" to my other view on the page, which is done by hiding one DataGrid row and showing another, then "switching" back. The data still isn't displayed, but after I do that I can run the code again that does the sorting and filtering and it starts working again - the data is displayed on the page. Not only that, but after I do that, it works every time from that point forward on Android.
I've spent hours trying every thing I can think of to try and find an event or property or anything that would indicate when this problem occurs so I can try and find a work around for it. I'm at a complete loss; wondering if there are suggestions for how to capture and/or fix this problem.
I did find a combination that worked to resolve this issue. I changed the page so that the CollectionView at issue is in the Grid row that has a non-zero (i.e. visible) height when the ContentPage loads. After doing that, the code works as expected. Previously, it was in a Grid.Row whose height was set to an absolute 0 when the page loaded, and then the height was changed to a non-zero value when a button was clicked.
FWIW, this is similar to other issues I've seen with MAUI on Android, where the visibility of certain controls as well as the order in which you modify them can interfere with rendering data binding results.
I solved sorting using a SortedList and made the list items inherit from IComparable, but I don't love the solution because a SortedList is not an ObservableCollection, and because implementing IComparable can be tricky and leaky.

XCode 4 Interface Builder: A better way to work with lots of overlapping views

In IB I have quite a few views that are shown. Many of them are hidden when the app loads, but are shown later when buttons are pressed. This is all fine, but when building this layout in IB it is extremely difficult to layout anything because there are so many overlapping views, some of which are partially transparent (ones that are set to hidden) and other are completely overlapping and covering others. This makes layout very hard.
What is the best method when laying out lots of views like this? Is there another way to break things up? Or better yet, can I hide a a view completely (like in photoshop) so that I can edit the ones underneath, then turn that layer back on?
Another option when trying to select a view that is obscured by another is the shortcut:
'ctrl' + 'shift' and click
It displays a list of all the views under the cursor.
I'm not aware of any way to hide objects in the canvas, but a useful trick for complex layouts is to double-click an item in the document tree to the left - this selects the item and puts focus on the canvas, you can the use the cursor keys to nudge it about.
This doesnt solve the problem of not being able to see things because there are, for example, five or six labels occupying the same space, but if that is the situation it may be a better idea to have a single label and change its contents in code.
I ran into this issue for an app I'm building that has an arial-view image of a park with clickable hotspots. When a hotspot is clicked a popup UIview is displayed with information about that spot in the park. I use the same VC/XIB for three parks. This makes the XIB really busy and hard to work with (i.e the same issue that you have) The detail UIViews make it hard to work with the views underneath. My workaround was to pick each detailed UIView that was hiding the part of the XIB I wanted to work on, and add 1000 to the UIView origin.x in the size inspector. This moved those UIViews enough out of the way for me to do what I needed to with the XIB. Then when I was done, I moved them back by x 1000. (I just needed to move them out horizontally to do what I needed to)
I know its clunky but given that XCode does not have a convenient way to hide portions of an XIB - it was the quickest approach I could think of!
One approach to handling overlapping items in IB is:
Ensure the groups of items that you want to hide are grouped into Views.
Give these Views names: e.g. ViewOptionA, ViewOptionB and ViewOptionC.
Can do this by clicking on name of view in the tree while it is selected and then typing new name.
When you want to hide one of those groups of items:
a) Select the View by either:
i) Clicking on it in the tree at the left or
ii) Ctrl-Shift Clicking in the layout editor and then select the view from the list.
b) In the Attributes Inspector set Alpha to 0.
When you want to unhide one of those groups of items:
As for 2) but set Alpha back to 1
[You do need to remember to unhide all views before you publish!
If you are forgetful like me then perhaps you could subclass UIView and set Alpha to 1. I haven't tried this subclassing idea yet.]

iPhone tableview pagination

First, please believe me when I say I did search for this answer first... a lot. I found many examples, but none performing similarly to what I need. Though I could have been searching using the wrong key words, I don't believe so.
Here is my issue:
I have a table view being populated by a query that is returning a huge amount of data. The data is for a list of restaurants, a price rating, and id. But there are so many restaurants in the database that it fills memory and crashes the app most time. (I am assuming this is what is going on, as the code works just fine if the query is limited, and has always worked on other pages I query things that don't have as much data returned.)
What I would like to do is make pagination for the application's table view for this page. I don't see how I could use the "Show More" method, or the auto load when scrolled to the bottom, simply because if you scroll down to the end of the list, you will still have the same issue: filling memory. Is there a way to do web-like pagination where (if they are not on the first page) they have a "Previous" cell at the top and (if not on the last page) a "Next" cell at the bottom? These would have to clear the cells out in the current view and drop the data so we're not just adding data which would cause the same issue, then do a new query to populate the cells.
Of course, I do not expect someone to sit here and write all that code for me. The main part I would need is just how to set up the cells for the next and previous cells. I should be able to figure the rest out after that, but I don't know how to go about clearing the data from the current table view.
Thanks for any help or suggestions.
I think you can do with a show more method or loading as you scroll, you say the problem is that you still load a bunch all the data and youll run out of memory, but you can avoid that... One option is, save to disk or just release data that isnt being shown on the table view, you can use indexPathsForVisibleRows method of UITableView to see which cells are visible, and with that info you should know which data you can safely release... You can do this either when you receive memory warnings, or maybe as cells are scrolled off the screen (up to you)...
Hope this helps
Daniel

ios UITableView - functioning like a dropdown list

Requirement : implementing a drowdown functionality in an UIView
The known way is using a UIWebView.
My Q is can this be done via a TableView?
Is there any way which lets me select a section(just like selecting a row), so that I can implement a hide/show cells of a section when that particular section is selected?
Don't know if I am understanding you correctly, but it seems to me that what you want can be done like this:
have a UITableView with several sections;
each section has got just one row;
when a specific row for a section is selected (didSelectRowAtIndex), you change the data source associated to that section by adding more elements and reloadData on the table.
when a specific row for a section is selected you also modify the data source corresponding to any other section so that it only contains one row.
EDIT:
From your last comment, it seems to me that what you are trying to do is a generic dropdown menu: you click somewhere and it displays; now, in your specific case you are thinking of clicking on a table, but it could in principle be anywhere else. I am saying this (if I am not wrong), because if it is so, then you can find ready-made implementations, like WEPopover, and you could save some effort.
Going back to your asking, in the case you are mentioning, you can animate the height of the table view frame (or bounds), so that its content is displayed little by little, as the view height increases; have a look at this Tutorial about Core Animations.

Can I implement something similar to iOS "Folders"?

I am going to make something that very visually similar to iOS4 folders but it's not folders at all )))
For example, I have 4 labels on screen - see sketch. Screen splits, if user click on label. Other lebels going down and we can see some text between splited views. If user click once more - view back to "normal" state as before. And so on.
Questions are:
is it confront iPhone HIG and app can be rejected?
what is the easiest way to implement this?
thanks )
alt text http://a.imageshack.us/img196/1306/sketch1.gif
Your App can always be rejected, for no reason at all.
This seems less like folders and more like an outline with collapsable items (or code folding in a programming editor). Plenty of outliner like apps in the store so no reason you should be able to do this (but read the first line of this answer again! No promises!).
Lots of ways to implement this. Here's a random quick one: If you use a UITableView and then have a UITableViewDataSource implementing class that has items marked as hidden/vislble. Then your numberOfRowsInSection method could return only the number of visible rows and the tableView:cellForRowAtIndexPath: would have to skip hidden rows (this might be too slow if you have many items - if so, cache visible count, use secondary array of indexes (or NSMutableIndexSet) of visible items, etc).