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];
}
Related
I trying to write rhodes native extension extension for opening iOS MailComposer.
Now code "works", but MFMailComposeViewController not displaying and xcode shows warning:
Attempt to present <MFMailComposeViewController: 0x12b60840> on <Iosmailto: 0xc1898d0> whose view is not in the window hierarchy!
I read that UIViewControllers must be in hierarchy, but i can't provide this from Rhodes ruby code or clear-C extension wrapper.
Now i'm trying to present my UIViewController with MFMailComposeController from [UIApplication sharedApplication].keyWindow.rootViewController but mail composer not show yet.
interface from iosmailto.h:
#interface Iosmailto : UIViewController<MFMailComposeViewControllerDelegate>
{
}
#property(nonatomic, assign) id delegate;
//-(IBAction)send_mail:(id)sender;
#end
implementation from iosmailto.m:
#implementation Iosmailto
- (void)viewDidLoad {
[super viewDidLoad];
[self send_mail];
}
- (void)send_mail {
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *composer = [[MFMailComposeViewController alloc] init];
composer.mailComposeDelegate = self;
[composer setSubject:[NSString stringWithUTF8String:subj]];
NSArray *recipients_array = [NSArray arrayWithObject:[NSString stringWithUTF8String:recipients]];
[composer setToRecipients:recipients_array];
NSString *composerBody = [NSString stringWithUTF8String:message];
[composer setMessageBody:composerBody isHTML:NO];
[composer setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentModalViewController:composer animated:YES];
[composer release];
} else {
NSLog(#"Device is unable to send email in its current state.");
}
}
/* some unnecessary for this question methods */
#end
And C function defined in iosmailto.m thats called from Rhodes:
// find root vc
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
// find topmost vc
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
iosmailer = [[Iosmailto alloc] init];
iosmailer.delegate = topController;
[topController presentViewController:iosmailer animated:YES completion:nil];
This app is not for AppStore. Hacks is welcome if needed.
Update init for Iosmailto:
- (id)init
{
self = [super initWithNibName:nil bundle:nil];
return self;
}
Update 2 The short version of this code (without UIViewController wrapper) was my starting point. That's don't work too. And this have the same warning and one more:
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *composer = [[MFMailComposeViewController alloc] init];
composer.mailComposeDelegate = (id<MFMailComposeViewControllerDelegate>)topController ;
[composer setSubject:[NSString stringWithUTF8String:subj]];
NSArray *recipients_array = [NSArray arrayWithObject:[NSString stringWithUTF8String:recipients]];
[composer setToRecipients:recipients_array];
NSString *composerBody = [NSString stringWithUTF8String:message];
[composer setMessageBody:composerBody isHTML:NO];
[composer setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[topController presentModalViewController:composer animated:YES];
[composer release];
} else {
}
Use this code to present view controller
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:composer
animated:YES
completion:nil];
Ok I think the problem is that your UIViewController doesn't have anything in its view property because you aren't using a .xib file to initialize it. See this question which programmatically creates a UIView and assigns it to the UIViewController's view property. I think that's the right way to go. See the implementation of their -(void)loadView method.
Your use-case is also a little strange, since it looks like your Iosmailto UIViewController doesn't have any content, and you're just using it as a wrapper around MFMailComposeViewController--you might consider reimplementing your C method to directly create a MFMailComposeViewController without the unnecessary layer of indirection of this unnecessary UIViewController that doesn't display anything itself.
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>
Update 9/2/10: This code no longer works as of the iOS 4 update--it fails with an internal assertion. There is now a great Address Book API example available in the iPhone SDK Reference Library called "QuickContacts."
The example code is available here; it will help you solve this problem:
http://developer.apple.com/iphone/library/samplecode/QuickContacts/Introduction/Intro.html
I'm attempting to add a feature to my app that allows the user to select a contact from an ABPeoplePickerNavigationController, which then displays an ABPersonViewController corresponding to the contact they picked. At that point, I want the user to be able to click on a contact's phone number and have my app respond with custom behavior.
I've got the ABPeoplePickerNavigationController working fine, but I'm running into a problem displaying the ABPersonViewController. I can get the ABPersonViewController to animate onto the screen just fine, but it only displays the contact's photo, name, and company name. None of the contact's other fields are displayed.
I'm using the 'displayedProperties' element in the ABPersonViewController to tell the program to display phone numbers. This creates some strange behavior; when I select a contact that has no phone numbers assigned, the contact shows up with "No Phone Numbers" written in the background (as you'd expect), but when selecting a contact that does have a phone number, all I get is a blank contact page (without the "No Phone Numbers" text).
Here's the method in my ABPeoplePickerNavigationController delegate class that I'm using to create my PersonViewController class, which implements the ABPersonViewController interface:
- (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {
BOOL returnState = NO;
PersonViewController *personView = [[PersonViewController alloc] init];
[personView displayContactInfo:person];
[peoplePicker pushViewController:personView animated:YES];
[personView release];
return returnState;
}
Here's my PersonViewController.h header file:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <AddressBookUI/AddressBookUI.h>
#interface PersonViewController : UIViewController <ABPersonViewControllerDelegate>
{
}
- (void) displayContactInfo: (ABRecordRef)person;
#end
Finally, here's my PersonViewController.m that's creating the ABPersonViewController to view the selected contact:
#import "PersonViewController.h"
#implementation PersonViewController
- (void) displayContactInfo: (ABRecordRef)person
{
ABPersonViewController *personController = [[ABPersonViewController alloc] init];
personController.personViewDelegate = self;
personController.allowsEditing = NO;
personController.displayedPerson = person;
personController.addressBook = ABAddressBookCreate();
personController.displayedProperties = [NSArray arrayWithObjects:
[NSNumber numberWithInt:kABPersonPhoneProperty],
nil];
[self setView:personController.view];
[[self navigationController] pushViewController:personController animated:YES];
[personController release];
}
- (BOOL) personViewController:(ABPersonViewController*)personView shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue
{
return YES;
}
#end
Does anyone have any idea as to why I'm seeing this blank Contact screen instead of one with clickable phone number fields?
Alright, I think I'm getting closer to finding the problem. I'm fairly sure it's with this part of the displayContactInfo call above:
[self setView:personController.view];
When I omit this line, all I see is a blank screen when I click a contact. The ABPeoplePickerNavigationController is pushing the PersonViewController onto the NavigationController stack. The PersonViewController then instantiates an ABPersonViewController object, but for whatever reason the ABPersonViewController never gets properly added to the NavigationController stack.
Does anyone know how to add the ABPersonViewController to the stack, rather than just the PersonViewController?
Just a heads-up to anyone who runs into this problem themselves: I was able to product the correct behavior by instantiating the ABPersonViewController in its delegate's viewDidLoad() method as below:
As before, here's my ABPeoplePickerNavigationController delegate's method:
- (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
BOOL returnState = NO;
PersonViewController *personView = [[PersonViewController alloc] init];
[peoplePicker pushViewController:personView animated:YES];
[personView displayContactInfo:person];
[personView release];
return returnState;
}
Here's my PersonViewController.h (ABPersonViewController delegate) header file:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <AddressBookUI/AddressBookUI.h>
#interface PersonViewController : UIViewController <ABPersonViewControllerDelegate>
{
ABPersonViewController *personController;
}
- (void) displayContactInfo: (ABRecordRef)person;
#end
Finally, here's the delegate's implementation (PersonViewController.m):
#import "PersonViewController.h"
#implementation PersonViewController
- (void) viewDidLoad
{
}
- (void) viewDidUnload
{
[personController release];
}
- (void) displayContactInfo: (ABRecordRef)person
{
personController = [[ABPersonViewController alloc] init];
[personController setDisplayedPerson:person];
[personController setPersonViewDelegate:self];
[personController setAllowsEditing:NO];
personController.addressBook = ABAddressBookCreate();
personController.displayedProperties = [NSArray arrayWithObjects:
[NSNumber numberWithInt:kABPersonPhoneProperty],
nil];
[self setView:personController.view];
}
- (BOOL) personViewController:(ABPersonViewController*)personView shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue
{
// This is where you pass the selected contact property elsewhere in your program
[[self navigationController] dismissModalViewControllerAnimated:YES];
return NO;
}
#end
Hopefully this ends up being helpful for someone. The AddressBook UI framework was a bit tricky for me to wrap my head around (although I'm new to iPhone development so I'm still learning a lot of the nuances of iPhone program organization).
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;
}