Why am I seeing a black screen? Did I not alloc something? - objective-c

In xcode, this is one of the views I have created:
If I run the program in the simulator, I can see this view fine. However, if I create a UIViewController class and hook it up with this view (I confirmed this view is a UIViewController), this is what I get in the simulator:
Why do I get this blank screen? How can I get the screen that looks like the first image?
Edit: code
#import "EnterLevelViewController.h"
#interface EnterLevelViewController ()
#end
#implementation EnterLevelViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)loadView
{
// Implement loadView to create a view hierarchy programmatically, without using a nib.
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end

It appears from your code that you have uncommented the -(void)loadView method from the view controller, which is provided in the template. When you do this, the controller will try to construct the view programmatically, instead of using the nib (storyboard). Remove the empty method completely and see if that helps.

just drag from the tabBarController to the new ViewController in the storyboard and when you let go, press the selection for relationship ViewController.
Here is a quick example of how to set it up with three tabs, one with your view:
https://github.com/HubertK/TabBar_Example

The storyboard that was part of your project at the outset already included a view controller and its associated view. You can see it in the storyboard image that you posted -- it's the icon at the bottom with the light gray background. That view controller was set up as the root view controller, and the code that came as part of the project template loaded that view controller and its view. That's what you were seeing in the simulator. When you added another view controller, you must have configured it as the root controller instead. Since it doesn't have a view connected to it (or if it does, the view is empty), you no longer see anything.

Related

How to make a multiple view app with a class linked to each view

Apologies if this has been replied already, I've been searching and I quiet cannot find what I am looking for.
I am trying to make a multiple view application (based on the single view template) and I want to have an object linked to each of the views.
So my intention is to have the same I have coming from the single view template: 1 view on the storyboard which is linked to the ViewController class.
I found some tutorials by using Navigation Controllers, Page View controllers, etc... but I don't want to use that functionality, I prefer to create my own buttons and link them to those pages.
I have a few questions, if you can help:
1 - Should I have an array of view objects?
I've seen an old tutorial where the guy creates a new view object when a button is pressed and then set the view as modal (which leads to the other class) and afterwards it destroys it immediately (I guess when the code come back once the modal view is closed).
In my case I would like to have an array of views and initialize all of them at the beginning of the app and just swap from one to the other depending on the user actions.
Which one is a better approach?
2 - How I create the class linked to the other view?
Can I create a normal class and make it subclass of UIViewController, is that enough or I need something else?
3 - Once I have the class created, how can I 'link' it to a view on the storyboard?
Basically I would like to have the outlets of each view in its correspondent class (and actions, etc...).
I am not sure if what I am trying to do is actually the correct way, any comments or help is more than appreciated :)
EDIT: I´ve managed to create a class, link it to a view of the storyboard and lunch it when the user press a button, but the new view appears completely black - any ideas?
Here is my code:
TestView.h:
#import <UIKit/UIKit.h>
#interface TestView : UIViewController
#end
TestView.m:
#import "TestView.h"
#interface TestView ()
#end
#implementation TestView
- (id) init
{
self = [super init];
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
#end
Then in the storyboard, I dragged in a new View, and in the "Identity Inspector" in the field "Class" I selected the TestView.
The in the file ViewController (the one created by default by the single view wizard), I added an action when a button is pressed:
- (IBAction)goToView1:(id)sender
{
[self presentViewController:view1 animated:YES completion:nil];
}
Also in the ViewController, function 'ViewDidLoad' I initialize the TestView class:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
view1 = [[TestView alloc] init];
}
So when I pressed the button it seems is doing something right or attempting to move to a different view, but the whole screen appears black - Am I missing something?
Thanks a lot in advance!!

Xcode: How to add Custom View from XIB File in a UIScrollView

