Created a View based Project and added a contact to the AddressBook using ABAddressBookRef,ABRecordRef now i wanted to display the added contact ABPersonViewController is the method but how to use in a view based project
Write this piece of code in navigation controller.m:
ABAddressBookRef addressBook= ABAddressBookCreate(); // this will open the AddressBook of the iPhone
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook); // this copies all the contacts from the Address Book into the array
NSString *contactName = [[NSString alloc] init];
// specify the contact name to be edited
contactName = #"ABCD";
for (int i =0 ;i<ABAddressBookGetPersonCount(addressBook);i++){
ABRecordRef ref = CFArrayGetValueAtIndex(people, i);
NSString *firstName = (NSString *)ABRecordCopyValue(ref,kABPersonFirstNameProperty); // this gets the First Name of the person
// check whether the editable contact exists in the AddressBook if exists then allows the user to edit the contact
if ([contactName compare: firstName] == NSOrderedSame) {
ABPersonViewController *personController = [[ABPersonViewController alloc] init];
personController.addressBook = addressBook; // this passes the reference of the Address Book
personController.displayedPerson = ref; // this sets the person reference
personController.allowsEditing = YES; // this allows the user to edit the details
personController.personViewDelegate = self;
personController.navigationItem.rightBarButtonItem = [self editButtonItem]; // this will add the inbuilt Edit button to the view
// this displays the contact with the details and presents with an Edit button
[[self navigationController] pushViewController:personController animated:YES];
[personController release];
}
}
// setEditing method needs to be overridden for edit functionality to work properly
------------------
- (void)setEditing:(BOOL)flag animated:(BOOL)animated {
[super setEditing:flag animated:animated];
if (flag == YES){
// change the view to an editable view
[ [self navigationController] setEditing:YES animated:NO];
}
else {
// save the changes and change the view to noneditable
[ [self navigationController] setEditing:NO animated:NO];
}
}
- (BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue {
return YES;
}
Related
I'm working with the EventKit Framework. It is working almost perfect but I have still some issues. When I push my on an Event, it goes to the details of that Event. It shows correctly the details and I can also edit and save it. The problem is with the navigation bar.
It shows the titles inside the navigation bar.These titles are Event Details and Edit. Also it is not showing a backbutton, to go back to my calendar. What I also should mention is that I'm using the Kal Calendar framework.
I'm pushing to de detailsViewController like this.
Appointment *appointment = [dataSource appointmentAtIndexPath:indexPath];
// Upon selecting an event, create an EKEventViewController to display the event.
self.detailViewController = [[EKEventViewController alloc] initWithNibName:nil bundle:nil];
self.detailViewController.title = #"";
detailViewController.event = appointment.event;
// Allow event editing.
detailViewController.allowsEditing = YES;
[calendar.navigationController pushViewController:detailViewController animated:YES];
And this is how my delegate looks like
// Overriding EKEventEditViewDelegate method to update event store according to user actions.
- (void)eventEditViewController:(EKEventEditViewController *)controller
didCompleteWithAction:(EKEventEditViewAction)action {
NSError *error = nil;
EKEvent *thisEvent = controller.event;
controller.title = #"";
switch (action) {
case EKEventEditViewActionCanceled:
// Edit action canceled, do nothing.
break;
case EKEventEditViewActionSaved:
// When user hit "Done" button, save the newly created event to the event store,
// and reload table view.
// If the new event is being added to the default calendar, then update its
// eventsList.
if (self.defaultCalendar == thisEvent.calendar) {
[self.eventsList addObject:thisEvent];
}
[controller.eventStore saveEvent:controller.event span:EKSpanThisEvent error:&error];
//[calendar reloadData];
break;
case EKEventEditViewActionDeleted:
// When deleting an event, remove the event from the event store,
// and reload table view.
// If deleting an event from the currenly default calendar, then update its
// eventsList.
if (self.defaultCalendar == thisEvent.calendar) {
[self.eventsList removeObject:thisEvent];
}
[controller.eventStore removeEvent:thisEvent span:EKSpanThisEvent error:&error];
//[calendar reloadData];
break;
default:
break;
}
// Dismiss the modal view controller
[controller dismissModalViewControllerAnimated:YES];
}
// Set the calendar edited by EKEventEditViewController to our chosen calendar - the default calendar.
- (EKCalendar *)eventEditViewControllerDefaultCalendarForNewEvents:(EKEventEditViewController *)controller {
EKCalendar *calendarForEdit = self.defaultCalendar;
return calendarForEdit;
}
I came up with this solution:
EKEventEditViewController * controller = [[EKEventEditViewController alloc] init];
controller.eventStore = self.eventStore;
controller.event = result;
controller.title = #"";
controller.navigationItem.title = #"";
controller.navigationItem.titleView = [UIView new];
NSArray * array =controller.navigationBar.items;
UINavigationItem * titleItem = array.firstObject;
titleItem.title = #"";
controller.editViewDelegate = (id)self;
[self presentViewController:controller animated:YES completion:NULL];
The EKEventEditViewController is not embedded in a navigation controller, it has its own UINavigationBar, I keep the navigation item if Apple will change this in the future and embed it in a navigation controller.
i think you have added navigation item on the storyboard or nib file. remove it.
make self.title=nil; or self.title=#"";
Im working on an app which allows the user to select a contact from phone's address book and displays that contact in the UITableView. Im using following code to pick up the contact;
-(IBAction)pickPhoneContacts:(id)sender //opens phone's address book
{
ABPeoplePickerNavigationController *picker =
[[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[self presentViewController:picker animated:YES completion:nil];
}
//called when user presses the cancel button in the Address book view controller
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController*)peoplePicker
{
[self dismissViewControllerAnimated:YES completion:nil];
}
//called when user pics up a contact from the phone's address book
- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
[self displayPerson:person]; //calls displayPerson:(ABRecordRef)person to show contact's information in the app
[self dismissViewControllerAnimated:YES completion:NULL];
return NO;
}
//called when the user selects the property of the contact. This method will not be called in the app but included to complete the implementation of the protocol
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)
peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
return NO;
}
//Displays the contact name and the contact's primary number in the app's text fields (add contact view controller)
- (void)displayPerson:(ABRecordRef)person
{
NSString* name = (__bridge_transferNSString*)ABRecordCopyValue(person,kABPersonFirstNameProperty); //Extracts the contact's first name from address book & assigns it to a string value
self.contactNameTextFiled.text = name;
NSString* phone = nil;
//Extracts the first phone number among multiple contact numbers from address book & assigns it to a string value
ABMultiValueRef phoneNumbers = ABRecordCopyValue(person,kABPersonPhoneProperty);
if (ABMultiValueGetCount(phoneNumbers) > 0)
{
phone = (__bridge_transfer NSString*)
ABMultiValueCopyValueAtIndex(phoneNumbers, 0);
}
else
{
phone = #"[None]";
}
self.primaryNumberTextField.text = phone;
CFRelease(phoneNumbers);
}
Now the task is, as soon as the user pics up a contact from the address book, the ABPeoplePickerNavigator should dismiss and immediately MFMessageComposeViewController should present with a default message and the picked contact number. So that the user of the app should send a message to the picked contact number. I have used following code for message compose view controller;
-(void)sendSMS
{
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if([MFMessageComposeViewController canSendText])
{
controller.body = #"Test Message";
controller.recipients = [NSArray arrayWithObjects:#"111222333", nil];
controller.messageComposeDelegate = self;
[self presentViewController:controller animated:YES completion:nil];
}
}
Now please help me where should I call this method so that the MFMessageComposeViewController should present as soon as the ABPeoplePickerNavigationController dismiss.
Use new function dismissViewControllerAnimated: completion: so after completion call send sms as i have edited your code.
- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
[self displayPerson:person]; //calls displayPerson:(ABRecordRef)person to show contact's information in the app
// [self dismissViewControllerAnimated:YES completion:NULL];
[self dismissViewControllerAnimated:YES completion:^{
[self sendSMS];
}];
return NO;
}
Set animation of your adresscontroller to No when you are dismissing it
[self dismissViewControllerAnimated:NO completion:nil];
Try in
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person;
call
-(void)sendSMS
in dismissViewControllerAnimated:completion: completion handler.
[self dismissViewControllerAnimated:YES completion:{[self sendSMS]}];
Hopes this helps.
in .h file
MFMessageComposeViewController *controller ;
ABPeoplePickerNavigationController *picker;
and in .m just do this
in -(void)sendSMS
{
//other code
[picker presentViewController:controller animated:YES completion:nil];
}
I want to edit record from address book in my iphone app. But I can not edit any record. Here is my code
// In my First View Controller
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *detailViewController=[[DetailViewController alloc] initWithRecordObject:record];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
//------------------------------------
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
#import "User.h"
#interface DetailViewController : UIViewController <UITableViewDelegate,UITableViewDataSource,UIActionSheetDelegate,ABPersonViewControllerDelegate> {
ABRecordRef record;
// Some other ivars
}
- (id)initWithRecordObject:(ABRecordRef)myrecord;
//------------------------------------
#implementation DetailViewController
- (id)initWithRecordObject:(ABRecordRef)myrecord
{
self = [super initWithNibName:#"DetailViewController" bundle:nil];
if (self) {
record = myrecord;
}
return self;
}
#pragma mark - Edit Record Method
-(void)btnEditContactTapped:(id)sender {
// Fetch the address book
ABAddressBookRef addressBook = ABAddressBookCreate();
ABRecordID recID = ABRecordGetRecordID(record);
ABRecordRef record1 = ABAddressBookGetPersonWithRecordID(addressBook,recID);
ABPersonViewController *personViewController = [[ABPersonViewController alloc]init];
// set delegate
personViewController.personViewDelegate = self;
// Allow editing info
personViewController.allowsEditing = YES;
// Display contact info of selected person
personViewController.displayedPerson = record1;
personViewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:self action:#selector(returnFromPersonView)] ;
APP_DELGATE.isContactEdited = YES;
[self.navigationController pushViewController:personViewController animated:YES];
[personViewController release];
}
-(void)returnFromPersonView {
NSLog(#"In %s",__PRETTY_FUNCTION__);
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - ABPersonViewControllerDelegate Method
- (BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue {
//[self dismissModalViewControllerAnimated:YES];
return NO;
}
When I push personViewController , I can't see anything regarding record. Here is a screenshot
Any kind of help is highly appreciated.Thanks
Take a look at Apple's Adress Book Programming Guide. A page that would be useful to you is the Direct Interaction: Programmatically Accessing the Database page. I advise you to just look around at those pages, they are quite self explanatory.
Changing return to YES may help in last method
- (BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue {
//[self dismissModalViewControllerAnimated:YES];
return NO; //try changing it to YES
}
You are not passing the "Correct Contact ID" as ABRecordRef ;)
How can I dismiss the ABPersonViewController? Here is my code
#pragma mark - Edit Record Method
-(void)btnEditContactTapped:(id)sender {
// Fetch the address book
ABAddressBookRef addressBook = ABAddressBookCreate();
ABRecordID recID = ABRecordGetRecordID(record);
ABRecordRef record1 = ABAddressBookGetPersonWithRecordID(addressBook,recID);
ABPersonViewController *personViewController = [[ABPersonViewController alloc]init];
// set delegate
personViewController.personViewDelegate = self;
// Allow editing info
personViewController.allowsEditing = YES;
// Display contact info of selected person
personViewController.displayedPerson = record1;
// Person view controllers must be used with a navigation controller in order to function properly.
UINavigationController *nc = [[UINavigationController alloc]
initWithRootViewController:personViewController];
[self presentModalViewController:nc animated:YES];
[personViewController release];
}
#pragma mark - ABPersonViewControllerDelegate Method
- (BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue {
[self dismissModalViewControllerAnimated:YES];
return NO;
}
record in my ivar declared as ABRecordRef record in .h file.
ABPersonViewControllerDelegate method never gets called? What's going wrong? Any kind of help is appreciated. Thanks
Have you implemented thesse protocols in .h of your project.. ?
< ABPeoplePickerNavigationControllerDelegate,
ABPersonViewControllerDelegate,
ABNewPersonViewControllerDelegate,
ABUnknownPersonViewControllerDelegate>
I am adding contact info from my iPhone application on Addcontact click. I just want to open edit contact window on same Addcontact click so user can edit or delete the contact which just now have added. I have done smthing like below..
- (IBAction)AddContact
{
ABAddressBookRef addressBook = ABAddressBookCreate();
ABRecordRef Showroom = ABPersonCreate();
//adding contact name as showroom name
ABRecordSetValue(Showroom, kABPersonFirstNameProperty, ShowroomName.text , nil);
ABAddressBookAddRecord(addressBook, Showroom, nil);
ABAddressBookSave(addressBook, nil);
// Fetch the address book
//ABAddressBookRef addressBook = ABAddressBookCreate();
// Search for the person named "Appleseed" in the address book
//ABRecordRef Showroom = (ABRecordRef)[Showroom objectAtIndex:0];
ABPersonViewController *picker = [[[ABPersonViewController alloc] init] autorelease];
picker.personViewDelegate = self;
picker.displayedPerson = Showroom;
// Allow users to edit the person’s information
picker.allowsEditing = YES;
[self.navigationController pushViewController:picker animated:YES];
}
this is my Map application. On launching I get showroom results with there contacts. This I can add in to the iPHone contact with edit contact window opening. But when I open other controller to pass user selected string address in to Map controller to search showroom location. The same above code is not working. I mean it only add the contacts but I didnt get the edit contact window.
Edit:
May be this problem is regarding navigation controller bar so check the below code also
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
- (void)viewDidLoad {
[self.navigationController setNavigationBarHidden:NO ];
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:25.0/255.0f green:25.0/255.0f blue:25.0/255.0f alpha:1.0f];
}
- (void)viewWillDisappear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
I hope this code is works for you i implements that code and in my application works fine thank you
contecviewcontroller.h
#interface DetailsViewController : UIViewController
DocumentNavController *coffeeObj;
editViewController *evController;
int currentindex;
}
#property (nonatomic, retain) DocumentNavController *coffeeObj;
#property (readwrite, assign) int currentindex;
#end
contecviewcontroller.m
- (void)viewDidLoad {
[super viewDidLoad];
//self.navigationController.toolbar.tintColor = [UIColor darkGrayColor];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemEdit
target:self action:#selector(goToEdit)]autorelease];
}
-(void)goToEdit{
if(evController == nil)
evController = [[editViewController alloc]initWithNibName:#"editViewController" bundle:nil];
evernoteAppDelegate *appdelegete = (evernoteAppDelegate *)[[UIApplication sharedApplication]delegate];
coffeeObj = [appdelegete.noteArray objectAtIndex:currentindex];
evController.Editcurrentindex = currentindex;
evController.docedObj = coffeeObj;
[self.navigationController pushViewController:evController animated:YES];
}