How to change popoverview size when popping off additional view controllers - objective-c

I've created a bare bones Master/Detail iPad application using the supplied template. It creates two view controllers (Master and Detail). I've created a view additional view controllers that get popped on top of the master view controller (pretty much drilling down tableviews until finally hitting a cell that populates the detail view. I've added the code below to load the master view controller popover to the specified dimensions (code below also shows when a selection is selected from the master view controller tableview):
#implementation MasterViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.vehicles = [[NSArray alloc] initWithObjects:#"Cars", #"Trucks", #"Boats", nil];
self.title = #"Vehicle Type";
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, [vehicles count] * 52.0);
}
return self;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.studySessionViewController)
{
self.secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
}
[self.navigationController pushViewController:self.secondViewController animated:YES];
}
When the popover is selected when the application first loads, everything looks great. However, when a user clicks back to the MasterViewController, the size of the popover is the same size as the largest view controller that was pushed on the stack. I've searched around and I've added the following code in the Master view controller class:
- (void)viewWillAppear:(BOOL)animated
{
self.contentSizeForViewInPopover = CGSizeMake(320.0, [vehicles count] * 52.0);
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
self.contentSizeForViewInPopover = CGSizeMake(320.0, [vehicles count] * 52.0);
[super viewDidAppear:animated];
}
However, this has no effect. Also once the popover is closed (either by rotation or deselecting the popover on the UI), the popover size of the largest table view controller that was previously pushed on the stack is still retained and completely ignores the above dimensions. What am I missing?

I couldn't understand your whole problem but I think that the base of your problem is bad size of a Popover.
Usually, the problems with Popover size come of the fact that [UIViewController contentSizeForViewInPopover] can be set only before you create the UIPopoverController instance. It's just the default value for the popover size.
When you create the UIPopoverController instance with your controller as its contents, the contentSizeForViewInPopover is copied into [UIPopoverController popoverContentSize] and never read again. If you change it on the contents, Popover size is not updated.
The only way how you can change size of an already created UIPopoverController instance is using the property [UIPopoverController popoverContentSize] or method [UIPopoverController setPopoverContentSize:animated:].

You are trying to set the popover size in the MasterViewController itself. Here lies the issue. For self.contentSizeForViewInPopover = CGSizeMake(320.0, [vehicles count] * 52.0); to work you will have to use this in the DetailViewController instead, since the DetailViewController is the one that has a popover. Basic idea here is that you set the size in parent view controller and not the controller itself.

