Three20 TTLauncher and TTTableItem seem to push views differently? - iphone

When I use the TTLauncher to call a TTTableViewController the table is loaded correctly it shows the "Loading..." screen as expected and then the table:
- (void)launcherView:(TTLauncherView*)launcher didSelectItem:(TTLauncherItem*)item {
[[TTNavigator navigator] openURLAction:[TTURLAction actionWithURLPath:item.URL]];
}
However when I call the TTTableViewController from a TTTableSubtitleItem using the URL:
[TTTableSubtitleItem itemWithText:#"Locations Map" subtitle:#"Find a specific location" URL:#"tt://BuildingsLocationTableViewController/Loc"]
the loading screen does NOT show, it waits and then goes directly to the loaded table. Can anyone tell me why these call the TTTableViewController is different ways considering they both map through TTURLMap?
Thanks
JC

The mechanism, as you say, is just the same in both cases.
I would suggest checking your BuildingsLocationTableViewController model definition, and check the isLoadingselector, and the data source titleForLoading selector.
From there, if you debug, you should be able to find out a little more.

Related

Refreshing the content of TabView

Ok I am trying to refresh the tab content of each of my tabs after a web call has been made, and I have tried soo many different methods to do this that I have lost count. Could someone please tell me how this is possible?
The web call just calls JSON from a server and uses it to update the content of the tabs. For testing purposes I have a button set up inside my settings class. Settings class is a view within the home tab which has a button called refresh. When clicked this takes JSON stored on the device which is different to the one called from the web call on application start up. This saves me having to change the JSON on the server.
I will take you through some of the techniques I have tried and would be grateful if someone could tell me what I am doing wrong.
I tried making an instance of the class and calling the refresh method like this
DashboardVC *db = [[DashboardVC alloc] init];
[db refreshMe];
The refresh method in dashboard class is this
-(void) refreshMe
{
[self loadView];
[self viewDidLoad];
}
However no luck. This method will work if I call it inside the Dashboard class, but wont work if I call it from another class. I think it is become I am instantiating a new class and calling refresh on that. So I dropped that technique and moved onto the next method
This loops through all the tabBars and changes the tabTitles without any issues, so it I know it is definitely looping through the ViewControllers properly.
I also tried every varient of the view methods like ViewDidAppear, viewWillAppear etc, no luck.
I also tried accessing the refreshMe method I made in the dashBoard class through the tabController like this
[[[self.tabBarController viewControllers] objectAtIndex:0] refreshMe];
But again no luck, this just causes my application to crash.
I read through this guide
https://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewControllerPGforiOSLegacy/TabBarControllers/TabBarControllers.html
on the apple website but it doesn't seem to cover how to refresh individual tab content.
All I want is to have each individual tab refresh its content after the web call is made, and have spent ages trying to figure this out, but nothing is working.
So would be very grateful if someone could show me what I am doing wrong?
Thanx in advance....
EDIT:
Expand on what I have tried
After discussion with Michael I realised you should never call loadView as against Apple guidelines. So I removed any references to LoadView. I have now placed a method in all the main ViewControllers called RefreshMe which sets up the views, images texts etc in the class. And this method is placed inside the ViewDidLoad. Now I want to be able to call these methods after a web call has taken place, so effectively refreshing the application.
My viewDidLoad now looks like this in all my the main classes.
- (void) viewDidLoad {
[super viewDidLoad];
[self refreshMe];
}
And then the refreshMe method contains the code which sets up the screen.
The JSON data pulled from the web call will set up the content of each of the 5 tabs, so need them all to be refreshed after web call.
I tried looping through the viewControllers and calling viewDidLoad, which should in turn call the refreshMe method which sets up the class, however nothing happens. Code I used was this
NSArray * tabBarViewControllers = [self.tabBarController viewControllers];
for(UIViewController * viewController in tabBarViewControllers)
{
[viewController viewDidLoad];
}
For the time being I have also included
NSLog(#"Method called");
in the viewDidLoad of each class to test if it is being called. However the message is only being printed out when I first load the application or if I re-enter the application. This method should be called after I click the refresh button in the settings screen but it isn't and I have no idea why.
Anyone have any idea why this is not working?
From the question and your comments, it sounds like there are at least two problems:
You're having trouble accessing the view controllers managed by your app's tab bar controller.
You seem to be working against the normal operation of your view controllers.
The first part should be straightforward to sort out. If you have a pointer to an object, you can send messages to that object. If the corresponding method doesn't execute, then either the pointer doesn't point where you think it does or the object doesn't have the method that you think it does. Let's look at your code:
NSArray * tabBarViewControllers = [self.tabBarController viewControllers];
for(UIViewController * viewController in tabBarViewControllers)
{
[viewController viewDidLoad];
}
This code is supposed to call -viewDidLoad on each of the view controllers managed by some tab bar controller. Leaving aside the wisdom of doing that for a moment, we can say that this code should work as expected if self.tabBarController points to the object that you think it does. You don't say where this code exists in your app -- is it part of your app delegate, part of one of the view controllers managed by the tab bar controller in question, or somewhere else? Use the debugger to step through the code. After the first line, does tabBarViewControllers contain an array of view controllers? Is the number of view controllers correct, and are they of the expected types? If the -viewDidLoad methods for your view controllers aren't being called, it's a good bet that the answer is "no," so figure out why self.tabBarController isn't what you think.
Now, it's definitely worth pointing out (as Michael did) that you shouldn't be calling -viewDidLoad in the first place. The view controller will send that method to itself after it has created its view (either loaded it from a .xib/storyboard file or created it programmatically). If you call -viewDidLoad yourself, it'll either run before the view has been created or it'll run a second time, and neither of those is helpful.
Also, it doesn't make much sense to try to "refresh" each view controller's view preemptively. If your app is retrieving some data from a web service (or anywhere else), it should use the resulting data to update its model, i.e. the data objects that the app manages. When a view controller is selected, the tab bar controller will present its view and the view controller's -viewWillAppear method will be called just before the view is displayed. Use that method to grab the data you need from the model and update the view. Doing it this way, you know that:
the view controller's view will have already been created
the data displayed in the view will be up to date, even if one of the other view controllers modified the data
you'll never spend time updating views that the user may never look at
Similarly, if the user can make any changes to the displayed data, you should ensure that you update the model either when the changes are made or else in your view controller's -viewWillDisappear method so that the next view controller will have correct data to work with.
Instead of refreshing your view controllers when updating your tab bar ordering, why not simply refresh your views right before they will appear by implementing your subclassed UIViewController's viewWillAppear: method?
What this means is that each time your view is about to appear, you can update the view for new & updated content.

How to get/set the rootViewController?

Now,I gonna Develop an App ,which wants to switch from many different Views irregularly,also the views need to load large resources,AKA,it's hard to manage memory.Are there any good solustion?
PS:I created a ViewController as RootViewController,and When a button was Touch,run the code as
"ViewController=newController"
.The problem came,The new View loaded wrong way,it rotate so that couldn't show in a correct way.
I google for the solution,some one said ,I should replace the rootViewController,just like that,
[UIApplication sharedApplication].delegate.window.rootViewController=newController;
But I can't get/set the rootViewController in other class though it's a singleton.
Why not having a class that handles all the view switches ?
This article describes an architecture that might be helpfull: http://www.mikeziray.com/2010/01/27/handling-your-initial-view-controllers-for-iphone/comment-page-1/#comment-607

iOS ViewController After Load Method

I'm trying to find a method thats called once everything has been loaded and displayed. The reason I want to do this is because I have some images that take some time to load in so instead of showing them a black screen I want to show a loading page and then call a setup method.
However the only methods I can find are called before the views come into view...
I am probably being really dumb..
Any help would be great.
Disco
You can use
- (void)viewWillLoad;
and
- (void)viewDidAppear:(BOOL)animated;
to do what you need.
How about
- (void)viewDidAppear:(BOOL)animated;

modal view while importing data

I'll start with a confession here... I'm a real newbie to Objective-C & iPhone programming (started studying in February & coding in March), I have a project that's very ambitious for that level of experience & a very tight deadline to catch an opportunity to give my app a field trial.
My app is Core Data driven & downloads all of it's data on first run which is a choice made because it will be used on sites where 3G network access may not be reliable. I'd like to present a modal view while this happens, nothing fancy just a bit of text to explain, a progress bar or activity indicator, a graphic to pretty it up & button becoming visible when the job is done. I've tried a couple of approaches & failed dismally so no code for that as all but the XIB has been trashed.
At the moment I'm running this code in applicationDidFinishLaunching ...
[self checkDataAndLoadIfNeeded];
[window addSubview:rootController.view];
[window makeKeyAndVisible];
rootController is a TabBarController with nested NavigationControllers. checkDataAndLoadIfNeeded is a method that checks a default for the data being loaded & if it is not YES presents an alert. The delegate method for dismissing the alert then a custom class, DataLoader, which goes about downloading & importing the data.
What's happening is that the rootController view becomes visible before the alert does & the table on the first tab doesn't load any data until the next run of the app. I'm wondering if that data not loading is because I'm doing that in viewDidLoad & whether I'd do better to have it in viewWillAppear or viewDidAppear. When I tried loading the modal view I've built my rootController view still became visible first & my modal view didn't become visible until the data had finished (or almost finished) downloading (the Done button became visible immediately).
Can anyone offer suggestions as to how I can make this work?
Cheers & TIA, Pedro :)
Sounds like your rootController is not watching for changes in the data. It should not matter if the element is displayed already or if the data loads first. If the data loads later then the UI element should notice that the data is updated and then refresh itself.
Depending on your app design, you should look at the NSFetchedResultsController class and implement it along with its delegate methods. This class is designed to watch the NSManagedObjectContext for changes and when data is saved out to disk, update its delegate with what has changed.

Help getting dataSource working on OpenFlow

I need help getting dataSource in OpenFlow. I
I want to provide CoverFlow functionality whenever the phone is turned horizontally. I'm using Alex Fajkowski's awesome code OpenFlow ( http://fajkowski.com/blog/2009/08/02/openflow-a-coverflow-api-replacement-for-the-iphone/ ) but the example provided is very different than what I need.
I am using OpenFlow in a horizontal view inside a navbar view controller. I have OpenFlow working already. I can scroll through all my images and works really good. However I am using it with over 100 images and it takes a while to load at first. In looking into performance improvements I realized the AFOpenFlowViewDataSource delegate is not getting called. I was able to get AFOpenFlowViewDelegate working by specifying the delegate in the view controller class "flowView.dataSource = self;". But I am not able to get the datasource delegate working. Not even with "flowView.viewDelegate = self;".
Is the datasource needed at all? It seems it is needed for threading of loading.
Ok, it looks like it is running beautiful now. The DataSource delegate is only called when there the objects are loaded dynamically. Meaning, if I use "[(AFOpenFlowView *)self.view setImage]" then dataSOurce is never called because all it knows images are already loaded. However, using "[(AFOpenFlowView *)self.view setNumberOfImages:30];" triggers the DataSource delegate to load the images as they are needed. I found the GetImageOperation NSThread very useful for my 100+ images. However, images are not unloaded after going offscreen. Anyone know how to unload images as they go off screen?