I am trying to present a popover on clicking a button. When I tap on button, it shows popover on top of the screen and background is completely black. I have set the position and gave hard coded origin to popover but still it is going on top.
Here is the snapshot:
Here is the code I am using:
UIPopoverController *popOverController = [[UIPopoverController alloc]
initWithContentViewController:myViewController];
CGRect frame = CGRectMake(20, 30, 100, 50);
popOverController.popoverLayoutMargins = UIEdgeInsetsMake(0, frame.origin.x, 0, 0);
popOverController.delegate = self;
[popOverController setBackgroundColor:[UIColor clearColor]];
[popOverController presentPopoverFromRect:frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
EDIT
I have changed my code and tried this:
UIView *callOut = [[UIView alloc] initWithFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, 100, 50)];
callOut.backgroundColor = [UIColor whiteColor];
UILabel *callOutLable = [[UILabel alloc] initWithFrame:CGRectMake(callOut.frame.origin.x-5, callOut.frame.origin.y-5, 80, 40)];
[callOutLable setText:#"Callout"];
[callOut addSubview:callOutLable];
UIViewController *controller = [[UIViewController alloc] init];
controller.view = callOut;
UIPopoverController *popOverController = [[UIPopoverController alloc]
initWithContentViewController:controller];
popOverController.delegate = self;
CGRect frame = callOut.frame;
frame.size.height = 100;
frame.size.width = 100;
popOverController.popoverContentSize = CGSizeMake(100.0, 50.0);
[popOverController setBackgroundColor:[UIColor blueColor]];
[popOverController presentPopoverFromRect:frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
As I am creating a custom view which is really small. Now it shows the label on assigned position but still the background view is white.
Now what I am missing here? Any clue?
TestViewController *testViewController = [[TestViewController alloc] initWithNibName:#"TestViewController" bundle:nil];
testViewController.delegate = self;
self.userDataPopover = [[UIPopoverController alloc] initWithContentViewController:testViewController];
self.userDataPopover.popoverContentSize = CGSizeMake(320.0, 400.0);
[self.userDataPopover presentPopoverFromRect:[(UIButton *)sender frame]
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
See this example, you should give content size to pop over as above. But you declared directly as CGRect.
Related
Apple seems to change the attitude of UIPopoverController since iOS8.
Please look at the code below. I want to show UIPopoverController after addSubview. iOS6 and iOS7 are no problem but it does not display on iOS8.
Could you suggest any possible reasons? Any help will be appreciated it.
- (IBAction)tapButton:(id)sender {
SampleView *sampleView = [[SampleView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,
[UIScreen mainScreen].bounds.size.width,
[UIScreen mainScreen].bounds.size.height)];
sampleView.backgroundColor = [UIColor blueColor];
sampleView.alpha = 0.5;
sampleView.label = [[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width / 2,
[UIScreen mainScreen].bounds.size.height / 2,
200.0f, 20.0f)];
sampleView.label.text = #"SAMPLE TEXT";
sampleView.label.textColor = [UIColor redColor];
[sampleView addSubview:sampleView.label];
[self.view.window addSubview:sampleView];
if (!self.popover) {
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor redColor];
vc.preferredContentSize = CGSizeMake(200, 300);
self.popover = [[UIPopoverController alloc] initWithContentViewController:vc];
}
// On iOS7 is OK but not show on iOS8
[self.popover presentPopoverFromRect:CGRectMake(200, 100, 0, 0)
inView:sampleView.label
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
}
Update1:
I followed by this question's answer.
in iOS8: UIPopoverController presentPopoverFromRect not work for keyWindow any more
This is updated code.
[self.popover presentPopoverFromRect:CGRectMake(200, 100, 0, 0)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
As far as I checked, keyWindos and self.view.window seems to be same.
NSLog(#"%#", [UIApplication sharedApplication].keyWindow);
NSLog(#"%#", self.view.window);
However, this is not complete solution for my case. I want to control views on the added subview.
Update2:
I guess that I need to use UIPopoverPresentationController on iOS8.
- (IBAction)tapButton:(id)sender {
// View
SampleView *sampleView = [[SampleView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,
[UIScreen mainScreen].bounds.size.width,
[UIScreen mainScreen].bounds.size.height)];
sampleView.backgroundColor = [UIColor blueColor];
sampleView.alpha = 0.5;
// Label
sampleView.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 20.0f)];
sampleView.label.text = #"SAMPLE TEXT";
sampleView.label.textColor = [UIColor redColor];
[sampleView addSubview:sampleView.label];
// View Controller
UIViewController *viewController = [[UIViewController alloc] init];
viewController.modalPresentationStyle = UIModalPresentationPopover;
viewController.view = sampleView;
// UIPopoverPresentationController
UIPopoverPresentationController *presentationController = viewController.popoverPresentationController;
[presentationController setDelegate:self];
presentationController.permittedArrowDirections = 0;
presentationController.sourceView = [[UIApplication sharedApplication] keyWindow];
presentationController.sourceRect = [[UIApplication sharedApplication] keyWindow].bounds;
[viewController setPreferredContentSize:CGSizeMake(320, 480)];
[self presentViewController:viewController animated:YES completion:nil];
if (!self.popover) {
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor redColor];
vc.preferredContentSize = CGSizeMake(200, 300);
vc.modalPresentationStyle = UIModalPresentationPopover;
self.popover = [[UIPopoverController alloc] initWithContentViewController:vc];
self.popover.delegate = self;
}
[self.popover presentPopoverFromRect:CGRectMake(300, 300, 0, 0)
inView:viewController.view
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
}
Update3 I used dispatch_async but not worked. Some say that dispatch_async is effective in this case. dispatch_async is very simple solution. I prefer to use it. If you can fix my problem by using dispatch_async, I would be grateful you could attache the code.
- (IBAction)tapButton:(id)sender {
SampleView *sampleView = [[SampleView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,
[UIScreen mainScreen].bounds.size.width,
[UIScreen mainScreen].bounds.size.height)];
sampleView.backgroundColor = [UIColor blueColor];
sampleView.alpha = 0.5;
sampleView.label = [[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width / 2,
[UIScreen mainScreen].bounds.size.height / 2,
200.0f, 20.0f)];
sampleView.label.text = #"SAMPLE TEXT";
sampleView.label.textColor = [UIColor redColor];
[sampleView addSubview:sampleView.label];
[self.view.window addSubview:sampleView];
if (!self.popover) {
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor redColor];
vc.preferredContentSize = CGSizeMake(200, 300);
self.popover = [[UIPopoverController alloc] initWithContentViewController:vc];
}
// I tried this but not worked.
dispatch_async(dispatch_get_main_queue(), ^{
[self.popover presentPopoverFromRect:CGRectMake(200, 100, 0, 0)
inView:sampleView.label
permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
});
}
Try and do the following for iOS 8
dispatch_async( dispatch_get_main_queue(), ^{
[self.popover presentPopoverFromRect:CGRectMake(200, 100, 0, 0) inView:sampleView.label permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
});
EDIT
This is my code, it works With or without dispatch_async.
self.popover = [[UIPopoverController alloc] initWithContentViewController:[self.storyboard instantiateViewControllerWithIdentifier:#"second"]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.popover presentPopoverFromRect:self.button.frame inView:self.button permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
});
I am displaying PickerView inside UIPopOver.
For that I have used the following code on button click to display PopOver.
- (IBAction)btnSelectTeachers:(id)sender {
UIView *masterView;
CGRect pickerFrame ;
if(appDelegate.isOSVersionGreaterThan7)
{
masterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 240, 216)];
pickerFrame = CGRectMake(0, 0, 240, 216);
}
else
{
masterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 216)];
pickerFrame = CGRectMake(0, 0, 300, 216);
}
UIPickerView *myPicker = [[UIPickerView alloc] initWithFrame:pickerFrame];
[myPicker setDataSource: self];
[myPicker setDelegate: self];
myPicker.tag=3;
[myPicker selectRow:selectedTeacherIndex inComponent:0 animated:NO];
[myPicker setShowsSelectionIndicator:YES];
self.myPickerView=myPicker;
[masterView addSubview:myPicker];
UIViewController *viewController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
viewController.view = masterView;
viewController.contentSizeForViewInPopover = viewController.view.frame.size;
self.popoverController =[[UIPopoverController alloc] initWithContentViewController:viewController];
UIButton *button = (UIButton *)sender;
[self.popoverController presentPopoverFromRect:button.frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
[self.myPickerView reloadAllComponents];
/*if(selectedTeacherIndex<0)
{
selectedTeacherIndex=0;
}*/
[self.myPickerView selectRow:selectedTeacherIndex+1 inComponent:0 animated:NO];
[self pickerView:self.myPickerView didSelectRow:selectedTeacherIndex+1 inComponent:0];
}
Its working fine for most of the time, but sometimes it gets terminated with above exception.
this is how i set image in my first class in viewDidLoad which is tableView
if ([self.navigationController.navigationBar respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)]) {
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"header.png"] forBarMetrics:UIBarMetricsDefault];
}
now this how i go to detail view
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:dvController animated:YES];
in detail view's bar the image which i have set for navigation bar comes automatically there and everything works perfect
now my problem is that pushViewController is working perfectly images are getting displayed
but i get default image in presentModelViewController this is how i use it
- (void) modelappear
{
if (self.testModalViewController == nil)
{
TestModalViewController *temp = [[TestModalViewController alloc] initWithNibName:#"TestModalViewController" bundle:[NSBundle mainBundle]];
self.testModalViewController = temp;
[temp release];
}
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:self.testModalViewController];
[self presentModalViewController:nav animated:YES];
}
Note i just set buttons in inner hierarchy views
Can you please tell me what am i doing wrong? please give explanation with answer thank you so much
try like this ,
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:[NSBundle mainBundle]];
dvController.topViewController.navigationController.navigationBar.tintColor = [UIColor colorWithPatternImage:[UIIMage imageNamed:#"name.png"]];
[self presentModalViewController:nav animated:YES];
UIImage *image = [UIImage imageNamed:#"header.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[self.navigationController.navigationBar addSubview:imageView];
UIImage *image = [UIImage imageNamed:#"header.png"];
UIImageView *imageViewe = [[UIImageView alloc] initWithImage:image];
UILabel *tmpTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 3, 150, 40)];
[tmpTitleLabel setFont:[UIFont boldSystemFontOfSize:18]];
tmpTitleLabel.text = #"Add Manually";
tmpTitleLabel.backgroundColor = [UIColor clearColor];
tmpTitleLabel.textColor = [UIColor whiteColor];
CGRect applicationFrame = CGRectMake(0, 0, 300, 40);
UIView * newView = [[[UIView alloc] initWithFrame:applicationFrame] autorelease];
[newView addSubview:imageViewe];
[newView addSubview:tmpTitleLabel];
[self.navigationController.navigationBar addSubview:newView];
I have created a UIButton and UIImageView where the button frame is set same as image frame size. What I'm willing to do is once I touch the image it should PopOver. Button is set with action.The problem is that it is displaying only image once I touch it is not Poping up.
What is wrong with my code?
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView *imageView=[[UIImageView alloc] initWithFrame:CGRectMake(10, 10,100, 100)];
imageView.image=[UIImage imageNamed:#"abc.jpg"];
[self.view addSubview:imageView];
imageView.userInteractionEnabled = YES;
UIButton *imageButton = [[UIButton alloc]init];
[imageButton setFrame:CGRectMake(0, 0, 100, 100)];
[imageButton addTarget:self action:#selector(imageTapped:) forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:imageButton];
[imageButton release];
[imageView release];
}
-(void)imageTapped:(UIButton*)in_sender {
UIViewController *popoverContent = [[UIViewController alloc] init];
CGRect theScreenFrame = [[UIScreen mainScreen] bounds];
popoverContent.view.frame = CGRectMake(theScreenFrame.origin.x, theScreenFrame.origin.y,100, 100);
popoverContent.view.backgroundColor = [UIColor whiteColor];
popoverContent.contentSizeForViewInPopover = CGSizeMake(300, 300);
[popoverContent.view addSubview:imageButton];
if(m_DetailPopover) {
[m_DetailPopover release];
m_DetailPopover = nil;
}
UIPopoverController m_DetailPopover = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[popoverContent release];
[m_DetailPopover presentPopoverFromRect:imageButton.frame inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
Might be the problem is a typo in the code:
UIPopoverController *m_DetailPopover = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
Also pls note that you cannot reference imageButton in imageTapped, because
you release it in viewDidLoad.
Dont' add an image view as subview to a button or vice versa. Just assign the image (not the image view) as background image to the button.
Your UIImageView is front of the UIButton, not allowing to get the button action. Why don't you create a custom button with your image?
Do like this:
UIButton *imageButton = [UIButton buttonWithType:UIButtonTypeCustom];
[imageButton setImage:[UIImage imageNamed:#"abc.jpg"]];
[imageButton setFrame:CGRectMake(0, 0, 100, 100)];
[imageButton addTarget:self action:#selector(imageTapped:) forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:imageButton];
[imageButton release];
[imageView release];
EDIT
UIPopoverController *m_DetailPopover = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[m_DetailPopover presentPopoverFromRect:imageButton.frame inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[popoverContent release];
i have a problem with UIScrollView and UINavigationController(s) and iOS 4. The following code works fine with iOS 5:
////////////////////////////////////////////////////////////////////////////////////
/* Scroll View */
////////////////////////////////////////////////////////////////////////////////////
mScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 88, 1024, 668)];
mScrollView.contentSize = CGSizeMake(1850, 668);
////////////////////////////////////////////////////////////////////////////////////
// First View
////////////////////////////////////////////////////////////////////////////////////
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"view_bg.png"]];
imgView.frame= CGRectMake(10, 50, 350, 510);
[mScrollView addSubview:imgView];
[imgView release];
mFirstView = [[[FirstView alloc] init] autorelease];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:mFirstView];
navigationController.navigationBar.tintColor = [UIColor colorWithRed:79.0/255 green:143.0/255 blue:0.0/255 alpha:1];
navigationController.view.frame = CGRectMake(25, 65, 320, 480);
[mScrollView addSubview:navigationController.view];
////////////////////////////////////////////////////////////////////////////////////
// Second View
////////////////////////////////////////////////////////////////////////////////////
UIImageView *imgView2 = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"view_bg.png"]];
imgView2.frame= CGRectMake(380, 50, 350, 510);
[mScrollView addSubview:imgView2];
[imgView2 release];
mSecondView = [[[SecondView alloc] init] autorelease];
UINavigationController *navigationController2 = [[UINavigationController alloc] initWithRootViewController:mSecondView];
navigationController2.navigationBar.tintColor = [UIColor colorWithRed:79.0/255 green:143.0/255 blue:0.0/255 alpha:1];
navigationController2.view.frame = CGRectMake(395, 65, 320, 480);
[mScrollView addSubview:navigationController2.view];
// finally add the scroll view to the parent view
[self.view addSubview:mScrollView];
All i do is, to add a ScrollView with 2 NavigationControllers (with a allocated root view controller) do the view. But using this code with iOS 4 does not show the right size of the ViewControllers added. The ViewControllers are the size of the whole iPad screen!!!!!
As i already said, it works on iOS 5! Even when i change the size of the views added manually it is not working, the added view always fills the whole iPad screen!! Any ideas to fix this?
Thank you in advance!
in your code you have the following
//first view you add mfirstview.view
[mScrollView addSubview:mFirstView.view];
//second view you add navigationController2.view
[mScrollView addSubview: navigationController2.view];
So i guess you have to change the first view code to do the following
[mScrollView addSubview: navigationController.view];