your going to have to setup the frames.
incomingCallViewController = [[IncomingCallViewController alloc]initWithNibName:#"IncomingCallViewController" bundle:nil];
[incomingCallViewController.view setFrame:CGRectMake(400, 200, 377, 243)];
[self.navigationController pushViewController:incomingCallViewController.view];
this of course is sample code from one of my projects, replace incomingCallViewController with your own class and declare it in the header

Related

Where to set the size of a view controller presented in a popover?

Based on Apple's sample code, my app is presenting a view controller in a popover, which is trigged by a bar button:
- (IBAction)configChartTapped:(id)sender {
GrowthChartConfigOneViewController *panelViewController = [[GrowthChartConfigOneViewController alloc]init];
UIPopoverController *popover = [[UIPopoverController alloc]initWithContentViewController:panelViewController];
popover.delegate = self;
// Store the popover in a custom property for later use.
self.popover = popover;
[self.popover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
However, I did not find a way to set the size of the popover.
Question: Where and how should I set the size of the popover and its view controller? Can I set the size directly in XCode to have the view correctly sized in storyboard?
You can also set it within the popover class itself. This way if you allow the popover to be called from multiple places, you can just set the size once.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
self.view.backgroundColor = [UIColor redColor];
self.contentSizeForViewInPopover = CGSizeMake(320.0, 216.0);
}
return self;
}
Just give popovercontentsize and make sure that view should fit in popover size as defined below:
popover = [[UIPopoverController alloc] initWithContentViewController: panelViewController];
popover.popoverContentSize = CGSizeMake(550, 700);
Good answer above but I just wanted to update it for storyboard due to my slightly different needs. If you're instantiating using storyboard identifier like this:
CBItemViewController *addNewPayee = [self.storyboard instantiateViewControllerWithIdentifier:#"cbItemPopover"];
then you can set the custom size inside the popover's code like this:
- (id)initWithCoder:(NSCoder *)decoder {
if(self = [super initWithCoder:decoder]) {
self.preferredContentSize = CGSizeMake(630, 340);
}
return self;
}

view controller not appearing in iOS 5 project

i started a single view template in Xcode 4.2(recently upgraded to Xcode 4.2 and ios5)
so now i have only one view controller.
I added a new class to the project which is a subclass of UIViewcontroller.
Now in the main controller class viewdidLoad method
- (void)viewDidLoad
{
// Override point for customization after application launch.
[super viewDidLoad];
[self presentQuizcontroller];
}
-(void) presentQuizcontroller
{
_QuizController = [[[Quiz alloc] initWithNibName:#"Quiz" bundle:nil] autorelease];
_QuizController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:_QuizController animated:YES]; // Do any additional setup after loading the view, typically from a nib.
}
the problem is in my Quiz class
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
the initWithNibName method does get called(i checked by using breakpoint) but it doesn't passes the condition of if(self) . and hence the view don't appears.
Any ideas?
Edit
After the first answer i tried this way too
- (void)viewDidLoad
{
// Override point for customization after application launch.
[super viewDidLoad];
}
-(void) presentQuizcontroller
{
_QuizController = [[[Quiz alloc] initWithNibName:#"Quiz" bundle:nil] autorelease];
_QuizController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:_QuizController animated:YES]; // Do any additional setup after loading the view, typically from a nib.
}
-(void) awakeFromNib
{
[self presentQuizcontroller];
}
same thing Quiz.m initwithnib name method does not passes the condition if(self).
I think you need to use awakefromnib.
Here is the Link for another StackOverflow post if you want to read more.
PresentModalViewController is depreciated, I think you should now use presentViewController instead of it.
Are you sure that "Quiz" is the name of your file? That string should be same as the name of your xib file, namely something like "QuizController" or "QuizViewController"
Make sure the xib file is properly connected to header/implementation files by checking:
Owner of the xib file should be set as the viewController
View on the xib file (the one above all if you have multiple views) should be connected to viewControllers view.

xcode unable to hide tabbarcontroller

I have a tabbarcontroller as main controller and when a view is pushed I would like to hide it. I use hidesBottomBarWhenPushed but not working. Thanks.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.hidesBottomBarWhenPushed = YES;
}
return self;
}
try to add this line when you push this controller, in it's parent view controller :
YourViewController *controller = [[YourViewController alloc]init....];
controller.hidesBottomBarWhenPushed = YES;
//then push the view controller
Good Luck
This will only work if one of the viewControllers of the tabBarController is a UINavigationController. The hidesBottomBarWhenPushed property is only respected if a view controller is pushed onto the stack of a UINavigationController and will not do much if it is the root view controller.
I've implemented my own custom tabBarController (which extends the original UITabBarController), because I need to toggle bars programmatically under certain circumstances (like device rotation), this is my implementation (comments explain how it works):
- (void)hideBottomBar:(BOOL)hide
{
#try
{
// UITabBarController has 2 subviews:
// - the first (index:0) is that one containing the active view controller's view
// - the second (index:1) is that one containing the UITabBar (self.tabBar)
UIView *topView = [self.view.subviews objectAtIndex:0];
UIView *bottomView = [self.view.subviews objectAtIndex:1];
// hide tabs container if necessary
[bottomView setHidden:hide];
// adjust frame
if (hide)
{
// expand main view to fit available space
[topView setFrame:self.view.bounds];
}
else
{
// restore main view frame
CGRect frame = topView.frame;
frame.size.height -= bottomView.frame.size.height;
[topView setFrame:frame];
}
}
#catch (NSException *exception)
{
[[GTMLogger sharedLogger] logError:#"Error occured adjusting tabs view: %#", exception.description];
}
}

calling addSubview in initWithNibName: causes viewDidLoad (and other UI Object inits)to fire before the addSubview Call executes

I'm adding a button in the middle of my initWithNibName:bundle:, when i add the button view to self.view, the view goes to start to initialize before it add's the button. So the Code in viewDidLoad gets fires before the initWithNibName:bundle: is finished. There is code below the addSubview that is relied on in the viewDidLoad and causes it to crash/not work since the init code has not run.
I've had the same experience when I added the button code to the viewDidLoad method. There is a UITableView in the .xib and the table gets inited before the rest of the viewDidLoad gets run and caused the tableView to get bad Data.
What is the best practice for adding a view to a view when you are initing and loading the view? just put all the addSubViews before the Return?
Thanks!
Here is my initWithNibName:bundle:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nil];
[self setIoUIDebug:(IoUIDebugSelectorNames)];
if (IoUIDebug & IoUIDebugSelectorNames) {
NSLog(#"%# - %#", [self description], NSStringFromSelector(_cmd) );
}
CGRect frame = CGRectMake(20, 521, 500, 37);
saveButton = [UIButton newButtonWithTitle:NSLocalizedStringFromTable(#"Save Animation Label",#"ScreenEditor",#"Save Animation Label")
target:self
selector:#selector(saveButtonPressedAction:)
frame:frame
image:[UIImage imageNamed:#"BlueButtonSmall.png"]
imagePressed:[UIImage imageNamed:#"BlueButtonSmallPressed.png"]
darkTextColor:NO];
[self.view addSubview:saveButton]; // <- Right here I'll hit breakpoints in other parts of viewDidLoad and cellForRowAtIndexPath, before the lined below get executed.
[saveButton setEnabled: NO];
[saveButton setUserInteractionEnabled: NO];
newAnimation = nil;
selectedSysCDAnimation = nil;
selectedIoCDTag = nil;
animationSaved = NO;
return self;
}
You should add the subviews inside viewDidLoad this will mean that the views are added when the main view is loaded into memory. I would reserve your initWithNibName:bundle: call for custom initialization and not interacting with the UI as this what viewDidLoad is designed for.
In regards to your tableView, you should put a call to load the tables datasource inside of viewDidLoad. Once the datasource is loaded, you can simply call reloadData on the tableview to load the data into the tableview.
For Example:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view addSubview:saveButton];
[self loadDataSource];
}
- (void)loadDataSource {
// load datasource here
[self.tableView reloadData];
}
Any access to the view property of the view controller will lazily initialize the view. This will trigger a call to viewDidLoad which will execute before the access to the view property returns in initWithNibName:. You should add the sub view in viewDidLoad or using interface builder.

Objective C: Part of UITableView hidden by Tab bar controller

Hi I have a Uitableview added to a Uiviewcontroller as seen in the code below. The controller is part of a UITabbarcontroller.
The problem here is that the tab bar (at bottom of screen) overlaps with the table view. Is there any way to shorten the table height so that it is not partially hidden by the tab bar?
- (void)viewDidLoad
{
[super viewDidLoad];
self.view = [[[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] autorelease];
self.feedTableView = [[UITableView alloc]init];
self.feedTableView.frame = self.view.bounds;
self.feedTableView.delegate = self;
self.feedTableView.dataSource = self;
[self.view addSubview: self.feedTableView];
[self getData];
[self.feedTableView reloadData];
}
You have two problems here:
You set self.view in viewDidLoad (it should already have been set in loadView).
You set the view frame to applicationframe, but your view does not take up the whole applicationframe (the tab bar controller's view probably does that).
When you have a tabbarcontroller and set viewcontrollers inside it, the tabbarcontroller sets up all the viewcontrollers (tells them when to load and what size to have and when to show). You should never need to set the view's frames in this case. So removing that first line after [super viewDidLoad]; should fix your problem.