ABPersonViewController in Modal - objective-c

I would like to display ABPersonViewController as a modal instead of pushing it on the navigation stack. I've got this working but to keep a done button present I've had to use an NSTimer to add the button every 0.25 seconds because the done button may be removed when the view appears and is always removed when the app enters the forground. This is a pretty lame hack so I'm wondering if anyone has a better idea :)
I made a subclass of ABPersonViewController that adds the done button and starts the timer on view did load and invalidates it when the view is deallocated.
Here is what my code looks like to show the modal:
- (IBAction)showContactModal:(id)sender{
CNABPersonViewController *personViewController = [[CNABPersonViewController alloc] init];
personViewController.displayedPerson = self.contact.record;
personViewController.addressBook = [[CNAddressBookManager sharedManager] addressBook];
personViewController.viewDelegate = self;
personViewController.shouldShowLinkedPeople = YES;
UINavigationController *navigationController =
[[UINavigationController alloc] initWithRootViewController:personViewController];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navigationController animated:YES completion:nil];
}

I had success in doing it like this. Insert this line to add a button to the navigation bar:
personViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:#"Test" style:UIBarButtonItemStylePlain target:self action:#selector(_yourAddressBookAction)];
If this does not solve your problem, please show us the code that you had the issue with.

Related

UINavigationBar, back button, and dismissModalViewController

