I am trying to enabling the editing of a Contact in a universal app, with a ABPersonViewController displayed in a UIPopoverController. The person does get displayed, but there is no Edit button. In actual fact, I would prefer it if the user saw the details already in an Editable form, but it would be ok if they could do the edit after hitting the Edit button. On the iPhone, it works fine. Can anyone help, please.
ABPersonViewController *view = [[ABPersonViewController alloc] init];
view.personViewDelegate = self;
ABAddressBookRef addressBook = ABAddressBookCreate();
ABRecordRef contact = ABAddressBookGetPersonWithRecordID(addressBook,(ABRecordID)recId);
view.displayedPerson = contact;
view.displayedProperties = [NSArray arrayWithObjects:[NSNumber numberWithInt:kABPersonFirstNameProperty], [NSNumber numberWithInt:kABPersonLastNameProperty], [NSNumber numberWithInt:kABPersonAddressProperty], nil];
view.allowsEditing = YES;
view.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Back",nil) style:UIBarButtonItemStylePlain target:self action:#selector(ReturnFromPersonView)] ;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
UIPopoverController *addressPopup;
addressPopup = [[UIPopoverController alloc] initWithContentViewController:view];
addressPopup.delegate = self;
self.popoverController = addressPopup;
[addressPopup release];
[self.popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
else
{
[self.navigationController pushViewController:view animated:YES];
}
if (addressBook) CFRelease(addressBook);
[view release];
You need to add your ABPersonViewController *view explicitly to a UINavigationController.
ABPersonViewController *view = [[ABPersonViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:view];
UIPopoverController *personViewPopover = [[UIPopoverController alloc] initWithContentViewController:navController];
Related
I have a UINavigationController as the root view controller of an app.
At some point I need to push a UITabController with specific tabs.
Up to this point it all works.
However in the tab view controllers I can't access the UINavigationController navBar (to change title, tint, etc).
Here is how I push it:
SCTabController *TabController = [[SCTabController alloc] init];
[self.navigationController pushViewController:TabController animated:YES];
SCTabController is a subclass of UITabController with the following viewDidLoadMethod:
- (void)viewDidLoad {
[super viewDidLoad];
UIViewController *view1 = [[UIViewController alloc] init];
UIViewController *view2 = [[UIViewController alloc] init];
UIViewController *view3 = [[UIViewController alloc] init];
UIViewController *view4 = [[UIViewController alloc] init];
NSMutableArray *tabViewControllers = [[NSMutableArray alloc] init];
[tabViewControllers addObject:view1];
[tabViewControllers addObject:view2];
[tabViewControllers addObject:view3];
[tabViewControllers addObject:view4];
[self setViewControllers:tabViewControllers];
//can't set this until after its added to the tab bar
bankHomeViewController.tabBarItem =
[[UITabBarItem alloc] initWithTitle:#"Title1"
image:nil
tag:1];
view2.tabBarItem =
[[UITabBarItem alloc] initWithTitle:#"Title2"
image:nil
tag:2];
view3.tabBarItem =
[[UITabBarItem alloc] initWithTitle:#"Title3"
image:nil
tag:3];
view4.tabBarItem =
[[UITabBarItem alloc] initWithTitle:#"Title4"
image:nil
tag:4];
In my project I have done so :
add UITabBarControllerDelegate
#interface SCTabController : UITabBarController<UITabBarControllerDelegate>
#end
then add below code in viewDidLoad in SCTabController.m
self.delegate = self;
implement UITabBarControllerDelegate didSelectViewController in SCTabController.m
-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
//Write your code here
//NSLog(#"%lu", (unsigned long)self.selectedIndex);
UILabel *functionTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 190, 50)];
[functionTitleLabel setTextAlignment:NSTextAlignmentCenter];
switch (self.selectedIndex) {
case 0:
[functionTitleLabel setText:#"title1"];
break;
case 1:
[functionTitleLabel setText:#"title2"];
break;
case 2:
[functionTitleLabel setText:#"title3"];
break;
default:
[functionTitleLabel setText:#"title4"];
break;
}
self.navigationItem.titleView = functionTitleLabel;
}
I have a tutorial ViewController called tutorialViewController which only presents itself for the first time the app is launched. This is how I do that:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
BOOL hasRunBefore = [defaults boolForKey:#"FirstRun"];
if (!hasRunBefore) {
[defaults setBool:YES forKey:#"FirstRun"];
self.window.rootViewController = [tutorialViewController new];
self.window.backgroundColor = [UIColor whiteColor];
// RESideMenu Stuff that Must Be Done
leftSideMenuViewController *leftMenuViewController = [[leftSideMenuViewController alloc] init];
rightSideMenuViewController *rightMenuViewController = [[rightSideMenuViewController alloc] init];
musicPlayerViewController *navigationController = [[homeViewController alloc] init];
RESideMenu *sideMenuViewController = [[RESideMenu alloc] initWithContentViewController:navigationController
leftMenuViewController:leftMenuViewController
rightMenuViewController:rightMenuViewController];
sideMenuViewController.menuPreferredStatusBarStyle = 1;
sideMenuViewController.delegate = self;
sideMenuViewController.contentViewShadowColor = [UIColor blackColor];
sideMenuViewController.contentViewShadowOffset = CGSizeMake(0, 0);
sideMenuViewController.contentViewShadowOpacity = 0.6;
sideMenuViewController.contentViewShadowRadius = 12;
sideMenuViewController.contentViewShadowEnabled = YES;
self.window.backgroundColor = [UIColor blackColor];
}
else
{
NSLog (#"Not the first time this controller has been loaded");
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[[homeViewController alloc] init]];
// RESideMenu Stuff that Must Be Done
leftSideMenuViewController *leftMenuViewController = [[leftSideMenuViewController alloc] init];
rightSideMenuViewController *rightMenuViewController = [[rightSideMenuViewController alloc] init];
RESideMenu *sideMenuViewController = [[RESideMenu alloc] initWithContentViewController:navigationController
leftMenuViewController:leftMenuViewController
rightMenuViewController:rightMenuViewController];
sideMenuViewController.menuPreferredStatusBarStyle = 1;
sideMenuViewController.delegate = self;
sideMenuViewController.contentViewShadowColor = [UIColor blackColor];
sideMenuViewController.contentViewShadowOffset = CGSizeMake(0, 0);
sideMenuViewController.contentViewShadowOpacity = 0.6;
sideMenuViewController.contentViewShadowRadius = 12;
sideMenuViewController.contentViewShadowEnabled = YES;
self.window.rootViewController = sideMenuViewController;
self.window.backgroundColor = [UIColor blackColor];
}
This works well so far - if I load the app for the first time, it shows tutorialViewController. If I close it and open it again, it shows homeViewController.
I'd just like to know how to add an IBAction to take me from tutorialViewController to homeViewController. Currently, I wrote this:
- (IBAction)goToHomeViewController:(id)sender {
homeViewController *navigationController = [homeViewController new];
[self presentViewController:navigationController animated:YES completion:^{
}];
NSLog(#"Start button pressed");
}
It presents homeViewController but it does not show the navigation bar, etc. - as it would if homeViewController was the rootViewController.
Here are some more details
tutorialViewController does not show a status bar or a navigation bar. It is simply a scrollview that takes up the whole screen.
'homeViewControllerhas a navigation bar with a left bar button and right bar button that brings up otherviewControllers`.
I've searched other SO questions but they are mostly to do with Storyboards, which I am not using. Just .xibs (and .h and .m).
How do I present homeViewController from tutorialViewController just as it would display if homeViewController was the rootViewController?
Wrap homeViewController in a UINavigationController should work.
[self presentViewController:[[UINavigationController alloc] initWithRootViewController:homeViewController] animated:YES: completion:nil]
You can also do like this.
In your 'if' condition add tutorialViewController as
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[[tutorialViewController alloc] init]];
And in the goToHomeViewController function add,
homeViewController *navigationController = [homeViewController new];
[self.navigation pushViewController:navigationController animated:NO];
So first time the tutorialViewController act as rootview controller and if you want to hide NavigationBar add following code,
[[self navigationController] setNavigationBarHidden:YES animated:YES];
I am creating a UISegementControl in UIPopoverController. How can i add UIImagePicker in that same UIPopoverController.
segmentController *segmentCtrl = [[segmentController alloc] init];
UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:segmentCtrl];
UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
[imgPicker setDelegate:self];
UIPopoverController *popOver = [[UIPopoverController alloc] initWithContentViewController:navCtrl];
[popOver setPopoverContentSize:CGSizeMake(300, 500) animated:YES];
popOver.delegate = self;
self.popoverImageViewController = popOver;
[self.popoverImageViewController presentPopoverFromBarButtonItem:button permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
In the above code It's create a UISegementControl in UIPopoverController. But i need to add also UIImagePicker in that UIPopover...
If i made any mistake. Please correct me.
Try doing something like this.
imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
UIViewController *containerController = [[UIViewController alloc] init];
containerController.contentSizeForViewInPopover = CGSizeMake(768, 1000);
NSArray *itemArray = [NSArray arrayWithObjects: #"One", #"Two", #"Three", nil];
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray];
[containerController.view addSubview:imagePickerController.view];
[containerController.view addSubview:segmentedControl];
popoverController = [[UIPopoverController alloc] initWithContentViewController:containerController];
[popoverController presentPopoverFromRect:selectedRect inView:self.view permittedArrowDirections:4 animated:YES];
//add ur segment control on top it would take 44 px then adjust the imagePicker frame accordingly.
CGRect tFrame = containerController.view.frame;
tFrame.origin.x -= 44;
tFrame.size.height -=44;
[imagePickerController.view setFrame:containerController.view.frame];
I am trying to make an iPhone app work in an iPad but the UIPopoverController is
comming back with error.
- (IBAction)photoTapped1 {
if(UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone){
// If in editing state, then display an image picker; if not, create and push a photo view controller.
if (self.editing) {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
[self presentViewController:imagePicker animated:YES completion:nil];
[imagePicker release];
} else {
RecipePhotoViewController *recipePhotoViewController = [[RecipePhotoViewController alloc] init];
recipePhotoViewController.hidesBottomBarWhenPushed = YES;
recipePhotoViewController.recipe = recipe;
[self.navigationController pushViewController:recipePhotoViewController animated:YES];
[recipePhotoViewController release];
}
}else{
if (self.editing){
self.popover = [[UIPopoverController alloc] initWithContentViewController:popover];
self.popover.delegate =self;
[popover release];
}else{
RecipePhotoViewController *recipePhotoViewController = [[RecipePhotoViewController alloc] init];
recipePhotoViewController.hidesBottomBarWhenPushed = YES;
recipePhotoViewController.recipe = recipe;
[self.navigationController pushViewController:recipePhotoViewController animated:YES];
[recipePhotoViewController release];
}}}
The error I am getting is:
'NSInvalidArgumentException', reason: '-[UIPopoverController initWithContentViewController:] must not be called with nil.'
Anyone available to give me a hand on this code, I have looked on the internet for solutions and samples but can not seem to make it work.
Thank you.
___ added to original question_____
I am adding the recipePhotoViewController here, I am assuming that ImageView manipulation is the same for iPhone and iPad.
my.h File
#class Recipe;
#interface RecipePhotoViewController : UIViewController {
#private
Recipe *recipe;
UIImageView *imageView;
}
#property(nonatomic, retain) Recipe *recipe;
#property(nonatomic, retain) UIImageView *imageView;
#end
Here is my .m file
#implementation RecipePhotoViewController
#synthesize recipe;
#synthesize imageView;
- (void)loadView {
self.title = #"Photo";
imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.backgroundColor = [UIColor blackColor];
self.view = imageView; }
- (void)viewWillAppear:(BOOL)animated {
imageView.image = [recipe.image valueForKey:#"image"];}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)dealloc {
[imageView release];
[recipe release];
[super dealloc];
} #end
You are initializing the popover controller in a wrong way:
self.popover = [[UIPopoverController alloc] initWithContentViewController:popover];
You should pass the controller you would like to display inside of the popover -- not the popover itself (which is nil since you have not yet initialised it)!
Maybe this would do it for you?
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
self.popover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
If this is correct, then you should also present the pop over you have just created: – presentPopoverFromRect:inView:permittedArrowDirections:animated:
-- e.g.:
[self.popover presentPopoverFromRect:sender.frame inView:[self view] permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
where sender is the argument to :
- (IBAction)photoTapped1:(id)sender {
The content of your popover which you store in the variable popover is obviously nil. I can't see it ever being created in the code you provided.
Maybe you intended to present the Recipe photo controller as the content of the popover. In that case you would do something like
RecipePhotoViewController *recipePhotoViewController = [[RecipePhotoViewController alloc] init];
self.popover = [[UIPopoverController alloc] initWithContentViewController:recipePhotoViewController];
problem is in this line of your code ,
self.popover = [[UIPopoverController alloc] initWithContentViewController:popover];
try like this
UIViewController* popoverContent = [[UIViewController alloc] init];
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 400, 320, 260)];
popoverContent.view = popoverView;
//Add what ever you want popoverView
self.popover = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
self.popover.delegate =self;
I have UIBarButtomItem that shows popover when pressed:
//add help button
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Help", #"Help") style:UIBarButtonItemStylePlain target:self action:#selector(showInfoBubble:)] autorelease];
infoBubblePopOverVisible = NO;
self.infoBubblePopOverController = nil;
Here is show info bubble:
- (void) showInfoBubble: (id) sender {
[self dismissPopoverControllerExplicitly];
if (self.infoBubblePopOverController == nil) {
InfoBubbleViewController *controller = [[InfoBubbleViewController alloc] initWithNibName:#"InfoBubbleViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
self.infoBubblePopOverController = [[UIPopoverController alloc] initWithContentViewController:navigationController];
[controller release];
[navigationController release];
}
//present popOverController
[self.infoBubblePopOverController presentPopoverFromBarButtonItem:self.navigationItem.leftBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
infoBubblePopOverVisible = YES;
}
But when presented popover is presented partially covering barbuttomitem:
How can i fix this?