how do i connect a uitableview to a uitableviewcontroller programmatically? - iphone

So i have a:
arrangeList = [[UITableView alloc] initWithFrame:CGRectMake(attributesPadding, y, popoverWidth - 2* attributesPadding, popoverHeight - y - attributesPadding) style:UITableViewStylePlain];
That is the tableview that i want to connect to a controller, and i also have added this tableview to a uiview that i have animate onto the screen in based on a click. So i subclassed uiviewcontroller and created this :
arrangeListViewController = [[[ArrangeListViewController alloc] init] autorelease];
Now how do i make it so that the 'arrangeList' is populated based on 'arrangeListViewController'?
Is this approach way wrong ? any help is welcome

I think you'll want to look at something like:
arrangeListViewController.tableView = arrangeList;
[arrangeList release]; //avoid leaking the arrangeList
Personally, I prefer setting this up in InterfaceBuilder, but it'll work programatically as well.
Hope this helps. Andrew.

Related

UTableView DataSource Setup

Just wondering why we can't we set the data source to UITableview in the below way rather than returning the data count in one method and returning the data for cell in different method.
Why don't we do something like below?.
UITableView *tableView = [UITableView alloc] init];
tableView.datasource = [NSArray arrayWithObjects:#"row1", #"row2", nil];
tableView.cellIdentifier = #"Identifier";
tableView.cell = [UITableViewCell alloc] init];
//delegate methods implemented as properties,
tableView.rowHeight = 50.0;
tableView.headerHeight = 100.0
tableView.headerView = [UIView alloc] init];
[self.view addSubView:tableView];
We can do this right, may not be 100 % correct, we can think of adding some more properties to make the TableView in the same way it works now.
Whey Apple designed the TableView in the way it works now.Helpful if some one could explain the pros and cons of this design with the existing design.
The problem with this implementation is that you are not getting dequeued cell which will spike your's device memory once you reached up to app's allocated maximum level of memory. On every table row, a new cell is created.
Moreover cellForRowIndexPath method gives you flexibility in customising cell based on row index path.
What if you are rendering two different custom cell, which contains different views, how can you differentiate between them without using cellForRowIndex delegate's method.

How to update a progressbar during instantiation of timeconsuming ui elements?

