How to set index of UIViewController as background - objective-c

I'm trying to set background to the entire app from the code:
UIViewController *controller = [[UIViewController alloc] init];
controller.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background#2x.png"]];
self.window.rootViewController = controller;
[self.window makeKeyAndVisible];
In the Storyboard I have a simple button in the main UIViewController. In the AppDelegate.m I set that code above, but, I background has added, they is in front of the text that is in the Storyboard.
I want to know how can I set that background from the current index to the last index in the stage.

You can create a subview, set the background image in that subview, frame it to the right size and then send that subview to a position "behind" everything else:
[mainView addSubview:backG1];
[mainView sendSubviewToBack:backG1];

Well, wenn you use a storyboard at all, AND declare it in your project settings as THE storyboard of your app, then you are not supposed to create and set the root view controller in your app delegate.
Both of them is perfectly fine, but one is the interface builder/storyboard option and the other is the programmatical way. Both ways just don't agree!!!
If you want to go for storyboards, which I encourage you to do, then give your root view controller an ID and in aoru ypp delegate method didFinishLoadingWithOptions: fetch it from the storyboard and set its background view then.
Have in mind: When you use a background view then you need to set all the background colours of all your view items (that may be tables, table cells, cell content views etc. pp.) to clearColor.

When you set an initial view controller in code (in AppDelegate.m, under didFinishLaunchingWithOptions), then it overrides the root view controller in your storyboard.
You can either set your view controller's background in the storyboard, or initialise it like you did - but then you need to create all other UI elements in code as well.

Related

How can I dynamically fit a xib file view into a storyboard view?

I have setup a simple layout with a button which, when pressed, causes the storyboard subview to load a xib file and assigns its view to the storyboard subview. The problem is that the xib view causes the storyboard subview to 'break' its original constraints:
Here's the main storyboard (left) and xib view (right):
Here's what happens when I press the button on the main storyboard.
- (IBAction)btnShowView:(id)sender {
xibViewController *xib_VC = [[xibViewController alloc] initWithNibName:nil bundle:nil];
xib_VC.modalPresentationStyle = UIModalTransitionStyleCrossDissolve;
//xib_VC.view.frame.size = self.myView.frame.size;
UIView *view = xib_VC.view;
[self.myView addSubview:view];
}
And here's the result - you can see that the xib view has caused the main storyboard subview to go outside of its constraints.
I'm guessing that dynamically changing the storyboard subview overwrites its original view and constraints? Do I have to programatically add these constraints again before assigning the xib view to the storyboard subview?
By your descriptions, it looks like your intention is to put newly created view(xib_VC.view) in the position of myView.
By code you mentioned is adding xib_VC.view to myview as a subview,It doesn't any constraints to it or provides a frame to view.
Setting xib_VC.view.frame.size will not going to work, this is frame for view in xib_VC.
If you just need view, then you don't have to create view controller xib. Just create view xib.
Following line no use, since you are not using a controller.
xib_VC.modalPresentationStyle = UIModalTransitionStyleCrossDissolve;

Prevent resizing of a view controller presented as a sheet?

Is there a way to prevent a view from being resized if the view controller is presented as a sheet using the method presentViewControllerAsSheet or using a segue of style "sheet"?
Note that modal/show segues can be implanted to a window controller which can be set as non resizable from the storyboard itself. Segues of type popover are non-resizable by default.
Have you tried setting your sheet view controller's -preferredContentSize? Failing that, what about adding width and height NSLayoutConstraints to the view controller's view on -viewDidLoad?
This worked for me. The sheet is no longer resizable:
override func viewWillLayout() {
preferredContentSize = view.frame.size
}
None of the other solutions worked for me, so I ended up using an NSWindow as the sheet controller (rather than a NSViewController on its own).
Declare an NSWindowController object in your header file:
NSWindowController *detailWindow;
To open the window in the form of a sheet, use the following code:
NSStoryboard *storyFile = [NSStoryboard storyboardWithName:#"Main" bundle:nil];
detailWindow = [storyFile instantiateInitialController];
[self.view.window beginSheet:detailWindow.window completionHandler:nil];
To close the window:
[self.view.window endSheet:detailWindow.window];
In order to stop the window sheet from being resized, simply set the NSWindow minimum/maximum size in interface builder:
That's it, super easy! (Don't forget to set the window controller, as the initial controller).
the above methods did not work for me .
self.view.autoresizesSubviews = NO;
this line in viewcontroller should do the trick if the above methods didnt work

View Controller behaves differently when set as 'initial view controller' vs. loading with presentModalViewController

