Question on creating TableView without TableViewController (doesn't display!)

Discussion in 'iOS Programming' started by tutiplain, Feb 27, 2011.

  1. tutiplain macrumors member

    Joined:
    Feb 4, 2011
    #1
    Hi everyone,

    I am a newbie to all things Objective-C and iPhone/iPad programming, and this is my first post on this forum. Hopefully you guys will be able to help me. I am trying to create an UITableView control and display some data on it. I've been reading Apple's documentation for it for almost two days now (not full time, of course) and still can't create one. I know there are various approaches, but I chose the one where you don't create a UITableViewController, but instead derive a class from UIiewController and have it adopt the UITableViewDataSource and UITableViewDelegate protocols. However, there seems to be something missing, since I only get an empty Table View when I run the program. I will post my code here:

    Here is the code for my main App Delegate's .h file:
    Code:
    #import <UIKit/UIKit.h>
    #import "MyTVDelegate.h"
    
    @class TableTestViewController;
    
    @interface TableTestAppDelegate : NSObject <UIApplicationDelegate> {
        UIWindow *window;
        //TableTestViewController *viewController;
    	MyTVDelegate *viewController;
    }
    
    @property (nonatomic, retain) IBOutlet UIWindow *window;
    @property (nonatomic, retain) IBOutlet MyTVDelegate *viewController;
    
    @end
    
    
    And it's .m file (I only include this method because it is the only one I modified):
    Code:
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
        
        // Override point for customization after application launch.
    
        // Add the view controller's view to the window and display.
    	[viewController	loadView];
    	[self.window addSubview:viewController.view];
        [self.window makeKeyAndVisible];
    
        return YES;
    }
    
    According to the docs, loadView is supposed to be called automatically, but debugging the program, it seems that it wasn't getting called, so I manually added it. Didn't seem to have any effect, though. I commented it out later.

    Finally, here is the code for the class which acts as the delegate/data source.

    The header file:
    Code:
    #import <Foundation/Foundation.h>
    
    @interface MyTVDelegate : UIViewController <UITableViewDelegate,UITableViewDataSource>
    {
    	NSMutableArray *items;
    }
    @property(nonatomic,retain) NSMutableArray *items;
    @property(nonatomic,retain) IBOutlet UITableView *tView;
    @end
    
    
    And the .m file (again, I've included only those methods overriden, or those necessary for the protocols):

    Code:
    #import "MyTVDelegate.h"
    
    
    @implementation MyTVDelegate
    @synthesize items;
    @synthesize tView;
    
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath * )indexPath
    {
    	static NSString *MyIdentifier = @"MyIdentifier";
    	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    	if (cell == nil) 
    	{ 
    		cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
    	}
    	NSString *texto = [items objectAtIndex:indexPath.row];
    	cell.textLabel.text = texto;
    	return cell;
    }
    
    -(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
    	return [items count];
    }
    
    -(void) loadView
    {
    	[items addObject:@"Item 1"];
    	[items addObject:@"Item 2"];
    	[items addObject:@"Item 3"];
    	
    	UITableView *tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
    	tableView.autoresizingMask =UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    	tableView.delegate =self;
    	tableView.dataSource = self;
    	self.view = tableView;
    	//[tableView release];
    }
    
    @end
    
    From a programmming point of view, everything seems to be set up correctly, but nothing happens when I run the program. I'm thinking that the problem might in the way my xib file is set up. In it, I have a reference to a MyTVDelegate as the File's Owner, with its view outlet set to a reference of a UITableView object present in the same nib file. Its datasource and delegate outlets are unconnected. The project is based on the "View-based Application" template.

    If you guys can help me determine what is wrong here, I would be eternally grateful. Many thanks for any info.
     
  2. KoolStar macrumors demi-god

    KoolStar

    Joined:
    Oct 16, 2006
    Location:
    Kentucky
    #2
    Have you connected all your outlets in interface builder?
     
  3. forum user macrumors regular

    Joined:
    Aug 28, 2008
    #3
    Unless you have a strong reason for wanting to work by remodeling UIViewController I would suggest you use the template in Xcode (the one in 3.2.5, set the check marks for UITableViewController)

    That template will give you an ready made UITableViewController. Before touching it, build and run it. Once you have seen it working, even so it remains empty, start updating the template with your code in cellForRowAtIndexPath

    Code:
    	NSString *texto = [items objectAtIndex:indexPath.row];
    	cell.textLabel.text = texto;
    
    and numberOfRowsInSection.
    Code:
    return [items count];
    
    The setting up of your items array will go into viewDidLoad.

    Code:
    [items addObject:@"Item 1"];
    	[items addObject:@"Item 2"];
    	[items addObject:@"Item 3"];
    
    For a full screen tableview you don't need to mess with delegates and datasources in the template.

    - Olaf
     
  4. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #4
    Start with the nav-based app. You can change the rootview controller's base class from UITableViewController to UIViewController.

    There are a bunch of connections that need to be set up and you've probably forgotten one or more of them.

    PS, never call loadView, the framework calls it for you.
     
  5. tutiplain thread starter macrumors member

    Joined:
    Feb 4, 2011
    #5
    Will try with a template instead

    Hi,

    Thanks everyone for your replies. I only chose the UIVIewController subclassing approach because I'd already tried using the Nav-based template and couldn't get it to work ( though I hadn't read as thoroughly about table views then as I have now). So I guess I'll try and use the template for now. However... I would like, at some point, to understand why what I did doesn't work. Here's an interesting bit: if I set a breakpoint inside the loadView method, the program never stops on it, even when I call it manually. What does that suggest? My guess is that the MyTVDelegate instance is not getting initialized (does @synthesize actually call init on the object?)

    Anyway, I'll try out the nav-based template and post back the results. Again, thanks for all your replies.
     
  6. tutiplain thread starter macrumors member

    Joined:
    Feb 4, 2011
    #6
    addObject does nothing!

    Hi again,

    I tried the nav-based template as suggested. I set it all up as instructed here by forum user, and still the table displays nothing. When I debug, I notice that the calls to addObject: don't seem to do anything:

    Code:
    [items addObject:@"Item 1"];
    [items addObject:@"Item 2"];
    [items addObject:@"Item 3"];
    
    Note that items is an NSMutableArray. It seems like it's getting initialized, since I can see it in the debugger reporting 0 items inside. However, calls to the addObject method don't seem to do anything. No data shows up the debugger inside the "items" array. Note that I placed this code in the viewDidLoad method provided by the template. I have not modified anything else. If you guys can help and suggest what might be wrong here, I will be very grateful.

    Many thanks in advance from a desperate rookie.
     
  7. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #7
    Show the code where you create and assign the items array.
     
  8. tutiplain thread starter macrumors member

    Joined:
    Feb 4, 2011
    #8
    Doesn't @syntesize do that for me?

    I don't call alloc and init for the items array, if that's what you mean. I thought declaring with @property in the .h and @syntesize did that automatically for me. I'll try initializing "manually" and post back the results.

    Thanks for your reply.
     
  9. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #9
    Synthesize only creates accessors. It does not create objects for you.
     
  10. tutiplain thread starter macrumors member

    Joined:
    Feb 4, 2011
    #10
    Ok, thanks for clarifying that for me. I'll do that, then, init the object properly.
     
  11. tutiplain thread starter macrumors member

    Joined:
    Feb 4, 2011
    #11
    It worked!

    Hi again,

    You guys were right. After I [alloc]ed and [init]ed my NSMutableArray (in viewDidLoad), everything worked the way it was supposed to. I can now see a populated table view. I was also able to get it to work using the UIViewController subclassing approach.

    Thanks for your replies. You guys are the best!
     

Share This Page