I have a question about using Xcode storyboard in the PhoneGap 1.7 project.
I have created an empty PG project, added a storyboard file to the project and dragged a View Controller onto the storyboard. But I do not find the wayto bind this controller to the variable created by PhoneGap framework:
CDVViewController* viewController;
How do I bind it if I can?
Thanks in advance.
Make sure you bind the ViewController in InterfaceBuilder to the CDVViewController class or your own subclass. It might also be useful to add a webview in the IB and bind it to the CDVCordovaView of the above view controller.
One thing you need to take care of is the fact that the CDVViewController does not implement the initWithCoder: method (as of Cordova 2.2.0), which is required for Storyboard usage. Add the following method to CDVViewController, so your view controller get's correctly initialized when instantiated from Storyboards:
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
[self __init];
}
return self;
}
Related
I'm quite new to IOS developpement, and I'm facing a problem here that I haven't encountered before. Here's what I have :
I created a project, added some ViewControllers attached to their own classes. But now, I just added a new ViewController in the storyboard. Then I created a new Objective-C class (with is a subclass of UIViewController). The problem is that in IB, I can't link the ViewController to the newly created class, as I simply don't have the class in the list provided by IB (see the image below). My new class is called MapShownViewController, but as you can see on the image, it's not available.
It worked well for all my other classes but not for this one.
Here's the MapShownViewController.h :
#import <UIKit/UIKit.h>
#interface MapShownViewController : UIViewController
#end
And the MapShownViewController.m :
#import "MapShownViewController.h"
#interface MapShownViewController ()
#end
#implementation MapShownViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Can someone explain me what I made wrong please ?
I had this exact problem and it drove me mad. I first noticed it after upgrading XCode to 4.4 from 4.1. I had an existing project that I had been working on in the older version of XCode, and I continued to work on it in 4.4. I did exactly what you did and created a new View in the story board and then created the sub-class files, but the class just was not avaiable in the Custom Class dropdown in IB. After much Googling and frustration I resorted to Quit Xcode (complete quit, not just close) and then re-start it. Then as if by magic it all started working and the new class was immediatley available in the IB custom class dropdown.
Ran into the same issue and restarting XCode was no help. You can always right click the storyboard and select Open As > Source Code. Find your view controller element in the XML file and add a customClass attribute:
<viewController title="Login" id="TJH-Bg-q4u" customClass="XYZLoginViewController" sceneMemberID="viewController">
...
</viewController>
Manual override FTW :).
Check your project settings. xcode->targets->build phases->compile sources
your viewcontroller's implemantation file must be added to this list.
For this to work you have to make sure of the following:
1) The element added to the storyboard is an UIViewController
2) The class you defined has the UIViewController as its superclass
#interface MapShownViewController : UIViewController
3) The Class is being correctly built in the project.
I've been running into this issue and tried all other solutions posted here.
The thing that worked for me was to set the correct super class after creating a custom class. Then you should be able to find and select it from the class dropdown.
e.g.
class LabsViewController: UITableViewController {
Check if you did choose the correct super class in your new class. Sometimes you create a view controller inherited by a UITableVIewController. This one can't be applied to a ViewController pattern in the Storyboard.
I had to set my custom class which inherit from UIViewController and act as table view controller to UITableViewController. I made simple trick and just changed my custom class inheritance to ": UITableViewController" and then i can set this class freely to controller. Of course after it was set i changed inheritance back.
I had the same issue with Xcode 7.1.1 on a Mac OSX app. I tried all the suggestions from the other answers – no success.
Finally I deleted my view controller files and created brand new ones.
Then it suddenly worked...
Just adding another possible solution that helped solve my problem since the others didn't.
I noticed that searching for my custom View Controller file using Command+Shift+O it was being found, but I couldn't see in which folder the file was, so I noticed that for some reason my custom class was missing from the project but still being found in the search.
All I had to do was to move the files to the project again and Voila!
Hope this can help someone in the future.
I am trying to manually start a view controller using storyboards.
That is written in code as opposed to wiring it up. I tried:
self initWithNibName:(NSString *) bundle:(NSBundle *)
but I am not sure if they are classed as nibs or what they are classed as in storyboards. Any help would be great thanks!
Sounds like you are looking for this method:
AlertContainerViewController *alertContainerViewController =
[[UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:NULL]
instantiateViewControllerWithIdentifier:#"alertContainer"];
You need to give the ViewController object in the Storyboard a unique identifier and specify the subclass. You do both through the Property Inspector.
How do I prevent a UIVIewController from loading the xib?
I downloaded an XCode (iPhone) project online, and I want to stop the xib file from loading. The view did load method doesn't have any code in it which deals with xib. How do I force the UIViewController to be loaded from it's viewDidLoad method instead of the xib?
Overwrite loadview but DO NOT call [super loadview]. Example:
-(void)loadView{
self.view = [UIView new];
[self.view setBackgroundColor:[UIColor redColor]];
}
From the Documentation
loadView
Creates the view that the controller manages.
You should never call this method
directly. The view controller calls this method when the view property
is requested but is currently nil. If you create your views manually,
you must override this method and use it to create your views. If you
use Interface Builder to create your views and initialize the view
controller—that is, you initialize the view using the
initWithNibName:bundle: method, set the nibName and nibBundle
properties directly, or create both your views and view controller in
Interface Builder—then you must not override this method.
The default implementation of this method looks for valid nib
information and uses that information to load the associated nib file.
If no nib information is specified, the default implementation creates
a plain UIView object and makes it the main view.
If you override this method in order to create your views manually,
you should do so and assign the root view of your hierarchy to the
view property. (The views you create should be unique instances and
should not be shared with any other view controller object.) Your
custom implementation of this method should not call super.
If you want to perform any additional initialization of your views, do
so in the viewDidLoad method. In iOS 3.0 and later, you should also
override the viewDidUnload method to release any references to the
view or its contents.
Write your own init method. Later if you require the nib you can create a UINib object and when you need the view you can use instantiateWithOwner.
Using init when creating your view controller will prevent the nib loading. Another thing to do is to name the nib something other than the name of the view controller - because the nib can be loaded automatically if they match. I use ViewControllerName_iPad or ViewControllerName_iPhone and create the view required depending on device idiom.
The code to load from the xib file is not in the viewDidLoad method of the view controller itself.
You should usually find it in the application delegate's didFinishLaunchingWithOptions: method, or in the info.plist file, under the NSMainNibFile entry.
Try changing the initWithNibNameOrNil method to just init.
If that doesn't work, also override the loadView method by uncommenting it and setting your view there.
Here's an example:
- (id)init
{
self = [super init];
if (self) {
// Custom initialization
}
return self;
}
- (void)loadView {
[super loadView];
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,460)];
myView.backgroundColor = [UIColor redColor];
self.view = myView;
[myView release];
}
Perhaps I'm barking up the wrong tree here, but is the UIViewController loading its view from a XIB because the XIB that loads the UIViewController itself has a "NIB Name" set in the view controller's settings?
e.g. load up MainWindow.xib, see your view controller. Select it, then look in the view controller settings over on the right (4th tab). One of the settings is "NIB Name". Just make that blank to stop the view controller loading its view from that XIB/NIB.
I've noticed that there are two different ways to load nib/xib files:
via the UIView's initWithNibName:bundle: method
NSBundle's loadNibNamed:owner:options: method.
Can someone explain the differences between these two and when it is more appropriate to use one over the other and in what circumstances?
For instance, if I'm loading a custom table section header view from a nib file in the tableView:viewForHeaderInSection: method, which one would I use?
Or, if I were loading a custom table view cell from a nib file, which one would I use?
NSBundle’s methods are the generic API to use for unarchiving NIBs. They do the actual work (together with NSNib).
UIViewController’s initWithNibName:bundle: on the other hand is a way to initialize a view controller which (might) load its view from a nib. The method does not itself load the nib but just takes note of the name. The controller loads the nib lazily when the view is requested.
I’m not aware of any nib loading in UIView.
If your header's view controller contains IBOutlets to any fields in the nib file it will be better to load the nib file instead of calling initWithNib.
In the view controller of the header file modify the initiation statement as the following .The default statement is commented out.
By doing so you will be able to access the fields in the nib file using the IBoutlets.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
//self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
// Custom initialization.
if ([[NSBundle mainBundle] loadNibNamed:#"NibFile" owner:self options:nil]) {
}
return self;
}
Being new to Cocoa, I'm having a few issues with Interface Builder, UIViewController and friends.
I have a UIViewController subclass with a UIView defined in a xib, and with the controller's view outlet connected to the view. The xib's "file's owner" is set as myViewcontroller subclass.
In this one instance, the following code to load the controller/view (from the main view controller) doesn't work as expected:
if ( self.myViewController == nil )
{
self.myViewController = [[MyViewController alloc]
initWithNibName:#"MyViewController" bundle:nil];
}
[self.navigationController
pushViewController:self.myViewController animated:YES];
In MyViewController's methods, I have placed breakpoints and log messages to see what is going on:
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
NSLog(#"initWithNibName\n");
}
return self;
}
-(void)viewDidLoad {
[super viewDidLoad];
NSLog(#"viewDidLoad\n");
}
Expected result
Both -initWithNibName and -viewDidLoad methods are called, and myViewController's view is displayed.
Observed result
Only -initWithNibName is called, the view is not displayed.
Have I missed something? Can anyone recommend anything to check? (Particularly in the wondrously opaque Interface Builder tool).
RE: SOLUTION FOUND!!!!!
Indeed that seems to be a working solution, however the real trick is not in setting the view.hidden property to NO, what makes the view load from the nib file is the calling of the UIViewController's view method, the view only actually gets loaded from the nib when the view method is called for the first time.
In that sense, a simple [viewController view] message would force the view to load from the nib file.
Ok, I have a partial answer - maybe the gurus can explain some more. The problem is:
[self.navigationController pushViewController:myViewController animated:YES];
Looking more closely, in this case self.navigationController is nil - so the push message is going no-where.
Instead, if I send:
[self.view addSubview:self.myViewController.view];
Then the view appears and -viewDidLoad is called.
I'm not entirely sure why self.navigationController is not set in this instance - the only thing I can think of is that self is a subclass of UIViewController rather than UITableViewController (where the pushViewController code came from).
Also, silently allowing messages to go to nil seems like a bad idea, although these answers say otherwise. See also my question here.
Final edit:
Answers in comments below, I've realised the display function that I was actually after (given myViewController is modal) is:
[self presentModalViewController:myViewController animated:YES];
Thanks everyone for their helpful responses.
SOLUTION FOUND!!!!!
Even something as innocuous as this makes the viewDidLoad method call happen.
Insert this right after alloc initWithNibName
viewController.view.hidden = NO; //calls viewDidLoad
make sure that the view outlet in File's Owner (your viewController subclass) is connected to the actual view (i.e. the 480X320 canvas you see on your screen that you use to build your UI)
Chances are that you might not have linked the supposed ViewController in main.storyboard from the Identity Inspector to the custom class you created. You might be able to navigate to that controller from other view controllers via segues but any of viewDidLoad(), viewWillAppear() etc. won't be executed.
Simply use
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
//Your Code here
}
instead of the viewDidLoad method.
Another reason, somewhat obvious in retrospect: if viewController.view is set in code, then the viewDidLoad event will not trigger.
It looks like a capitalization problem to me. You're referencing the class MyViewController instead of the property myViewController in the call to pushViewController.
Check your run log for errors. Almost certainly, the NIB is not loading, and there should be an error to that effect. The most likely cause for that is failure to put it in the bundle. Look in your "Copy Resources" build phase and make sure that the XIB is actually being copied. Build for the simulator, and go down into the build directory and make sure that the NIB is in the .app bundle.
Apart from other answers here,
It often happens when the identifier with which you instantiate your ViewController from the storyboard is incorrect. For e.g.
[[self getStoryboard] instantiateViewControllerWithIdentifier:MyVC];
If MyVC is the identifier of some other ViewController, this might happen.
OP is using nib instead of storyboard here. But the answer applies.
The page has been presented but not visible in Debug view hierarchy & in device(simulator also), issue happens based on and
i found the fix:
func viewWillLayoutSubviews{
if day == true{
self.view.backgroundColor = .clear
}else{
self.view.backgroundColor = .blue
}
}
Don't try to implement the self.view (viewcontrollers view) in function of layoutsubviews. So better use self.view in viewwillappear or viewdidload. This issue happens starts from v-14 devices.
Hope it works for you too.