My app has a map that tracks the user's location. This map will only appear under certain circumstances, and will dominate the user's attention until a particular task is complete, which is why the map isn't part of a navigation or tab bar UI.
If my map VC is set as the initial view controller in storyboard, it works fine. But if I try to load the map VC from elsewhere like this;
MapViewController *mapVC = [[MapViewController alloc] init];
[self presentModalViewController:mapVC animated:YES];
I just get a black screen.
I can confirm with NSLog that the VC is calling viewDidLoad and viewDidAppear, but the 'map' property of the VC is (null). I don't understand why (or how) I need to create the map property manually when using this technique, but it gets done for me when it is the initial VC.
The MapViewController instance in your storyboard is configured with a view hierarchy, including an MKMapView, and whatever else you did to configure that particular instance in the storyboard.
Now in this code which you show here, you are creating a completely new instance of MapViewController. It has no relationship to the instance in the storyboard other than they happen to be of the same class. So the one you create here with [[MapViewController alloc] init] has no view hierarchy (which is why you see a black screen), and none of the outlets or other configuration you may have made to the other MapViewController in your storyboard.
So what you want is to load that MapViewController that you've already set up from the storyboard. Assuming you are doing this from within a method in another view controller loaded from the same storyboard already, you can just do this:
// within some method on another vc from a scene in the same storyboard:
// given an identifier for the map view controller we want to load:
static NSString *mapVCIdentifier = #"SomeAppropriateIdentifier";
NSLog(#"Storyboard: %#",self.storyboard); // make sure this vc(self) was loaded from a storyboard
MapViewController *mapVC = [self.storyboard instantiateViewControllerWithIdentifier:mapVCIdentifier];
[self presentModalViewController:mapVC animated:YES];
And then back in the storyboard, just make sure you set the identifier for this map view controller to "SomeAppropriateIdentifier".
Hope that helps.

Adding a Navigation Controller to a View based Application adds top margin

I am trying to programmatically add a Navigation Controller to my View based Application. This is the code I am using (this code gets called after a button press in a view controller):
MainMenu *control = [[MainMenu alloc] initWithNibName: #"MainMenu" bundle: nil];
UINavigationController *navControl = [[UINavigationController alloc] initWithRootViewController: control];
[self.view addSubview:navControl.view];
[control release];
That works, but this ends up happening:
Notice the odd margin above the Navigation control.... My View controller that I am adding the Navigation Controller to has a gray background which you can see.
Any ideas??
If you have a better way of adding a Navigation Controller to a View based Application I am very open to suggestions!
Thank you in advance!
Thank you both for your response, but unfortunately, wantsFullScreenLayout set to YES or NO in the code didn't have any effect. I was able to push the Navigation Controller up by 20 using this line of code:
self.navigationController.navigationBar.frame = CGRectOffset(self.navigationController.navigationBar.frame, 0.0, -20.0);
but then what happened was that the View Controller did not move up with the Navigation bar and left a gap below the Navigation Bar and the View Controller. What eventually worked was checking the Wants Full Screen checkbox in IB in the MainWindow view controller that is automatically generated when you set up a view based application.
The gap you are seeing is the same height as a status bar. Check the status bar settings in your NIB file.
Chances are you want to make the UINavigationController the root view controller for the window, rather than whichever view controller you have now. That would be the better way to do it.
The reason you're seeing that extra margin at the top is because UINavigationController normally expects that it will be sized to fill the entire screen (except perhaps a tab bar at the bottom, if it's inside a UITabBarController), and therefore expects that the top edge of its view will be under the status bar if the status bar is visible. Therefore, it places its navigation bar 20 pixels below the top of its view to leave space for the status bar, without bothering to check whether its view actually is under the status bar. Interestingly, sometimes a re-layout operation will perform this check, but that's unreliable. What I've found works well in a situation like this is to set the UINavigationController's wantsFullScreenLayout property to NO. Then ti doesn't try to leave room for the status bar, so everything works as expected.
I've been struggling with this same issue this morning. Since setting the wantsFullScreenLayout property doesn't seem to have any effect, I resorted to using a little subclass, which worked fine:
#interface MyNavigationController : UINavigationController
#end
#implementation MyNavigationController
- (BOOL)wantsFullScreenLayout;
{
return NO;
}
#end
Its so simple to remove that gap..
self.navigationBar.view.frame = CGRectMake(0, -20, 320, 480);

UINavigationController with UIView and UITableView

I'm creating a navigation-based app which displays a graph, rendered with openGL, and a tableview listing disclosure buttons of all of the elements that are displayed on the graph, and a settings disclosure button.
The navigation controller is also a tableview delegate and datasource, and the tableview is added to the view programatically and has its' delegate and datasource set to 'self'. The OpenGL based graph view is added via IB.
The problem I'm having is that I'm trying to push a view controller (either settings or graph element properties) within the didSelectRowAtIndexPath method. The method registers and the new view is pushed on, but the tableview stays and obscures part of the view that was pushed on, as if it has a different navigation controller.
I can't seem to set the tableview's navigation controller to be the same as the rest of the UINavigationControllers' view.
Does anyone know how I could fix this?
My navigation controllers' initWithCoder method, where the tableview is added, appears as follows:
elementList = [[UITableView alloc] initWithFrame:tableFrame style:UITableViewStyleGrouped];
elementList.dataSource = self;
elementList.delegate = self;
[self.view addSubview:elementList];
Further in the source file, the DidSelectRowAtIndexPath method where the navigation controller is pushed appears as follows:
Settings* Controller = [[Settings alloc] init];
[self pushViewController:Controller animated:YES];
[Controller release];
Fixed by just adding a UITableView in IB, adding IBOutlet to elementList, and setting the UIViewController as the delegate and datasource via IB.
Stack Overflow can be really useful for putting your problems to words so the solution becomes obvious.