I am trying to display tableviewcontroller in a popover from a barbuttonitem like this :
- (IBAction)sortData:(id)sender {
if(!sortViewController)
sortViewController = [[SortDataViewController alloc] init];
[sortViewController.tableView setDelegate:self];
[sortViewController.tableView setTag:12];
[sortViewController setIsMatter:YES];
sortViewController.contentSizeForViewInPopover = CGSizeMake(150, 100);
sortViewController._radioSelection = 0;
[sortViewController.tableView reloadData];
}
if(!popOverController) {
popOverController = [[UIPopoverController alloc] initWithContentViewController:sortViewController];
}
[popOverController setPopoverContentSize:CGSizeMake(100, 100)];
[popOverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
for the first time it got displayed for 1sec and automatically dismissed and from next time onwards it is not displaying at all. Can anyone please help me in this regard.
Set delegate for the UIPopOVerController...
popOverController.delegate = self;
I am reloading the view after each second to test some requirement and forgot to disable it. So my view is reloading continuously and it's not giving enough time for popover to display it's view. Now I disabled it and the popover is working without any issues.
Related
I have a problem since last half-an-hour.I am using UIButton and I want to show UIPopovercontroller on it.But It crashes on it's touchUpinside action.I know this can we easily done if i use UIBarButton but I have some UI specification that's why I can't use UIBarButton and UIToolbar.
So please if someone have any idea about showing UIPopovercontroller on UIButton then please help me.Help would be appriciated.
[popoverController presentPopoverFromRect:button.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
You can try using the below Code :
-(IBAction)Show_Menu_Controller:(id)sender
{
if (_colorPicker == nil) {
self.colorPicker = [[[ColorPickerController alloc] initWithStyle:UITableViewStylePlain] autorelease];
_colorPicker.delegate = self;
self.colorPickerPopover = [[[UIPopoverController alloc] initWithContentViewController:_colorPicker] autorelease];
}
[self.colorPickerPopover setPopoverContentSize:CGSizeMake(600.0f, 250.0f)];
[self.colorPickerPopover presentPopoverFromRect:CGRectMake(365,-118 , 300, 200) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES]; **//Set the Origin & Direction of PopOverController accordingly**
}
I've got a popover within my view. Within this popover there is content from another xib file (Infoscreen.xib). How can I dismiss the popover with a button which is inside another .xib file? Here's a snippit of my code:
-(IBAction)infoDruk: (id)sender {
if([popover isPopoverVisible]) {
[popover dismissPopoverAnimated:YES];
}
else {
Infoscreen *choser = [[Infoscreen alloc] init];
popover = [[UIPopoverController alloc]
initWithContentViewController:choser];
[choser release];
popover.delegate = self;
popover.popoverContentSize = CGSizeMake(230, 563);
[popover presentPopoverFromBarButtonItem:sender
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
}
Help is greatly appreciated!
Your another xib should inform (give a call back) to your pop over that such button has been pressed. This concept is called delegates. Thus, you can dismiss the pop over in this call back method.
Could anyone please tell me what the rect and view should be? I do not understand what I shall pass to the selector. An example would be great!
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIPopoverController_class/Reference/Reference.html
- (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated
I use this pretty often. Let's say you want to tap on an image and present a popover with information about it. Assuming you have a gesture recognizer with the selector method (handleImageTap:) on your image, here would be an example code to make that happen:
- (void)handleImageTap:(UIGestureRecognizer *)gesture {
// initialize your popover view controller and assign it to your popoverController
MyPopoverViewController *content = [[MyPopoverViewController alloc] init];
popoverController = [[UIPopoverController alloc] initWithContentViewController:content];
popoverController.popoverContentSize = CGSizeMake(600, 600);
popoverController.delegate = self;
[content release];
if (popoverController.popoverVisible == NO) {
// you can find the tappedImage through the gesture by searching up superviews if you don't already have a reference to it;
[popoverController presentPopoverFromRect:[tappedImage frame] inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else {
[popoverController dismissPopoverAnimated:YES];
}
}
So basically, view will be self.view becuase you are displaying it from the current view controller. The rect is just whatever rect you want the popover to display from. In this case, it is set up to be displayed from the frame of an image. I hope this helps you. If something is still confusing, I'll be happy to try and clear it up
hours ago I post a question on organizing portrait and landscape mode in iPhone and now I think I know how to do it using willRotateToInterfaceOrientation:duration.
The first screen is 'Map View' with one button that leads to 'Setting View'. The Map View does not support rotate but for the Setting View I made separate view for portrait and landscape and they swap accordingly when rotated.
, ,
As you can see when Setting button pressed SettingView is added on the view stack as usual. So basically I use three view controllers; Setting, SettingLandscape and SettingPortrait.
I still found problem in rotating view in iPhone when I use navigationViewController. Segmented control is not working. it crashes without error message. It used to working fine without rotation.- when I'm not using multiple view for rotation-.
rotateViewController.m
This is root view controller.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
-(IBAction) buttonPressed{
Setting *settingViewController = [[Setting alloc] initWithNibName:#"Setting" bundle:[NSBundle mainBundle]];
UINavigationController *navController1 = [[UINavigationController alloc] initWithRootViewController: settingViewController];
[self.navigationController presentModalViewController:navController1 animated:YES];
[settingViewController release];
[navController1 release];
}
Setting.m
This view controller does nothing but swap views when rotate and shows appropriate view between portrait and landscape.
In Setting.m, I swap view as follow;
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (toInterfaceOrientation==UIInterfaceOrientationLandscapeRight) {
NSLog(#"to Right");
SettingLandscape *setting_landscape = [[SettingLandscape alloc] initWithNibName:#"SettingLandscape" bundle:[NSBundle mainBundle]];
self.view = setting_landscape.view;
[setting_landscape release];
}
if (toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft) {
NSLog(#"to Left");
SettingLandscape *setting_landscape = [[SettingLandscape alloc] initWithNibName:#"SettingLandscape" bundle:[NSBundle mainBundle]];
self.view = setting_landscape.view;
[setting_landscape release];
}
if (toInterfaceOrientation==UIInterfaceOrientationPortrait) {
NSLog(#"to Portrait");
SettingPortrait *settingportrait = [[SettingPortrait alloc] initWithNibName:#"SettingPortrait" bundle:[NSBundle mainBundle]];
self.view = settingportrait.view;
[settingportrait release];
}
if (toInterfaceOrientation==UIInterfaceOrientationPortraitUpsideDown) {
NSLog(#"to PortraitUpsideDown");
SettingPortrait *settingportrait = [[SettingPortrait alloc] initWithNibName:#"SettingPortrait" bundle:[NSBundle mainBundle]];
self.view = settingportrait.view;
[settingportrait release];
}
}
In viewWillAppear, Setting view controller also has ;
self.title = #"Shell ";
self.navigationController.navigationBarHidden = NO;
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStylePlain target:self action:#selector(Done)] autorelease];
and Done is
- (void) Done{
[self dismissModalViewControllerAnimated:YES];
}
SettingLandscape.m
This view stacked on when the view is rotated. This view controller has it's navigation bar.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.title = #"Setting Landscape";
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
in viewDidLoad;
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"landscape:viewDidLoad");
//self.title = #"SettingLandscape";//not working!!
//self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Done1" style:UIBarButtonItemStylePlain target:self action:#selector(Done)] autorelease];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
stringflag4MapType = [[NSString alloc] initWithString:#"blah"];
stringflag4MapType = [defaults stringForKey:#"flag4MapType"];
if (![stringflag4MapType isEqualToString:#"Hybrid"] && ![stringflag4MapType isEqualToString:#"Standard"] && ![stringflag4MapType isEqualToString:#"Satellite"]) {
segmentedControl4MapType.selectedSegmentIndex = 0;
}else if ([self.stringflag4MapType isEqualToString:#"Standard"]) {
segmentedControl4MapType.selectedSegmentIndex = 0;
}else if ([self.stringflag4MapType isEqualToString:#"Satellite"]) {
segmentedControl4MapType.selectedSegmentIndex = 1;
}else if ([self.stringflag4MapType isEqualToString:#"Hybrid"]) {
segmentedControl4MapType.selectedSegmentIndex = 2;
}
and following call does not get invoked. strange. doesn't matter rotation works anyway.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (toInterfaceOrientation==UIInterfaceOrientationPortrait) {
NSLog(#"to Portrait");// does not print out.
SettingPortrait *settingportrait = [[SettingPortrait alloc] initWithNibName:#"SettingPortrait" bundle:[NSBundle mainBundle]];
self.view = settingportrait.view;
[settingportrait release];
}
if (toInterfaceOrientation==UIInterfaceOrientationPortraitUpsideDown) {
NSLog(#"to PortraitUpsideDown");
SettingPortrait *settingportrait = [[SettingPortrait alloc] initWithNibName:#"SettingPortrait" bundle:[NSBundle mainBundle]];
self.view = settingportrait.view;
[settingportrait release];
}
}
ok now, as you can see from those snap shots there are two navigation bar and each has its bar button, Done and Item. The Done button came from Setting and the Item button from SettingPortrait or SettingLandscape. All button's selector is same, that leads back to map view. The button Done works fine, but the button Item crashes. I need a button on navigation bar after rotation that acts like back button . I guess once I did 'self.view = settingportrait.view;' the problem starts.
The reason why I need the Item button work is that the segmented control started crashing once I add code to support rotation. If I found reason how to make the Item button-that is inside rotation view- work I think I can make the segmented control work as well.
You can download the whole code at https://github.com/downloads/bicbac/rotation-test/rotate-1.zip
https://github.com/downloads/bicbac/rotation-test/rotate-1.zip
this sample code is amazing for me. It solve my problem of rotating view just by simple delegate method
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
my best attempt to answer question without looking at code (don't have time tonight :( )
When you present setting viewcontroller modally, your top viewcontroller is setting.
When rotation happens, you load setting_landscape or setting_portrait viewcontroller, but only retain the view inside setting_landscape|portrait. Thus, setting_landscape/portrait viewcontrollers are released. When device is rotated, it's probably "setting" viewcontroller receiving rotation message, not the "setting_landscape/portrait" viewcontroller because they are not pushed on to the viewcontroller stack.
So, when you click on item or segment control, it will call delegate, which is probably set to setting_landscape|portrait which is released already.
What is the message in console you get with crash?
My recommendation would be to build setting viewcontroller with segmented control, then use "willAnimateRotationToInterfaceOrientation:duration:" function to reposition the segmented control to the right position and frame. Just by returning YES to all orientation, rotation should be supported, doesn't it?
What was the reason for using two separate viewcontroller for landscape/portrait? (I do this sometimes, but rarely)
Edit* you need to use "willAnimateRotationToInterfaceOrientation" callback to animate the changes, not "willRotate..."
I think the issue here is that I'm trying to call a mediaPicker and that doesn't support other orientations...
Does anyone have a fix for this?
Here is my current code:
- (IBAction)openMediaPicker:(id)sender {
MPMediaPickerController *mediaPicker = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeAnyAudio];
mediaPicker.delegate = self;
mediaPicker.allowsPickingMultipleItems = YES; // this is the default
mediaPicker.modalPresentationStyle = UIModalPresentationPageSheet;
//mediaPicker.prompt = #"Select items to play";
[self presentModalViewController:mediaPicker animated:YES];
[mediaPicker release];
// Init a Navigation Controller, using the MediaPicker as its root view controller
UINavigationController *theNavController = [[UINavigationController alloc] initWithRootViewController:mediaPicker];
[theNavController setNavigationBarHidden:YES];
// Init the Popover Controller, using the navigation controller as its root view controller
popoverController = [[UIPopoverController alloc] initWithContentViewController:theNavController];
// Make a rect at the size and location of the button I use to invoke the popover
CGRect popOverRect = chooseMusicButton.frame;
// Specify the size of the popover
CGSize MySize = CGSizeMake(520.0, 720.0);
[popoverController setPopoverContentSize:MySize animated:YES];
// Display the popover
[popoverController presentPopoverFromRect:popOverRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
popoverController.delegate = self;
}
This code is overly complicated. First you present the media picker modally, then you present it as a popover; why? In the popover, you stuff it into a navigation controller before presenting it; why? Presenting a media picker on iPad is much simpler than that:
MPMediaPickerController* picker =
[[[MPMediaPickerController alloc] init] autorelease];
picker.delegate = self;
UIPopoverController* pop =
[[UIPopoverController alloc] initWithContentViewController:picker];
self.currentPop = pop;
[pop presentPopoverFromRect:[sender bounds] inView:sender
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[pop release];
That works in any orientation and even survives rotation while the popover is showing.
All pre-defined modal controllers support all orientations but they must be presented from the root view controller for them to behave correctly in orientation and rotation. My guess is that that the "self" in your code is not the root view controller. You may have to re-architect the code a bit to make this happen if possible.
There are other hacks I have seen to make it work without being presented from the root view controller but they all seemed to be asking for trouble such as extending UIViewController with a category to over-ride interfaceOrientation.
If you can present it from the root view controller, it would be the simplest and cleanest but I realize it is not always possible (e.g., it is inside a library you are providing to third party apps to embed).