I would like to update a progressbar while i am instantiating some ui elements that takes some times. I first create my view during the viewLoad method and add my progress bar there. Once my view appeared in the viewDidAppear method I am making several uikit objects instantiation but i would like to update the progress bar in the mean time. I am not sure how to proceed since everything should happen in the main thread as it is ui elements.
Here is part of my code:
-(void) viewDidAppear:(BOOL)animated
{
// precompute the source and destination view screenshots for the custom segue
self.sourceScreenshotView = [[UIImageView alloc] initWithImage:[self.view pw_imageSnapshot]];
[self.progressBar setProgress:.3];
SCLViewController *rvc = [[SCLViewController alloc] init];
UIView *destinationView = rvc.view;
destinationView.frame = CGRectMake(0, 0, kWidthLandscape, kHeightLandscape);
self.destinationScreenshotView = [[UIImageView alloc] initWithImage:[destinationView pw_imageSnapshot]];
[self.progressBar setProgress:.5];
}
In the above code I just need to create two screenshots of views to use them later on. The problem is that i only see the last update (.5) when setting the progress to the progress bar. What is the proper way to do this update?
You can use the performSelectorInBackground:withObject: method in order to instantiate your heavy views. That method (the one that instantiates your views) will have to set your progress bar progress in the main thread.
So your code would look something like this:
- (void)viewDidAppear:(BOOL)animated
{
[self performSelectorInBackground:#selector(instantiateHeavyViews) withObject:nil];
}
- (void)instantiateHeavyViews
{
self.sourceScreenshotView = [[UIImageView alloc] initWithImage:[self.view pw_imageSnapshot]];
[self performSelectorOnMainThread:#selector(updateMyProgressView:) withObject:[NSNumber numberWithFloat:0.3f] waitUntilDone:YES];
SCLViewController *rvc = [[SCLViewController alloc] init];
UIView *destinationView = rvc.view;
destinationView.frame = CGRectMake(0, 0, kWidthLandscape, kHeightLandscape);
self.destinationScreenshotView = [[UIImageView alloc] initWithImage:[destinationView pw_imageSnapshot]];
[self performSelectorOnMainThread:#selector(updateMyProgressView:) withObject:[NSNumber numberWithFloat:0.5f] waitUntilDone:YES];
}
- (void)updateMyProgressView:(NSNumber *)progress
{
[self.progressBar setProgress:[progress floatValue]];
}
Edit: of course, it won't animate your progress bar (I don't know if that is what you wanted). If you want it to move on while your views are being created, you should use a delegate to be notified of the progress, and this can be a bit harder. This way you would be able to update the progress bar every time the delegate is notified.

SSCollectionView SSCollectionViewItem - no Items displayed

I ran into difficulties with SSCollectionView and SSCollectionViewItem.
First of all I'd like to get it initialized from IB. But that won't work for me.
I have a SelectFooViewController which is:
#interface SelectFooViewController : SSCollectionViewController { ... }
and am using it as filesOwner of the corresponding XIB.
SelectFooViewController* selectFooVC = [[SelectFooViewController alloc]
initWithNibName:#"SelectFooViewController" bundle:nil];
But since it wont work I had to initialize its properties inside viewDidLoad() myself.
Furthermore I am not able to display anything except the backgroundColor of my SSCollectionViewItems. What I want is a textLabel and an image .
- (SSCollectionViewItem *)collectionView:(SSCollectionView *)aCollectionView itemForIndexPath:(NSIndexPath *)indexPath {
SSCollectionViewItem *item = [[[SSCollectionViewItem alloc] initWithStyle:SSCollectionViewItemStyleImage reuseIdentifier:itemIdentifier] autorelease];
SSLabel* label = [[SSLabel alloc] init];
[label setText:#"foo"];
item.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"foo.png"]];
item.textLabel = label;
[label autorelease];
return item;
}
I can confirm that the delegate methods (for determining the number Of rows, sections and such) are implemented and working as expected. But my items are all empty - but react onclick with the expected popup.
Does anyone see an error in what I did? - Thanks...
EDIT: I was also not able to display a local image by changing SSCatalog project
I just figured out, that I have to set the frame of each property (textLabel, detailTextLabel and imageView) myself. That fixed it.
When you create instance SelectFooViewController just insert this line
selectFooVC.view;
or
selectFooVC.view.hidden = NO;
And then add it to the view.
This is because the view is not initalised until you explicitly access it. Hence your items are loaded only when you click it and not immediately. You can call it a hack but i don't call it one. :-)

In Three20, can I not use custom table cells in a searchViewController?

I'm implementing a TTTableViewController with a searchViewController part, and I'm running into issues when displaying the results of the search in the search's TableView.
If I add TTTableTextItems to the datasource items property, it works fine, but if I try to add a TTTableCaptionItem or a TTTableImageItem or any custom cell I've created, the rendering is messed up.
Can anyone confirm that it's possible to use custom table cells in a searchViewController and perhaps point me in the right direction for how to make it work?
I've attached 3 screen shot to show what's working and what's not working.
No. 1: Works with this code:
[self.items addObject:[TTTableTextItem itemWithText:[item objectForKey:#"title"]]];
No 2. Breaks the layout with this code:
[self.items addObject:[TTTableCaptionItem itemWithText:[item objectForKey:#"title"]
caption:[item objectForKey:#"excerpt"]]];
No. 3 Also breaks the layout with this code:
[self.items addObject:[TTTableImageItem itemWithText:[item objectForKey:#"title"]
imageURL:[item objectForKey:#"thumbnail"]]];
OK, I figured it out. The key is setting the the variableHeightRows property to YES in the TTTableViewController that you're using as the search controller. Below is the code I've used.
TTTableViewController* searchController = [[[TTTableViewController alloc] init] autorelease];
searchController.dataSource = [[[MagazineSearchDataSource alloc] init] autorelease];
searchController.variableHeightRows = YES;
self.searchViewController = searchController;
self.tableView.tableHeaderView = _searchController.searchBar;

Implementing my own navigation controller?

I have a tab bar app. Under one of the tabs i want a uisegmentedControl in the top navigation view, that controls what view is currently displayed. This is dead easy if i just exchange the view, but i want to do it in a more organized and generic way, by using one uiviewcontroller for each view and exchanging them in the most optimzed way.
i guess step one would be to know exactly what a tabbar controller sends to a navigation controller/view controller when a tab is changed, and work it out from there.
Can any one point me in the right direction?
Some time ago I stumbled upon SegmentsController which I found in this blog entry from red artisan.
I used it in conjunction with a UITabBarController, but without knowing I did it wrong. Not wrong as in "it crashs" or "it doesn't do what i want" but wrong in the sense that I have to forward each UIViewController call (like viewDidAppear, receivedMemoryWarning etc) to the child viewControllers. The app with the wrong code is still in the app store and I never received a complain about it.
But I played around a while and figured out how to use it right. It's a bit of a hassle but imho it's absolutely worth it.
I'll show you the correct version that I have right now, I'm creating the UITabBarController in Interface Builder so I have to change the tab in code. Which introduces another piece of mess, and maybe there is room for improvements. But right now I'm satisfied with this solution.
NSMutableArray *items = [self.tabBarController.viewControllers mutableCopy]; // tabs from tabbar configured in IB
// The two child vc that will appear in the segment control
SomeViewController_iPhone *tvcs = [[[SomeViewController_iPhone alloc] initWithNibName:#"SomeView_iPhone" bundle:nil] autorelease];
SomeOtherViewController_iPhone *tvct = [[[SomeOtherViewController_iPhone alloc] initWithNibName:#"SomeOtherView_iPhone" bundle:nil] autorelease];
NSArray *viewControllers1 = [NSArray arrayWithObjects:tvcs, tvct, nil];
// the nav controller acts as a wrapper around the child viewcontrollers
UINavigationController *navController1 = [[[UINavigationController alloc] init] autorelease];
navController1.tabBarItem.title = NSLocalizedString(#"FirstTab", nil);
navController1.tabBarItem.image = [UIImage imageNamed:#"tabImage1.png"];
navController1.navigationBar.tintColor = [UIColor navBarTintColor];
firstTabSegmentsController = [[SegmentsController alloc] initWithNavigationController:navController1 viewControllers:viewControllers1];
// uses a NSArray category that basically creates a NSArray that has the title properties of the vc in viewControllers1
firstTabSegmentedController = [[UISegmentedControl alloc] initWithItems:[viewControllers1 arrayByPerformingSelector:#selector(title)]];
firstTabSegmentedController.frame = CGRectMake(0, 0, 222, 30);
firstTabSegmentedController.segmentedControlStyle = UISegmentedControlStyleBar;
firstTabSegmentedController.selectedSegmentIndex = 0;
[firstTabSegmentsController indexDidChangeForSegmentedControl:firstTabSegmentedController];
[firstTabSegmentedController addTarget:firstTabSegmentsController action:#selector(indexDidChangeForSegmentedControl:) forControlEvents:UIControlEventValueChanged];
// replace first tab from interface builder with this
[items replaceObjectAtIndex:0 withObject:navController1];
as you see it needs a bit of setup, but in my opinion this solution is better than anything else I've tried throughout the time. I hope I de-NDAed the code correctly.
Edit: Uploaded a sample project: BeautifulColors.zip
Just exchanging the views and keeping up with the current view's viewController is the best way to implement a UISegmentedControl in this regard.
Note: by exchanging the views i mean adding a subview to the current view and removing the old one.
You might be interested in the method below, which is implemented by the UITabBarControllerDelegate
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController;