I am making an application with a UITableView that has a few sections (2), and when I run, the table view has this annoying gray index bar on the side, like the one in the "iPod" application, that has but 2 options in it. My question is, how do I hide the "index bar," because it is an unnecessary waste of space?
Example:
Code snippets:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [sections count];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return sections;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
return 2;
}
return 1;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [sections objectAtIndex:section];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
cell.textLabel.text = [content objectAtIndex:(indexPath.row + [[sectionAmounts objectAtIndex:indexPath.section] intValue])];
tableView.showsVerticalScrollIndicator = NO;
return cell;
}
- (void)viewDidLoad {
[super viewDidLoad];
content = [NSArray arrayWithObjects:#"Sphere", #"Cylinder", #"Circle", nil];
sections = [NSArray arrayWithObjects:#"3d", #"2d", nil];
sectionAmounts = [NSArray arrayWithObjects:[NSNumber numberWithInt:0], [NSNumber numberWithInt:2], nil]; //Second number is objects in first section... odd huh?
self.tableView.showsVerticalScrollIndicator = NO;
[content retain];
[sections retain];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
(Mind my odd comments...)
HiGuy
I tried this, and it didn't work for me.
so i went through the table view properties, and got this.
self.tableView.showsVerticalScrollIndicator = NO;
works like a charm.
*for any one who wants to do this in the future.
That "scroll bar" is your index bar, assuming you're talking about the giant grey thing.
Return nil from sectionIndexTitlesForTableView: and it'll go away.
I had similar issue, however had to deal with my header/footer. Essentially I just removed the following methods
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #" "; //#"Top";
}
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
return #" "; //#"Bottom";
}
You just use the below code and gray bar will go....
tableViewBrowse.sectionIndexTrackingBackgroundColor = [UIColor clearColor];
Use sectionIndexBackgroundColor property of UITableView to set the color of index bar to clear color as hiding scroll bar is going to hide the indexes as well.
Add it to your viewDidLoad: as following:
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.sectionIndexBackgroundColor = [UIColor clearColor]; //Replace it with your desired color
}
Related
The separator lines on my table view are absent from the view. Need suggestions on what may be the cause. I have checked my storyboard and everything seems to check out. The separator and separator color are both set to default.
As for my code:
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
[self loadObjects];
self->restaurants = [NSArray array];
[self performSelector: #selector(retreiveFromParse)];
[_restaurantTable reloadData];
}
- (void)retreiveFromParse {
PFQuery *retrieveRestaurants = [PFQuery queryWithClassName:#"Restaurants"];
[retrieveRestaurants findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
restaurants = [[NSArray alloc] initWithArray:objects];
NSLog(#"successful");
}
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section {
return [self->restaurants count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath object:(PFObject*)object
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UILabel *title = (UILabel*) [cell viewWithTag:1];
title.text = [object objectForKey:#"title"];
return cell;
}
Update: I solved it by simply deleting the [self loadObjects]; line my viewDidLoad method. The separator lines now show in my view !
The problem might be of separator color itself .By default it is White
so try changing it to another color either in storyboard or by code itself.
[self.tableView setSeparatorColor:[UIColor blackColor]];
When the UITableView is selected in the storyboard, the Separator dropdown should be set to: "Default" or "Single Line"
I have the same issue on simulator for xcode6.1 but it works fine for the device. Have you tried running it on the device?
I'm creating a UITableViewController to list names of people and a star next to their name to indicating favorite people like so
The stars light up when touched, indicting a favorite, the row number of that cell goes into an NSMutableArray which is called in this method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
When I tap a cell and add the index to the array, everything works, until I scroll down, and more stars are filled. They are in random, I believe, a few popup every time I scroll up then down, and look like this, faded stars...
This is the full star
Somehow the stars that shouldn't be filled are faded.
I cannot pin point where the stars are getting switched to on. The log only shows setting the star to on when I scroll to the particular cell.
My problem is that stars are switched on when they should not be, my array is good, I've checked that multiple times, it has to be the UITableView.
This is my code,
I only have two images of that star, one filled and one empty, and the
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// NSLog(#"%i",[[cell.contentView subviews] count]);
// NSMutableArray *array = [[NSMutableArray alloc] initWithArray:[cell.contentView subviews]];
[tableView reloadData];
UIImageView *star = cell.star;
NSLog(#"Star Tag: %i",star.tag);
if (star.tag == kStarEmpty) {
[[Global sharedGlobal].favTeachers addObject:[NSString stringWithFormat:#"%i",cell.identifierTag]];
NSLog(#"Added: %i",cell.identifierTag);
// NSLog(#"setting star image: 1");
[star setImage:[UIImage imageNamed:#"star.png"]];
[star setTag:kStarFilled];
} else if (star.tag == kStarFilled) {
[[Global sharedGlobal].favTeachers removeObject:[NSString stringWithFormat:#"%i",cell.identifierTag]];
NSLog(#"Removed: %i",cell.identifierTag);
// NSLog(#"setting star image: 2");
[star setImage:[UIImage imageNamed:#"star_empty.png"]];
[star setTag:kStarEmpty];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *teacher = [[Global sharedGlobal].teachers objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
UIImageView *starView = [[UIImageView alloc] init];
starView.image = [UIImage imageNamed:#"star_empty.png"];
starView.frame = CGRectMake(720, 2, 29, 29); //748,22
[starView setTag:kStarEmpty];
cell.star = starView;
[cell addSubview:starView];
cell.identifierTag = indexPath.row;
NSLog(#"This cell's identifier tag: %i",cell.identifierTag);
cell.textLabel.text = [[Global sharedGlobal].teachers objectAtIndex:indexPath.row];
for (int i = 0; i < [[Global sharedGlobal].favTeachers count]; i++) {
int favTeacherTag = [[[Global sharedGlobal].favTeachers objectAtIndex:i] intValue];
NSLog(#"%i",i);
NSLog(#"Fav Teacher Tag: %i",favTeacherTag);
if (cell.identifierTag == favTeacherTag) {
NSLog(#"found fav teacher: %i",cell.identifierTag);
NSLog(#"------------------------------------------");
// NSMutableArray *array = [[NSMutableArray alloc] initWithArray:[cell.contentView subviews]];
NSLog(#"setting star image");
[starView setImage:[UIImage imageNamed:#"star.png"]];
NSLog(#"Previous star tag: %i",starView.tag);
[starView setTag:kStarFilled];
break;
}
NSLog(#"--------------------------------");
}
return cell;
}
EXTRA INFO:
I have a custom class for the cells, which adds the cell.identifierTag as an int.
I am using Storyboard
I use static cells in Storyboard
Thank you! If you need any more information please comment and ask.
You need to make sure to set the UIImage to nil in the else block here:
if (cell.identifierTag == favTeacherTag) {
//your existing code
} else {
[starView setImage:nil];
};
This is because the cells are reused, and you may be getting a cell that had previously had the star image added.
call [tableView reloadData] at end of (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath method
After two days of this I finally figured it out. :D
I added this code, because I was using the same UIImageView sometimes and kept adding image views every time this - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath was called.
UIImageView *starView = [[UIImageView alloc] init];
if (cell.star == nil) {
starView.image = [UIImage imageNamed:#"star_empty.png"];
starView.frame = CGRectMake(720, 2, 29, 29); //748,22
[starView setTag:kStarEmpty];
cell.star = starView;
[cell addSubview:starView];
} else if (cell.star != nil) {
starView = cell.star;
}
is it possible to change background image of each sections in uitableview?
I want to add background image for each sections in uitableview
does anyone know how can I do that?
Thanks in advance!
like this picture --> put different background images for wednesday , Thursday and friday separately
Edit I want to add image 1 for wednesday image 2 for Thursday image 3 for friday and .....
how can I specify that ?
Edit
this the code for creating sections header I want to have background also
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if(section == 0)
return #"Monday";
else if(section == 1){
return #"Tuesday";
}else if(section == 2){
return #"Wednesday";
} else if(section == 3){
return #"Thuesday";
} else if(section == 4){
return #"Friday";
} else if(section == 5){
return #"Saturday";
}else
return #"Sunday";
}
You could change the background in the cellForRowAtIndexPath delegate method based on the indexPath, like so:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TaskCellRow";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
int maxRow = 3;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed: [NSString stringWithFormat: #"background_image%i.png", MIN(indexPath.row, maxRow)]]];
}
else
{
UIImageView *background = (UIImageView *)cell.backgroundView;
background.image = [UIImage imageNamed: [NSString stringWithFormat: #"background_image%i.png", MIN(indexPath.row, maxRow)]];
}
return cell;
}
// To change header backgrounds
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
int maxRow = 3;
UIImageView *headerView = [[UIImageView alloc] initWithImage:[UIImage imageNamed: [NSString stringWithFormat: #"background_image%i.png", MIN(section, maxRow)]]];
return headerView;
}
You would then just create images, numbered for the desired amount header/rows, ie. background_image0.png, background_image1.png, background_image2.png, ... and so forth. The MIN will cap the amount off at the whatever you decide is the max backgrounds. Hope that helps.
EDIT: Changed cellForRowAtIndexPath based on Henri's comments. I overlooked that, thanks! This is for ARC compatibility.
You can use:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
to specify any kind of UIView for a section header. This other delegate method:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
lets you specify the height.
Just alloc/init the UIView in the first one using the table's width and the height from the second method and then add any number of views to it, such as a UIImageView for a background then a label for the title.
Iterating (and mostly correcting) example given by ezekielDFM. Note, this code is not ARC compatible (which previous example may have been).
// To change cell backgrounds
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"TaskCellRow";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
int maxRow = 3;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
UIImageView *imageView = [[UIImageView alloc] initWithImage: [UIImage imageNamed: [NSString stringWithFormat: #"background_image%i.png", MIN(indexPath.row, maxRow)]]] autorelease];
cell.backgroundView = imageView;
} else {
// Reusing, we need to swap out the image of the background
cell.backgroundView.image = [UIImage imageNamed: [NSString stringWithFormat: #"background_image%i.png", MIN(indexPath.row, maxRow)]];
}
return cell;
}
// To change header backgrounds
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
int maxRow = 3;
UIImageView *headerView = [[[UIImageView alloc] initWithImage:[NSString stringWithFormat:#"background_image%i.png", MIN(section, maxRow)]] autorelease];
return headerView;
}
As i guess it is not possible to change the background image for Table view Sections. If you want to do such a requirement, please try with cell for row as Sections. i.e. for each row treat as section of table & in that add 1 more table view with different tag. It will full your req. or else for each row take
I have a UITableView in my UITableViewController (lol, obviously) but I need to get a cell at a given index inside the - (void)viewWillAppear:(BOOL)animated method.
Now, my cells are static and I create them in the interface builder. If I call
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:previously_selected_cell.integerValue inSection:0]];
it returns null for the cell. I only have 3 static cells in 1 sections. I tried both sections 0 and 1 and both return null.
Currently I have removed the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method because if I add it, it will clear the UITableView of all my static cells.
Is there a method I can call in - (void)viewWillAppear:(BOOL)animated that will return a cell at a given index?
Thanks in advance!
EDIT: I checked out this stackoverflow question but I'm using static cells without cellForRowAtIndexPath so that question didn't help. :(
EDIT2: I'm trying to set the accessory type of the cell when the view loads. But only on a certain cell, that cell being the one the user selected before he quit the app.
#import "AutoSyncSettings.h"
#import "CDFetchController.h"
#implementation AutoSyncSettings
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
CDFetchController *cdfc = [[CDFetchController alloc] init];
NSFetchedResultsController *results = [cdfc getFetchedResultsControllerWithEntityName:#"SETTINGS"];
NSArray *objects = [results fetchedObjects];
NSNumber *sync_setting;
if(objects.count > 0)
{
NSManagedObject *object = [objects objectAtIndex:0];
sync_setting = [object valueForKey:#"wifi_setting"];
NSLog(#"(Settings)sync_setting: %#",sync_setting);
NSLog(#"(Settings)sync_setting int value: %i",sync_setting.integerValue);
NSLog(#"(Settings)TableView: %#",self.tableView);
//cell is null, even after this.
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:wifi_settings.integerValue inSection:0]];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
//cell is still null. WHY OH WHY? :(
objects = nil;
}
cdfc = nil;
results = nil;
objects = nil;
sync_setting = nil;
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
for (int i = 0; i < [tableView numberOfRowsInSection:indexPath.section]; i++)
{
if([[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:indexPath.section]] accessoryType] == UITableViewCellAccessoryCheckmark)
{
[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:indexPath.section]].accessoryType = UITableViewCellAccessoryNone;
}
}
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
CDFetchController *cdfc = [[CDFetchController alloc] init];
NSFetchedResultsController *results = [cdfc getFetchedResultsControllerWithEntityName:#"SETTINGS"];
NSManagedObjectContext *context = [results managedObjectContext];
NSArray *objects = [results fetchedObjects];
if(objects.count > 0)
{
NSManagedObject *object = [objects objectAtIndex:0];
NSNumber *sync_setting = [NSNumber numberWithInt:indexPath.row];
[object setValue:sync_setting forKey:#"sync_interval"];
[object setValue:[NSNumber numberWithInt:0] forKey:#"id"];
[ErrorHandler saveMoc:context];
}
else
{
//INSERT NEW OBJECT
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:#"SETTINGS" inManagedObjectContext:context];
NSNumber *sync_setting = [NSNumber numberWithInt:indexPath.row];
[object setValue:sync_setting forKey:#"sync_interval"];
[object setValue:[NSNumber numberWithInt:0] forKey:#"id"];
[ErrorHandler saveMoc:context];
}
}
#end
I have a project doing exactly this and it works perfectly. However, it doesn't work unless you call [super viewWillAppear:animated] before trying to access the cells in this manner.
The base implementation presumably loads in the cells from the storyboard.
I want to add a checkmark accessory to the previously selected cell,
the previously_selected_cell variable gets stored even if the app
quits/crashes
The way to go will be to control the indexPath in your cellForRowAtIndexPath implementation and act if it's equal to previously_selected_cell.integerValue:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// usual cache lookup, allocation of the cell, etc
if (indexPath.row == previously_selected_cell.integerValue) {
// add checkbox here
} else {
// remove checkbox
}
}
I am trying to display a list of friends in a UITableView.
I am loading the friends:
- (void)viewDidLoad
{
[super viewDidLoad];
[self apiGraphFriends];
}
Then I am setting my results in:
- (void)request:(FBRequest *)request didLoad:(id)result
{
friends = [[NSMutableArray alloc] initWithCapacity:1];
NSArray *resultData = [result objectForKey:#"data"];
if ([resultData count] > 0) {
for (NSUInteger i=0; i<[resultData count]; i++) {
[friends addObject:[resultData objectAtIndex:i]];
}
} else {
//[self showMessage:#"You have no friends."];
}
}
and I am implementing the required UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [friends count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
//NSManagedObjectModel *friend [fetch
FriendCell *cell = [tableView dequeueReusableCellWithIdentifier: #"friendCell"];
cell.cellName.text = [friends objectAtIndex:indexPath.row];
return cell;
}
The problem is that the method 'cellForRowAtIndexPath' is being called before my data has arrived, how do you prevent the automatic initialization of the table view and only initialyse it when you have data for it ?
The tableview is always loaded on launch. Instead, after the data has finished loading, call
[self.tableView reloadData];
This tells the tableView to refresh, and it calls cellForRowAtIndexPath and all that jazz again.
how do you prevent the automatic initialization of the table view
You don't. The table view will automatically try to load its data when it is created and displayed. But that should not be a problem.
and only initialyse it when you have data for it.
Send a reloadData message to the table view once the data is ready.
Have you remembered to change the number of sections from 0 to at least 1?
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
To fully test this you can use the following code
- (void)viewDidLoad
{
[super viewDidLoad];
//Add your friend as you initialise the array
NSMutableArray *array = [NSMutableArray arrayWithObjects:f1,nil];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.friends count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//change this to whatever you need
NSString *friend = [self.friends objectAtIndex:indexPath.row];
cell.textLabel.text = friend;
return cell;
}
Your numberOfRowsInSection should return 0 if you don't have anything to display. After the data is loaded and ready to display, you should call reloadData on the tableView, and only then should the data be displayed. numberOfRowsInSection should now give the number of rows you loaded.
In short, you don't prevent the tableView from initializing. You initially tell it to display no data, and once your data is loaded, you tell it to display as many rows as you have.
Don't set the tableview delegate and datasource until AFTER you have your data.
i.e.
-(void)viewDidLoad{
[self apiGraphFriends];
self.tableview.delegate = self;
self.tableview.datasource = self;
}
I am assuming your method 'apiGraphFriends' doesn't use any background threading and isn't asynchronous. If it is, then just create a new method and put the datasource/delegate setting in there, then call it from a block in your apiGraphFriends method.
simply call reloadData of the tableView once you got your data, the tableview will reload its data and thus recall all your datasource methods to get its data.
You are so close!
- (void)viewDidLoad
{
[self apiGraphFriends];
[super viewDidLoad];
}
That should do it. If not, you can always call reloadData on the tableView.