I'm trying to create a simple create, display and edit contacts in Xcode 4.2 for iOS using AddressBook, so far I have done the create and display function. Now I need to implement edit function along with display. Now when I click on display it displays all the contacts and when I click on any name it shows info with a back button and a cancel button. I need to change the cancel button to edit and call the edit functionality. Below is the code of ViewController.m which I have done so far. Appreciate if u could give me a solution.
#import "ViewController.h"
#import <AddressBook/AddressBook.h>
enum MainMenuChoice
{
menuDisplayContacts,
menuCreateContacts
};
#implementation ViewController
#synthesize menuArray;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *plistPath = [[NSBundle mainBundle] pathForResource:#"Menu" ofType:#"plist"];
NSLog(#"%#",plistPath);
self.menuArray = [NSMutableArray arrayWithContentsOfFile:plistPath];
}
- (void)viewDidUnload {
self.menuArray = nil;
}
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [menuArray count];
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *aCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (aCell == nil) {
// Make the rows look like buttons
aCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
aCell.textLabel.textAlignment = UITextAlignmentCenter;
}
aCell.textLabel.text = [[menuArray objectAtIndex:indexPath.section] valueForKey:#"title"];
return aCell;
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.section) {
case menuDisplayContacts:
[self showContacts];
break;
case menuCreateContacts:
[self createContacts];
break;
default:
[self showContacts];
break;
}
}
//Show list of all people in Contacts
- (void)showContacts {
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc]init];
picker.peoplePickerDelegate = self;
NSArray *displayItems = [NSArray arrayWithObjects:[NSNumber numberWithInt:kABPersonPhoneProperty],[NSNumber numberWithInt:kABPersonEmailProperty], [NSNumber numberWithInt:kABPersonBirthdayProperty],nil];
picker.displayedProperties = displayItems;
[self presentModalViewController:picker animated:YES];
}
// Dismisses the people picker and shows the application when users tap Cancel.
-(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {
[self dismissModalViewControllerAnimated:YES];
}
//For creating new contact when user tap create contacts
-(void)createContacts {
ABNewPersonViewController *picker = [[ABNewPersonViewController alloc]init];
picker.newPersonViewDelegate=self;
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:picker];
[self presentModalViewController:navigation animated:YES];
}
// Dismisses the new-person view controller when user tap cancel.
- (void)newPersonViewController:(ABNewPersonViewController *)newPersonViewController didCompleteWithNewPerson:(ABRecordRef)person {
[self dismissModalViewControllerAnimated:YES];
}
#end
I can get the desired result if I code like this in the tableview didselectRowAtIndexPath property, but I want to implement and integrate this code inside my displayContacts method instead of tableview here. Because this method is for initial screen for display and create contacts. Is there any other way that I could get the indexPath of the current selected names once I am inside the display contacts???
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ABPersonViewController *DVC=[[ABPersonViewController alloc]init];
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL,NULL);
NSMutableArray *allPeople = (__bridge NSMutableArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
int nPeople = ABAddressBookGetPersonCount(addressBook);
for(int i=0;i<nPeople;i++) {
ABRecordRef person = (__bridge ABRecordRef)([allPeople objectAtIndex:i]);
NSString *name = [self.contactAdd objectAtIndex:indexPath.row],*name2;
if(ABRecordCopyValue(person, kABPersonFirstNameProperty) != NULL) {
name2 = [[NSString stringWithFormat:#"%#", ABRecordCopyValue(person, kABPersonFirstNameProperty)]
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
name2=[name2 stringByAppendingString:#" "];
name2=[name2 stringByAppendingString:[[NSString stringWithFormat:#"%#", ABRecordCopyValue(person, kABPersonLastNameProperty)]
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
}
if([name isEqualToString:name2])
{
DVC.displayedPerson=person;
DVC.allowsEditing=YES;
[self.navigationController pushViewController:DVC animated:YES];
break;
}
}
}
-(BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
[peoplePicker dismissModalViewControllerAnimated:NO];
ABPersonViewController *picker = [[ABPersonViewController alloc] init];
picker.personViewDelegate = self;
picker.displayedPerson = person;
// Allow users to edit the person’s information
picker.allowsEditing = YES;
[self.navigationController pushViewController:picker animated:YES];
return YES;
}
Got the solution with help of this function, but now stuck in adding delete function :P
Related
I've created an UITableView with cells and i am trying to add a person's phone and name information into a cell via some functions. The problem is when i try to add a person's info, it is being added into my data array but, i cannot see the new info on UITableView cell. I tried to use reloadData function to reload UITableView, it was no use.
I have arrays for people's numbers and names. Also, i have a button which adds a person via ABPeoplePickerNavigationController.
addedContacts.h :
#import <UIKit/UIKit.h>
#import AddressBook;
#import AddressBookUI;
#interface addedContacts : UIViewController <UITextFieldDelegate, ABPeoplePickerNavigationControllerDelegate, UITableViewDelegate,
UITableViewDataSource>{
NSMutableArray* people;
NSMutableArray* numbers;
IBOutlet UITableView *tableview;
}
- (IBAction)addPerson:(id)sender;
#end
I use commitEditingStyle function to delete a person's information from the tableview. In addition, I keep people's information in defaults of application.
addedContacts.m :
#import "addedContacts.h"
#implementation addedContacts
-(void)viewDidLoad{
[super viewDidLoad];
}
- (IBAction)addPerson:(id)sender {
ABPeoplePickerNavigationController* picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[self presentViewController:picker animated:YES completion:nil];
}
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {
[self dismissViewControllerAnimated:YES completion:nil];
}
-(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person{
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
numbers = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:#"numbers"]];
people = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:#"people"]];
if(numbers.count == 0 && numbers.count == 0){
numbers = [[NSMutableArray alloc] init];
people = [[NSMutableArray alloc] init];
}
NSString *contactName = CFBridgingRelease(ABRecordCopyCompositeName(person));
NSString* nameField = [NSString stringWithFormat:#"%#", contactName ? contactName : #"No Name"];
ABMultiValueRef phoneRecord = ABRecordCopyValue(person, kABPersonPhoneProperty);
CFStringRef phoneNumber = ABMultiValueCopyValueAtIndex(phoneRecord, 0);
NSString* phoneField = (__bridge_transfer NSString *)phoneNumber;
CFRelease(phoneRecord);
[people addObject:nameField];
[numbers addObject:phoneField];
[defaults setObject:people forKey:#"people"];;
[defaults setObject:numbers forKey:#"numbers"];
[self dismissViewControllerAnimated:YES completion:nil];
return NO;
}
-(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Remove the row from data model
[people removeObjectAtIndex:indexPath.row];
[numbers removeObjectAtIndex:indexPath.row];
// Request table view to reload
[tableView reloadData];
}
-(NSInteger) numberOfSectionsInTableView: (UITableView*) tableView{
return 1;
}
-(NSInteger) tableView:(UITableView*) tableView numberOfRowsInSection:(NSInteger)section{
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
numbers = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:#"numbers"]];
return [numbers count];
}
-(UITableViewCell*) tableView: (UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
numbers = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:#"numbers"]];
people = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:#"people"]];
NSLog(#"%#",numbers);
NSLog(#"%#",people);
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
cell.accessoryType = UITableViewCellAccessoryDetailButton;
}
NSLog(#"%ld", (long)indexPath.row);
NSLog(#"%ld", (long)people.count);
NSString* Tname = [people objectAtIndex:indexPath.row];
NSString* Tnumber = [numbers objectAtIndex:indexPath.row];
cell.textLabel.text = Tname;
cell.detailTextLabel.text = Tnumber;
return cell;
}
#end
Any suggestions?
1) this is something strange:
if(numbers.count == 0 && numbers.count == 0){
numbers = [[NSMutableArray alloc] init];
people = [[NSMutableArray alloc] init];
}
i think you mean
if(numbers.count == 0 && people.count == 0)
2) i think you mast insert reload of table after you add your new object into people and numbers arrays
[people addObject:nameField];
[numbers addObject:phoneField];
[tableView reloadData];
My hunch is that, there this a bug in the tableView:numberOfRowsInSection code. You need to return count of people or numbers. Not get the value from the user defaults. Since they don't have the newly added person and number.
-(NSInteger) tableView:(UITableView*) tableView numberOfRowsInSection:(NSInteger)section{
return [numbers count];
}
I want to store address book of iOS in array and display that in UITableView. This is the code I am using. I just want contact name and phone number to be displayed.
pragma mark- address book methods
(BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
ABPeoplePickerNavigationController *picker= [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[self presentModalViewController:picker animated:YES];
return NO;
}
(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person{
ABMultiValueRef phone = (ABMultiValueRef) ABRecordCopyValue(person, kABPersonPhoneProperty);
ABMultiValueRef personID = (ABMultiValueRef) ABRecordCopyValue(person, kABPersonFirstNameProperty);
CFStringRef phoneID = ABMultiValueCopyValueAtIndex(phone, 0);
//CFStringRef personName= ABMultiValueCopyValueAtIndex(personID, 0);
NSLog(#"%#",[NSString stringWithFormat:#"%#", phoneID]);
NSLog(#"%#",[NSString stringWithFormat:#"%#", personID]);
}
Please refer to Rays addressbook tutorial. I think it should answer all your questions.
Why are u calling the picker navigator on beginning of a text? You should call it through a button added as a right bar button item. Then select the persons you want and store them in a mutable array. After that dismiss the controller and load the table view.
Edited:
Please find the code below for your reference. I hope it might help in understanding how it is working. Here is the reference link to the sample code as well.
Interface:
#import <UIKit/UIKit.h>
#interface JSViewController : UITableViewController
#end
Implementation:
#import "JSViewController.h"
#import <AddressBookUI/AddressBookUI.h>
#import <AddressBook/AddressBook.h>
#interface JSViewController ()<ABPeoplePickerNavigationControllerDelegate,UITableViewDataSource,UITableViewDelegate>
#property (nonatomic, strong) NSMutableArray *peopleSelected;
#end
#implementation JSViewController
-(NSMutableArray *)peopleSelected
{
if (!_peopleSelected) {
_peopleSelected = [NSMutableArray new];
}
return _peopleSelected;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIBarButtonItem *selectPerson = [[UIBarButtonItem alloc] initWithTitle:#"Select" style:UIBarButtonItemStyleBordered target:self action:#selector(btnSelectHandler:)];
self.navigationItem.rightBarButtonItem = selectPerson;
}
- (void)btnSelectHandler:(id)sender
{
ABPeoplePickerNavigationController *peoplePicker = [ABPeoplePickerNavigationController new];
peoplePicker.peoplePickerDelegate = self;
[self.navigationController presentViewController:peoplePicker animated:YES completion:^{
}];
}
#pragma mark - ABPeoplePickerNavigationControllerDelegate
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker;
{
[self dismissViewControllerAnimated:YES completion:^{
if (self.peopleSelected) {
[self.tableView reloadData];
}
}];
}
The below method is deprecated in iOS 8.0. You can use the function
- peoplePickerNavigationController:didSelectPerson:
instead of this:
//Deprecated in iOS 8.0.
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
NSString *name = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty));
ABMultiValueRef phoneNumbers = (ABRecordCopyValue(person, kABPersonPhoneProperty));
NSString *mobile = #"";
NSString *label = #"";
for (CFIndex i=0 ; i<ABMultiValueGetCount(phoneNumbers); i++) {
label = (__bridge NSString *)ABMultiValueCopyLabelAtIndex(phoneNumbers, i);
if ([label isEqualToString:(NSString *)kABPersonPhoneMobileLabel]) {
mobile = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phoneNumbers, i);
}else if([label isEqualToString:(NSString*)kABPersonPhoneIPhoneLabel]){
mobile = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phoneNumbers, i);
break;
}
}
NSDictionary *dict = #{#"name":name,
#"phone":mobile};
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self.phone == %# && self.name == %#",mobile,name];
NSArray *personAlready = [self.peopleSelected filteredArrayUsingPredicate:predicate];
NSLog(#"personAlready %#",personAlready);
if (!personAlready.count) {
[self.peopleSelected addObject:dict];
}
return NO;
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
return YES;
}
#pragma mark - UITableViewDataSource
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.peopleSelected.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
NSDictionary *dict = self.peopleSelected[indexPath.row];
cell.textLabel.text = dict[#"name"];
return cell;
}
#pragma mark - UITableViewDelegate
#end
*Update: This actually works, the style for my custom cell hasn't come across and so the cell looks blank. How then do I get the searchResultsTableView to use my custom cell?
I have implemented a search bar in my table view. Searching, filtering all work when I debug, but when I enter characters into the search bar, the results do not load or show. This is everything I'm doing:
#interface InviteTableViewController ()<UIAlertViewDelegate, UISearchBarDelegate, UISearchDisplayDelegate>
#property(nonatomic, strong) NSNumber *contactsCount;
#property(nonatomic, strong) InviteTableViewCell *selectedCell;
#property(strong, nonatomic) NSMutableArray *filteredContactArray;
#property (weak, nonatomic) IBOutlet UISearchBar *contactsSearchBar;
#end
#implementation InviteTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void) extractAllContacts: (ABAddressBookRef) addressBookRef{
NSMutableArray *contactsArray = [NSMutableArray array];
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBookRef);
CFIndex numberOfPeople = ABAddressBookGetPersonCount(addressBookRef);
for(int i = 0; i < numberOfPeople; i++){
ABRecordRef person = CFArrayGetValueAtIndex( allPeople, i );
NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty));
if(firstName){
ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(emails); i++) {
NSString *email = (__bridge_transfer NSString *) ABMultiValueCopyValueAtIndex(emails, i);
MyUser *amUser = [[MyUser alloc] init];
amUser.email =email;
NSString *fullName =[NSString stringWithFormat:#"%# %#",firstName, (__bridge NSString *)(ABRecordCopyValue(person, kABPersonLastNameProperty))];
amUser.fullName = fullName;
[contactsArray addObject:amUser];
}
}
}
NSLog(#"================================count ============= %d", [contactsArray count]);
contactsArray = [contactsArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSDate *first = [(MyUser*) a fullName];
NSDate *second = [(MyUser*)b fullName];
return [first compare:second];
}];
self.inviteContactsArray = contactsArray;
self.filteredContactArray = [NSMutableArray arrayWithCapacity:[contactsArray count]];
[self.tableView reloadData];
}
- (void)viewDidLoad
{
[super viewDidLoad];
_contactsCount = [NSNumber numberWithInt:0];
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
if (granted) {
[self extractAllContacts: addressBookRef];
[self.tableView reloadData];
} else {
NSString *message = [NSString stringWithFormat:#"You have not given permission to use your address book. Please allow in settings "];
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Enable Contacts" message:message delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
});
}
else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
// The user has previously given access, add the contact
[self extractAllContacts:addressBookRef];
}
else {
// The user has previously denied access
// Send an alert telling user to change privacy setting in settings app
}
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [self.filteredContactArray count];
} else {
return [self.inviteContactsArray count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"InviteCell";
InviteTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if ( cell == nil ) {
cell = [[InviteTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
MyUser *person = nil;
if (tableView == self.searchDisplayController.searchResultsTableView)
{
person = [self.filteredContactArray objectAtIndex:[indexPath row]];
NSMutableArray *tempArray = self.filteredContactArray;
}
else
{
person = [self.inviteContactsArray objectAtIndex:[indexPath row]];
}
//InviteTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
person = [self.inviteContactsArray objectAtIndex:indexPath.row];
cell.nameLabel.text = person.fullName;
cell.emailLabel.text = person.email;
return cell;
}
#pragma mark Content Filtering
-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
// Update the filtered array based on the search text and scope.
// Remove all objects from the filtered search array
[self.filteredContactArray removeAllObjects];
// Filter the array using NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.fullName contains[c] %#",searchText];
self.filteredContactArray = [NSMutableArray arrayWithArray:[self.inviteContactsArray filteredArrayUsingPredicate:predicate]];
}
#pragma mark - UISearchDisplayController Delegate Methods
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
#end
This is what it looks like:
Agree with #rdelmar.
BUT There is a kind of tricky behavior in TableView, if you change the code in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
....
InviteTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
....
}
to
InviteTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if added the prefix "self." your code should works fine.
and
if ( cell == nil )
{
cell = [[InviteTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
is unnecessary. it will just create a standard "Subtitle Cell" for you that seems not you want, just remove them.
If you want to use the same cell for your main table and the search results table, you should make the cell in a xib (or you could do it entirely in code). In viewDidLoad, register the nib for both table views,
- (void)viewDidLoad {
[super viewDidLoad];
[self.searchDisplayController.searchResultsTableView registerNib:[UINib nibWithNibName:#"InviteTableViewCell" bundle:nil] forCellReuseIdentifier:#"InviteCell"];
[self.tableView registerNib:[UINib nibWithNibName:#"InviteTableViewCell" bundle:nil] forCellReuseIdentifier:#"inviteCell"];
}
In cellForRowAtIndexPath, you can do something like this,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
InviteTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"InviteCell" forIndexPath:indexPath];
MyUser *person = ([tableView isEqual:self.tableView])? self.inviteContactsArray[indexPath.row] : self.filteredContactArray[indexPath row];
cell.nameLabel.text = person.fullName;
cell.emailLabel.text = person.email;
return cell;
}
If you've already setup your cell in the storyboard, you can copy and paste it into an empty xib file, so you don't have to set it up all over again. You can delete the cell from your storyboard table view since you will be getting the cell from the xib file instead.
Below line in viewdidload should do the trick
self.searchDisplayController.searchResultsTableView.rowHeight = self.tableView.rowHeight
I have a tableview loaded withe records, see the code below:
- (void)viewDidLoad
{
self.navigationItem.title=#"Accounts";
// NSString *accountFile = [[NSBundle mainBundle] pathForResource:#"Accounts2" ofType:#"plist"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [paths objectAtIndex:0];
NSString *plistPath = [documentPath stringByAppendingPathComponent:#"Accounts2.plist"];
accounts = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];
NSLog(#"Accounts contains : %#", accounts);
account = [accounts objectForKey:#"Account"];
NSLog(#"account %#", account);
number = [accounts objectForKey:#"Number"];
dueDay = [accounts objectForKey:#"DayDue"];
minAmount = [accounts objectForKey:#"MinAmount"];
balance = [accounts objectForKey:#"Balance"];
NSLog(#"data loaded");
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)insertNewObject:(id)sender
{
// if (!_objects) {
// _objects = [[NSMutableArray alloc] init];
// }
// [_objects insertObject:[NSDate date] atIndex:0];
// NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
// [self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
if (!self.addView) {
self.addView = [[AddView alloc] initWithNibName:#"AddView" bundle:nil];
}
[self.navigationController pushViewController:self.addView animated:YES];
NSLog(#"I am done, now what");
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"Number of records is %d", [account count]);
return [account 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];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
NSDate *object = _objects[indexPath.row];
cell.textLabel.text = [object description];
NSString *nameOfAccount = [account objectAtIndex:indexPath.row];
cell.textLabel.text = nameOfAccount;
NSString *accountNumber = [number objectAtIndex:indexPath.row];
cell.detailTextLabel.text = accountNumber;
NSLog(#"Index %d", indexPath.row);
return cell;
}
I want to add a record to table, so I use the "InsertNewObject" method ... new screen appears, I am able to add the record to my plist, and then I execute the following line in the DetailView to return:
[self.navigationController popToRootViewControllerAnimated:NO];
Now, I want to reload my TableView with my new record:
I thought I just had to have the following viewWillAppear method like below:
- (void) viewWillAppear {
NSLog(#"View will appear");
[super viewWillAppear:YES];
[self.tableView reloadData];
}
but, my NSLog is never executed, therefore my program is never getting here... am I doing something incorrectly, thank you for any response
I have added the following two methods:
- (void) navigationController:(UINavigationController *) navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
[self.tableView reloadData];
}
-(void) navigationController:(UINavigationController *) navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
[self.tableView reloadData];
}
and changed the line
[self.navigationController popToRootViewControllerAnimated:YES];
still not working, is something still wrong.
You are not using the correct method. You are leaving out the animated argument, try using -(void)viewWillAppear:(BOOL)animated:
See UIViewController - viewWillAppear:
- (void)viewWillAppear:(BOOL)animated {
NSLog(#"View will appear");
[self.tableView reloadData];
[super viewWillAppear:animated];
}
if you are using a nav controller I belive the correct way to reload a view would be to call somethihng like this
-(void) viewWillAppear: (BOOL) animated
{
[self.tableView reloadData];
}
You could also create your own custom reloadData method that sets what you want changed and then call that method.
As pointed out, viewWillAppear takes an animated argument. However, even when you add that, popping a view controller off the navigation stack does not trigger a call to viewWillAppear:. You need to use UINavigationControllerDelegate's navigationController:willShowViewController:animated: and navigationController:didShowViewController:animated: methods to reload your table view.
I'm a beginning programmer. And I had a question.
I currently have a Table View in my app. There are three rows to it, History, Theory, and Applied Use. I would like each one to go to a different detail view. However, each one only clicks to one of the detail views.
I think the issue is at
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"Magnets_AU_Aubrey" bundle:[
Please help any. The three XIB's are Magnets_AU_Aubrey, Magnets_History_Aubrey, and Magnets_Theory_Aubrey
#import "DisclosureButtonController.h"
#import "NavAppDelegate.h"
#import "DisclosureDetailController.h"
#import "DetailViewController.h"
#implementation DisclosureButtonController
#synthesize list;
- (void)viewDidLoad {
NSArray *array = [[NSArray alloc] initWithObjects:#"History", #"Theory", #"Applied Use", nil];
self.list = array;
[array release];
[super viewDidLoad];
}
- (void)viewDidUnload {
self.list = nil;
[childController release], childController = nil;
}
- (void)dealloc {
[list release];
[childController release];
[super dealloc];
}
#pragma mark -
#pragma mark Table Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [list count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * DisclosureButtonCellIdentifier =
#"DisclosureButtonCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
DisclosureButtonCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:DisclosureButtonCellIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
NSString *rowString = [list objectAtIndex:row];
cell.textLabel.text = rowString;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
[rowString release];
return cell;
}
#pragma mark -
#pragma mark Table Delegate Methods
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"Magnets_AU_Aubrey" bundle:[
NSBundle mainBundle]];
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
dvController = nil;
}
- (void)tableView:(UITableView *)tableView
accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
if (childController == nil) {
childController = [[DisclosureDetailController alloc] initWithNibName:#"MagnetsAubreyCreditsDisclosureDetail" bundle:nil];
}
childController.title = #"Disclosure Button Pressed";
NSUInteger row = [indexPath row];
NSString *selectedMovie = [list objectAtIndex:row];
NSString *detailMessage = [[NSString alloc]
initWithFormat:#"School",selectedMovie];
childController.message = detailMessage;
childController.title = selectedMovie;
[detailMessage release];
[self.navigationController pushViewController:childController animated:YES];
}
#end
NSArray *array = [[NSArray alloc] initWithObjects:#"History", #"Theory", #"Applied Use", nil];
Now do the same for xibs. Create array and fill it with xib names. Then in didSelectRowAtIndexPath to get correct xib name apply the same logic as you do in cellForRowAtIndexPath for getting cell text.