Populate a tableview with contacts from the addressbook in Xcode 4.3 - iphone

I'm making an app for iPad and iPhone. in the first screen you need to log on, this works. but then i come to the next screen witch is a tableview. i want this view to be al the names (first name and last name) off the adresbook on the iPad or iPhone.
i get the tableview, but it's empty. can somebody help me?
this is my controller (.m, i don't need to edit the .h):
#import "TableViewController.h"
#import "ViewController.h"
#import "AddressBook/AddressBook.h"
#interface TableViewController ()
#end
#implementation TableViewController
{
NSMutableArray *ListOfItems;
}
#synthesize tblContacts;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[self ListContacts];
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)viewDidUnload
{
[self setTblContacts:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)Back:(id)sender{
[self dismissModalViewControllerAnimated:YES];
}
- (void)ListContacts{
/*ABAddressBookRef addressBook = ABAddressBookCreate( );
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );
for ( int i = 0; i < nPeople; i++ )
{
ABRecordRef ref = CFArrayGetValueAtIndex( allPeople, i );
UITableView ContactList
} */
ListOfItems = [[NSMutableArray alloc] init];
[ListOfItems addObject:#"Iceland"];
[ListOfItems addObject:#"Greenland"];
[ListOfItems addObject:#"Switzerland"];
[ListOfItems addObject:#"Norway"];
[ListOfItems addObject:#"New Zealand"];
[ListOfItems addObject:#"Greece"];
[ListOfItems addObject:#"Rome"];
[ListOfItems addObject:#"Ireland"];
self.navigationItem.title = #"Countries";
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [ListOfItems count];
}
// 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] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier];
}
// Set up the cell...
NSString *cellValue = [ListOfItems objectAtIndex:indexPath.row];
cell.text = cellValue;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
#end
notice that i tried to fill my table with some hardcoded values. but again, my table stays empty. Please help.

#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#interface AddressBookViewController: UIViewController <ABPeoplePickerNavigationControllerDelegate> {}
-(IBAction) btnClicked:(id)sender;
#end
This is the AddressBook api to access the contacts application from your own application. Maybe you can use it and it'd be much quicker than to implement your own UITableView and all.
Hope it helps.

Have you set the table's delegate and datasource? You can do it easily through Interface Builder:
Select the table view in Interface Builder.
Go to the Connectors Inspector of the right bar (the last tab, where you link Outlets and Actions).
Link the Data Source and Delegate outlets to the File's Owner (or the file which has the info an methods to manage the table view).
Remember to specify your own class in the File's Owner Identity Inspector (again, in the right bar of Xcode, third tab).
Hope this helps you!

cell.textLabel.text = [listOfItems objectAtIndex:indexpath.row];
and make sure you set the identifier in the attributes to Cell.

This is a year later, but hopefully this will help someone:
It looks like you commented out some very important code underneath your ListContacts method.
Remove the /* and */ under -(void)ListContacts and your code should at least return some values.

Try to use [self.tableView reloadData]; after add data in objects

Related

How to change the style of a UITableViewController programmatically in Xcode

I'm trying to change the style of a UITableViewController to grouped. I know you can do this when creating a new table view, but I have a class that extends UITableViewController, so I don't need to make a new table view. Here's my code:
#import "DetailViewController.h"
#import "NSArray-NestedArrays.h"
#implementation DetailViewController
#synthesize steak, sectionNames, rowControllers, rowKeys, rowLabels;
- (void)viewDidLoad {
sectionNames = [[NSArray alloc] initWithObjects:[NSNull null], NSLocalizedString(#"General", #"General"), nil];
rowLabels = [[NSArray alloc] initWithObjects:
[NSArray arrayWithObjects:NSLocalizedString(#"Steak Name", #"Steak Name"), nil],
[NSArray arrayWithObjects:NSLocalizedString(#"Steak Wellness", #"Steak Wellness"), NSLocalizedString(#"Steak Type", #"Steak Type"), NSLocalizedString(#"Other", #"Other"), nil]
, nil];
rowKeys = [[NSArray alloc] initWithObjects:
[NSArray arrayWithObjects:#"steakName", nil],
[NSArray arrayWithObjects:#"steakWellness", #"steakType", #"other", nil]
, nil];
// TODO: Populate row controllers array
[super viewDidLoad];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [sectionNames count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
id theTitle = [sectionNames objectAtIndex:section];
if ([theTitle isKindOfClass:[NSNull class]]) {
return nil;
}
return theTitle;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [rowLabels countOfNestedArray:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"SteakCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier];
}
NSString *rowKey = [rowKeys nestedObjectAtIndexPath:indexPath];
NSString *rowLabel = [rowLabels nestedObjectAtIndexPath:indexPath];
cell.detailTextLabel.text = rowKey;
cell.textLabel.text = rowLabel;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// TODO: Push editing controller onto the stack
}
#end
- (instancetype)init
{
self = [super initWithStyle:UITableViewStyleGrouped];
if (self) {
}
return self;
}
Not following? What do you mean by you don't have to "make a new table view"?? You still have to instantiate one.
Either you created one already and it has the style you want, or you have to instantiate a new one and set the property on it.
tableView.style is READONLY. So you can't change the style of an existing one. You are going to have to do something like:
[MyTableViewSubClass initWithFrame:aFrame style:UITableViewStyleGrouped];
You can not just change the style of an UITableView. So you only have 2 options:
Make another UITableView which is grouped
Use custom cells
Hope it helps
You would take care of this when you instantiated your view controller.
For example, to instantiate a normal UITableViewController you would do the following.
UITableViewController *tblCtr = [[UITableViewController alloc]initWithStyle:UITableViewStyleGrouped];
Therefore, if you have extended UITableViewController then your init code should take care of this.
MyCustomTableViewController *mctvc = [[MyCustomTableViewController alloc]initWithStyle:UITableViewStyleGrouped];
To achieve this you will need to implement this method in your .m file. Below is an example of what your header and implementation file should contain for instantiation.
Header
#interface MyCustomTableViewController : UITableViewController
{
-(id)initWithStyle:(UITableViewStyle)style;
}
Implementation
#implementation MyCustomTableViewController
-(id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if(self)
{
...
return self;
}
return nil;
}
#end
When you call [super initWithStyle:style] the code provided by apple will take care of building the tableview for you with the requested view style.
You can create a new tableview to overwrite UITableviewController's tableview like this:
UITableView *tableView = [[UITableView alloc] initWithFrame:self.tableView.frame style:UITableViewStyleGrouped];
self.tableView = tableView;
simply buddy to allocate set the frame and style of table ..example code write down.
[tableObject initWithFrame:CGRectMake(x,y,width,height) style:UITableViewStyleGrouped];

UItbaleview Cell json contents not displayed in iOS

I created an app which will fetch info from web service.So far i got it by displaying the contents using NSLog but when i tried to load it in UITableViewCell its not displayed.Here is my code for that
#import "TableViewController.h"
#import "JSON.h"
#import "SBJsonParser.h"
#interface TableViewController ()
#end
#implementation TableViewController
#synthesize jsonurl,jsondata,jsonarray;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
jsonurl=[NSURL URLWithString:#"http://minorasarees.com/category.php"];
jsondata=[[NSString alloc]initWithContentsOfURL:jsonurl];
self.jsonarray=[jsondata JSONValue];
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (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 [jsonarray 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] autorelease];
}
NSLog(#"1");
NSLog(#"%#",jsonarray);
cell.textLabel.text=[jsonarray objectAtIndex:indexPath.row];
NSLog(#"2");
return cell;
}
-(void)dealloc
{
[super dealloc];
[jsonarray release];
[jsondata release];
[jsonurl release];
}
#end
i've inserted tableviewcontroller by adding file with UITableViewController..will that be a problem..Help please..
Your JSON contains an array of dictionaries, so you're setting the text in your table view cell to an dictionary which cannot work since a string is expected. This actually should crash.
To solve that set your text to the category property of that dictionary:
cell.textLabel.text=[[jsonarray objectAtIndex:indexPath.row] valueForKey: #"category"];
besides this there are other things wrong with your code: [super dealloc] needs to be the last thing you call in your dealloc method. And you really should be using asynchronous networking code, blocking the main thread with networking is not acceptable.

How to implement sections in table view containing SQLite database?

So, i have UITableView, large amount of data which is displayed with a many rows, and i want to make sections (like default contacts application and its sections). So there is my code (listViewController.m file):
#import "FailedBanksListViewController.h"
#import "FailedBankDatabase.h"
#import "FailedBankInfo.h"
#import "FailedBanksDetailViewController.h"
#import "BIDAppDelegate.h"
#implementation FailedBanksListViewController
#synthesize failedBankInfos = _failedBankInfos;
#synthesize details = _details;
- (void)viewDidLoad {
self.view.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:#"3.png"]];;
[super viewDidLoad];
self.failedBankInfos = [FailedBankDatabase database].failedBankInfos;
self.title = #"Продукты";
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.failedBankInfos = nil;
self.details = nil;
}
- (void) viewWillAppear:(BOOL)animated
{
}
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [_failedBankInfos count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_failedBankInfos count];
}
// 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:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Set up the cell...
FailedBankInfo *info = [_failedBankInfos objectAtIndex:indexPath.row];
cell.textLabel.text = info.name;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#, %#", info.city, info.state];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.details == nil) {
self.details = [[FailedBanksDetailViewController alloc] initWithNibName:#"FailedBanksDetailViewController" bundle:nil];
}
FailedBankInfo *info = [_failedBankInfos objectAtIndex:indexPath.row];
_details.uniqueId = info.uniqueId;
[self.navigationController pushViewController:_details animated:YES];
}
- (void)dealloc {
self.failedBankInfos = nil;
}
#end
With your code you should have multiple sections (each one exactly equal than the others).
The idea for a multiple section table view is (normally) to have a 2 dimensional array (not 1 dimensional as is your case). Then each row would represent a section for your table view.
For example, if you have an array structured this way (and I know you can't initialize it this way):
arr = {
{'apple','orange','banana'},
{'CD-Rom', 'DVD', 'BR-Disk'},
{'AK-47', 'Rocket launcher', 'Water gun'}
}
your number of sections method may return [arr count] and the number of rows for section s may return [[arr objectAtIndex:s] count]. And remember that you can set the title for each section with the table view datasource method tableView:titleForHeaderInSection:.
If you want to load the info from a SQLite DB, nothing may change. It's exactly the same but you will have to keep of the way to get your data.
When you thing you understand all this stuff then checkout the Core Data framework.

iPhone Multiple UITableView controls on one View

Im having a little issue with using more than 1 UITableView on a view.
Here's what I've done so far (using examples, etc from here and other places):
Created a class for each table. Each class is pretty basic:
.h:
#interface ConstructionDocumentsJobTable : UITableViewController <UITableViewDataSource, UITableViewDelegate> {
NSMutableArray *tableItems;
IBOutlet UITableView *itemsTable;
NSInteger recordSelected;
id <JobTableSelectionDelegate> tableSelectDelegate;
}
#property (nonatomic, retain) NSMutableArray *tableItems;
#property (nonatomic, assign) id <JobTableSelectionDelegate> tableSelectDelegate;
#end
.m:
#implementation ConstructionDocumentsJobTable
#synthesize tableItems, tableSelectDelegate;
#pragma mark -
#pragma mark View Life Cycle
-(void) loadView
{
}
-(void) dealloc
{
[tableItems release];
[super dealloc];
}
#pragma mark -
#pragma mark Table view data source
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [tableItems count];
}
// 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];
}
cell.textLabel.text = [tableItems objectAtIndex:indexPath.row];
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//pass the tap value back to the delegate
}
Both are completely identical, save the names.
When Im making the call to the first one, it is called in the ViewDidLoad method of the controller of the view. It's pretty basic:
NSMutableArray *tableItems = [[NSMutableArray alloc] initWithCapacity:intMax];
//strDocumentType is set elsewhere and loaded here
if(strDocumentType == #"typea"){
[tableItems addObject:#"Type A - Value 1"];
[tableItems addObject:#"Type A - Value 2"];
}
else {
[tableItems addObject:#"Type B - Value 1"];
}
if(jobTableController == nil){
jobTableController = [[ConstructionDocumentsJobTable alloc] init];
[jobTableController loadView];
jobTableController.tableItems = tableItems;
jobTableController.tableSelectDelegate = self;
}
[tableJobList setDataSource:jobTableController];
[tableJobList setDelegate:jobTableController];
jobTableController.view = jobTableController.tableView;
The second table is built when a cell in the first table is selected. So, in the first tables selection method, the delegate is called back from the parent controller, which then has this:
NSMutableArray *tableTypeItems = [[NSMutableArray alloc] initWithCapacity:100];
if(tableSelect == #"plumbing"){
[tableTypeItems addObject:#"Something"];
[tableTypeItems addObject:#"Other"];
}
if(typeTableController == nil){
typeTableController = [[ConstructionDocumentsTypeTable alloc] init];
[typeTableController loadView];
typeTableController.tableItems = tableTypeItems;
typeTableController.tableSelectDelegate = self;
}
[tableTypeList setDataSource:typeTableController];
[tableTypeList setDelegate:typeTableController];
typeTableController.view = typeTableController.tableView;
[typeTableController.tableView reloadData];
//Code to move the first table off the screen and move this one into view goes here
Ive been stuck on this for days, and I really need to get this done!!!
Im sure it's something REALLLLLLY simple.
Any help you guys can pass along would be HUGELY appreciated.
Thanks everyone.
Your only defining itemsTable in your header, try defining another table, and in your cellForRowAtIndexPath try this:
if(itemsTable1){
/* stuff for first table */
} else {
/* stuff for second table */
}
And do the same for each UITableVIew Delegate

having two table views in a single xib one of plain style and the other grouped styled

I want to use two tableviews under the segmentedcontrol. one is plain styled and the other is groupstyled. How can i controll the delegate and datasource for the two table views?
--
Regards,
Syed yusuf
HI,
I have to inserted the data into table view by using sqlite.But now i need that data in to two table views in next view..I have arranged segmented bar.Am getting two table views but the values in r not displaying.It is displaying NULL.
Using multiple or two exclusive table in the save UI view controller sharing the same data source.
I face a problem like this, if anybody needs later...
I try to set my ViewController as a datasource for two different table. But it did not work. 2 tables are exclusively shown at loadtime of the view. Either one will be hidden in viewDidLoad depending on a flag. Seems once dataSource is called for one table, it's not called for the 2nd table. All connections are set in IB.
The solution is to set the dataSource in code in viewDidLoad. Then it works.
-(void) viewDidLoad(){
table1.dataSource = self;
table2.dataSource = self;
if(someCondition == YES)
table1.visible = NO;
else
table2.visible = NO;
}
Since you can't change the UITableViewStyle of a UITableView once created (it can only be set at construction time), you have to have two different instances. You can do this in very different ways, but I've done it this way: add a UISegmentedControl to your interface, and set its target to the RootViewController class instance in your application. The RootViewController class could look like this:
#class DataSource;
#interface RootViewController : UITableViewController
{
#private
UITableView *_originalTableView;
UITableView *_secondaryTableView;
DataSource *_dataSource;
BOOL _showingSecondaryTableView;
}
- (IBAction)swap:(id)sender;
#end
And this might be the implementation:
#import "RootViewController.h"
#import "DataSource.h"
#implementation RootViewController
- (void)dealloc
{
[_dataSource release];
[_originalTableView release];
[_secondaryTableView release];
[super dealloc];
}
- (void)viewDidLoad
{
[super viewDidLoad];
_dataSource = [[DataSource alloc] init];
_secondaryTableView = [[UITableView alloc] initWithFrame:self.tableView.frame
style:UITableViewStyleGrouped];
_secondaryTableView.delegate = _dataSource;
_secondaryTableView.dataSource = _dataSource;
_originalTableView = [self.tableView retain];
_showingSecondaryTableView = NO;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark -
#pragma mark IBAction method
- (IBAction)swap:(id)sender
{
if (_showingSecondaryTableView)
{
self.tableView = _originalTableView;
_showingSecondaryTableView = NO;
}
else
{
self.tableView = _secondaryTableView;
_showingSecondaryTableView = YES;
}
}
#pragma mark -
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (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];
}
cell.textLabel.text = [NSString stringWithFormat:#"RootViewController cell %d", indexPath.row];
return cell;
}
#end
This is the interface of the DataSource class:
#import <UIKit/UIKit.h>
#interface DataSource : NSObject <UITableViewDelegate,
UITableViewDataSource>
{
}
#end
And the implementation:
#import "DataSource.h"
#implementation DataSource
#pragma mark -
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"DataSourceCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [NSString stringWithFormat:#"DataSource cell %d", indexPath.row];
return cell;
}
#end
You can change the datasource and delegate of the UITableView instances to anything you want, at any time during runtime, which might help you encapsulate different data sources with separate controllers.
Hope this helps!