Coming from an Android and Java background, I am relative new with Xcode Development.
I am using Xcode 5.0.2 and created my first IOS Application by selecting Create a New Xcode Project -> Single View Application. The initial project structure has been generated and I found that there is a Main_iphone.storyboard file which opens a UI Designer where I can drag and drop items to it. I selected UIScrollView and dragged it into the main window that has been generated.
Now in the Controller header file, I added #property (nonatomic, retain) IBOutlet UIScrollView *scrollView; so that i could access the scrollView from inside my controller code.
I wanted to add an item to the scrollView programatically so I created a template Custom View by adding new file -> Objective-C Class with XIB for User Interface, named it TSTFilesInfoController and designed the XIB by adding a View and a label inside the view. Same with the scrollView above, I created a property to expose the mainView in my controller class.
I hardcoded a loop of 10x inside the controller of the UIScrollView and inside the for loop I am instantiating TSTFilesInfoController and adding the view to the UIScrollView. But when i run the application, nothing is shown or added in the UIScrollView.
Heres the code for adding the CustomView:
- (void)viewDidLoad {
[super viewDidLoad];
for ( int i = 0; i < 10 ; i++) {
TSTFilesInfoController *info = [[TSTFilesInfoController alloc] init];
[self addChildViewController:info];
[self.scrollView addSubview:info.mainView];
NSLog(#"View has been added into the scrollView");
}
}
Can someone please tell me whats wrong with my codes and what would be the correct approach to achieve the output that i wanted? Thank you in advance for the help.
-- EDIT --
This code is auto-generated in TSTFilesInfoController.m
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
This is a misuse of a UIViewController subclass. Do not use a view controller just as a sort of fishing rod to hook a view that's inside a xib file. Simply load the xib file and grab the view yourself, and stuff it into your interface.
There are complex rules for how to put a view controller's view manually inside your interface, and in general it is something you should be reluctant to do. But making views come and go dynamically and directly is easy and common.
Let's suppose the .xib file is called TSTFilesInfo.xib and it has a top-level UIView subclass object, class MyView, which is the one you want. Then:
MyView* v = (MyView*)
([[UINib nibWithNibName:#"TSTFilesInfo" bundle:nil]
instantiateWithOwner:nil options:nil][0]);
This loads the nib once, instantiating its contents, and handing you a reference to that instance (the UIView in this case). Now plunk v into your interface. Keep that reference in an instance variable (probably weak, since it is retained by its superview) so that you can subsequently configure and communicate with any subviews of MyView to which you have created outlets.
NOTE: However, I must say from the example so far that it sounds to me like what you really want here is a UITableView, not a simple UIScrollView. It comes all set to do just the kind of thing you seem to up to here.

IBOutlets not being set EXCEPT when creating throwaway variables during initWithNibName:bundle:

Let me first say that I've searched Google and, although many have similar issues, I haven't seen anything with the following bizarre behavior and remedy.
I've created a UIViewController and associated nib with several IBOutlets. On trying to consume this nib from another class, I discovered that after instantiating it with initWithNibName:bundle:, the IBOutlets are still nil.
I confirmed that they are correctly wired up, and yes, they are being synthesized, but still nothing. While investigating further, I changed the initWithNibName method as follows:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UIView *view = self.view;
NSArray *subviews = self.view.subviews;
NSLog(#"Loaded view containing %d subviews.", [subviews count]);
}
return self;
}
Unbelievably, the addition of the three lines here, creating throwaway variables and logging, makes the IBOutlets wire up properly and work from the outside.
I have cleaned and rebuilt and restarted my machine, but still, if I remove these lines, it stops working. I am really baffled here and concerned that I have some kind of voodoo working that's going to break the moment I ship. Any ideas on what could be happening?
You misunderstand what initWithNibName:bundle: does, and when a UIViewController loads its nib.
The initWithNibName:bundle: method records the name of the nib to be loaded. It does not immediately load the nib.
The -[UIViewController view] method loads the nib on demand, by sending [self loadView] if necessary. The implementation of -[UIViewController view] is basically this:
- (UIView *)view {
if (_view == nil) {
[self loadView];
[self viewDidLoad];
}
return _view;
}
So if you call self.view in your initWithNibName:bundle: override, that will cause the view controller to load its nib.
However, it's generally inappropriate to call self.view from initWithNibName:bundle:. A view controller should be able to exist without its view hierarchy.
For example, suppose a user is running your app and navigates through several view controllers, which you implement by pushing the view controllers onto a navigation controller. Then the user switches to another app for a while. Now the system is running low on memory, so it kills background apps - including your app.
When the user launches your app again, your app (if it's well done) should try to restore the user's state. That means reloading the navigation controller with the stack of push view controllers. But only the top view controller's view is visible on screen. It would be a waste of time, memory, and battery to reload the views for all of the hidden view controllers immediately. That's why each view controller loads its nib on demand.

Topbar cannot rotate in landscape view with storyboard

I have just converted from .nib files to storyboard, but suddenly the view wont rotate topbar in landscape view. All the settings are "inferred" in my view, and i have not really made any changes since the conversion.
Is this a common problem when upgrading? I have not found any specific info.
And furthermore i do not force any view rotations in my code.
If any more info is needed i can supply anything!
Thanks in advance.
ViewController:
- (void) viewDidLoad {
[super viewDidLoad];
self.view.autoresizingMask = UIViewAutoresizingNone;
self.view.autoresizesSubviews = UIViewAutoresizingNone;
}
I've taken a look at your code and you seem to be missing a method that allows your view controller to rotate freely.
Subclass UIViewController e.g. like this:
// .h file
#interface OrientationAwareViewController : UIViewController
#end
// m.file
#implementation OrientationAwareViewController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
#end
Then set OrientationAwareViewController in the storyboard as your main view controller's class name. That said, I have no idea how this worked for you when using nibs :) Documentation says clearly:
By default, this method returns YES for the UIInterfaceOrientationPortrait orientation only. If your view controller supports additional orientations, override this method and return YES for all orientations it supports.

How to load a SplitViewController in a universal app

This is probably a straight forward problem, but I for some reason cannot get it to work.
I have an universal app, with icons on the start screen (TTLauncher) and use TTNavigator to push in view controllers.
On one of the icons a normal tableView is loaded (for the iPhone). As that is not nice for the iPad, I want to load that same tableView (if possible, as it has all the logic in it, I can adjust the code to include the required code for the splitview).
But how do I do that?
I created a UIViewController (called SplitViewController), with a XIB in which I included the SplitViewController, and I made the class for the RootViewContorller of the splitview my custom TableViewController..
I thought it would work if I added the view to the TTNavigator, but nothing happens:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"TEST!");
TTNavigator* navigator = [TTNavigator navigator];
[[navigator window] addSubview:splitViewController.view];
}
(Test is called)
I finally did try:
- (void)viewDidLoad
{
[super viewDidLoad];
//[self setView:splitViewController.view];
[window addSubview:splitViewController.view];
}
But still nothing happens. I think it is obvious that I don't understand how this works...
Any tips? Or how can I better describe this, I assume, simple problem?