I have an app that is navigation based, so all views default to have a top nav bar. I have reached a page where a back button is not displayed by default for whatever reason and I was required to add one programatically. Unfortunately, the back button does not dismiss the modal view as expected.
I load the view in question through:
-(IBAction) linkPress:(id)sender
{
potentialUrl = [[NSURL alloc] initWithString:((Button*)sender).emailContent];
webViewInst = [[WebView alloc] initWithNibName:#"WebView" bundle:nil url:potentialUrl];
NSString *deviceType = [UIDevice currentDevice].model;
if([deviceType isEqualToString:#"iPad"] || [deviceType isEqualToString:#"iPad Simulator"]){
[self presentModalViewController:webViewInst animated:YES];
}
else {
[self.navigationController pushViewController:webViewInst animated:YES];
}
}
I add the back button through:
UIBarButtonItem *MKbackBtn = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:self action:#selector(backButton:)];
[self.navigationItem setLeftBarButtonItem:MKbackBtn];
And the action that the back button should take to remove the view and return to the previous view:
-(IBAction)backButton:(id)sender
{
UIViewController* parent = [self parentViewController];
if(parent==nil) {
parent = [self presentingViewController];
}
[parent dismissModalViewControllerAnimated:YES];
}
If another set of eyes could go over these bits of code and try to discern what mistake I have made, that would be greatly appreciated! I am more than willing to provide more information/code as well.
Thanks!
You're calling dismissModalViewControllerAnimated but based on your code above there's a chance that it's not presented as modal and is instead pushed onto the navStack, in which case dismissModalViewControllerAnimated wouldn't actually dismiss it. Instead you would need to do popViewController etc. You should be casing around the presentation means. Can you confirm that this isn't part of the problem?
Also, off the top of my head I think you would call [self dismissModalViewController...] rather than parent.
Displaying a view controller modally does not include it in the navigation controller's stack. You have to provide your own UI mechanism to dismiss the modal view. It looks to me like your solution to dismiss the modal view controller should mostly work--although I think all you need is this one line in backButton::
[self dismissModalViewControllerAnimated:YES];

Change autoresizingMask on programmatically created navigation bar

So I have a view-based app in which I need one page with a tableview and I wanted a navigation bar above it to go back. I added this programmatically with:
-(IBAction)switchToTableView; {
tableView *table = [[tableView alloc] initWithNibName:#"tableView" bundle:nil];
UINavigationController *navControl = [[UINavigationController alloc] initWithRootViewController: table];
table.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[table release];
[self presentModalViewController: navControl animated:YES];
[navControl release];
}
Then in the viewDidLoad of the tableview class I implemented:
- (void)viewDidLoad
{
self.tableView.rowHeight = 70.f;
UIBarButtonItem *back = [[UIBarButtonItem alloc]
initWithTitle:#"Back"
style:UIBarButtonItemStyleDone
target:self
action:#selector(switchToHome)];
self.navigationItem.leftBarButtonItem = back;
UIBarButtonItem *map = [[UIBarButtonItem alloc]
initWithTitle:#"Map"
style:UIBarButtonItemStyleDone
target:self
action:#selector(switchBacktoFindArt)];
self.navigationItem.rightBarButtonItem = map;
[map release];
[super viewDidLoad];
}
to add the needed buttons. Now, all of this worked great, but now that I'm going through my app and allowing for orientation changes, I'm having trouble with this one since I can't change the autoresizingMask in IB. The whole tableview page resizes nicely except the navigation bar becomes very skinny top-to-bottom wise. I'd like it to stay the same height. How do I go about setting the appropriate Masks or even accessing the navigation bar outside of IB?
I suppose you can play with things like this to disable height changes:
navControl.navigationBar.autoresizingMask ^= UIViewAutoresizingFlexibleHeight
But a UINavigationController might really get wonky if you play around with its internals like that. I'm surprised that the nav's bar isn't already resizing to an appropriately pleasing height, like it's supposed to do by default. (It feels like something else might be wrong elsewhere in your code, but I'd have to see more to find out).

How to add a custom button to the Quick Look toolbar in iOS?

I'm currently displaying a PDF file using the Quick Look framework on an iPad via the Modal View Controller. Works great. My problem is that since I'm displaying a PDF file the Quick Look preview is automatically adding a "Print" button. What I would like to do is replace the "Print" button with a custom "Email" button. Is this something that can be done? At first pass I thought this was going to be a somewhat trivial thing to do but at this point I'm really struggling with it. Any help would be greatly appreciated.
Thanks,
Brett
Since QLPreviewController is a subclass of UIViewController, you can take advantage of -[UIViewController setToolbarItems:] to customize the toolbar.
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemReply target:self action:#selector(emailPDF)];
NSArray *items = [NSArray arrayWithObject:item];
[previewController setToolbarItems:items animated:NO];
[[self navigationController] presentModalViewController:previewController animated:YES];
Now when the user taps the "reply" icon in the toolbar, your implementation of -emailPDF will get called.
you can create a subclass of QLPreviewController like MyQLPreviewController
Then in viewWillAppear:(BOOL)animated (IMPORTANT!!)
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIBarButtonItem *rightRatain = self.navigationItem.rightBarButtonItem;
UIBarButtonItem *email = ...;
self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:right, email, nil];
[email release];
}

pushViewController resulting in different behaviour when called in different scenarios

I have the following code which works from my 'scorer' class apart from in the following scenario. I push another viewcontroller editscore, in that view do something, return to scorer pop the editscore and then in some circumstances i will end up pushing my legorderviewcontroller as shown below (it calls the same code). Only this time the new navigation bar is written over the top of the 'scorer' navigation bar and legorderviewcontroller doesn't appear. Does anyone know why this happens in this scenario?
legOrderViewController *controller = [[legOrderViewController alloc] initWithStyle:UITableViewStyleGrouped];
controller.leg = self.leg;
controller.delegate = self;
controller.match =self.match;
controller.set = self.set;
controller.managedObjectContext = self.managedObjectContext;
[self.navigationController pushViewController:controller animated:NO];
controller.playerChangeArray = playerOrder;
[controller release];
This might happen if you call pushViewController too fast after performing popviewcontroller WITH an animation. I ran into that issue once, disabling the animation solved it.

How to change the text of UINavigationBar back button?

I want to ask a question about the iPhone application. I create the UINavigationController programmatically. And I use the UITableView to do the following thing. However, I don't know how to change the text of the text in the back button (see below, in this case is 'Plays') in code level? Thank you very much.
alt text http://www.freeimagehosting.net/image.php?02730817e4.png
Link: http://www.freeimagehosting.net/image.php?02730817e4.png
To customize the back button you modify the view controller you are going back to. So you can either set the title for your "Plays" view controller:
- (void)viewDidLoad {
// ...
[self setTitle:#"Whatever"];
}
Or access the back button item:
- (void)viewDidLoad {
// ...
// target/action must be nil
self.navigationItem.backBarButtonItem =
[[[UIBarButtonItem alloc] initWithTitle:#"Whatever"
style:UIBarButtonItemStyleBordered
target:nil action:nil] autorelease];
}
You have to actually change the text of the back button before pushing the new view controller onto the stack.Otherwise the back button text will not be displayed.
put this in you viewDidLoad, and i think you will get what you need.
UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"yourTitle"
style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backBarButtonItem;
[backBarButtonItem release];