ViewDeck with Storyboard - xcode

I have some problems with ViewDeck with my app. I'm trying to use it with storyboard and the examples only shows how to use it with nibfiles. I have checked out many ways to do it here on stackexchange but i don't seem to get it to work.
My code in appdelegate.m file:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//UIViewController* leftController = [[UIViewController alloc] init];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
RightViewController* rightController = [[RightViewController alloc] initWithNibName:#"RightViewController" bundle:nil];
ViewController* centerController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.centerController = [[UINavigationController alloc] initWithRootViewController:centerController];
IIViewDeckController* deckController = [[IIViewDeckController alloc] initWithCenterViewController:self.centerController rightViewController:rightController];
deckController.rightSize = 100;
self.window.rootViewController = deckController;
[self.window makeKeyAndVisible];
return YES;
}
I of course i get the expected error:
2012-12-29 03:55:18.501 Network[27451:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/Rostgaard/Library/Application Support/iPhone Simulator/6.0/Applications/C2BADD3B-660E-4363-8FC7-932B4E9D6172/Network.app> (loaded)' with name 'RightViewController''
*** First throw call stack:
(0x17cd012 0x15f2e7e 0x17ccdeb 0x755fac 0x61ae37 0x61b418 0x61b648 0x61b882 0xbcdf 0xe673 0xb7e2 0xada7 0x61d753 0x61da7b 0x61e964 0x581877 0x5885a3 0x580eed 0x56ab56 0x56adbf 0x56af55 0x573f67 0x2546 0x5377b7 0x537da7 0x538fab 0x54a315 0x54b24b 0x53ccf8 0x261adf9 0x261aad0 0x1742bf5 0x1742962 0x1773bb6 0x1772f44 0x1772e1b 0x5387da 0x53a65c 0x226d 0x2195 0x1)
libc++abi.dylib: terminate called throwing an exception
(lldb)

Here is the code I'm using which works fine:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard* mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
UIViewController* menuController = [mainStoryboard instantiateViewControllerWithIdentifier:#"LeftSideMenu"];
UINavigationController* navigationController = (UINavigationController *) self.window.rootViewController;
self.viewDeckController = [[IIViewDeckController alloc] initWithCenterViewController:navigationController leftViewController:menuController rightViewController:nil];
self.window.rootViewController = self.viewDeckController;
}

Well, solved this myself by using ECSlidingViewController instead, already optimized with storyboard.
https://github.com/edgecase/ECSlidingViewController
Just in case anyone runs into the same problem.

Try this tutorial project, it works

Related

UISplitViewControllerDisplayModePrimaryOverlay causes "Unbalanced calls to begin/end appearance transitions"

In iOS 8, setting the preferredDisplayMode on a UISplitViewController to PrimaryOverlay is generating the following warning:
"Unbalanced calls to begin/end appearance transitions for UINavigationController"
There is no problem if I set preferredDisplayMode to AllVisible or don't set it at all. Problem occurs for all iPads and iPhones in the simulator that I've tried. Problem occurs whether the app starts up in portrait or landscape.
Here's some very simple code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UITableViewController *tableViewController = [[UITableViewController alloc] init];
UIViewController *viewController = [[UIViewController alloc] init];
UINavigationController *masterNavController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
UINavigationController *detailNavController = [[UINavigationController alloc] initWithRootViewController:viewController];
UISplitViewController *svc = [[UISplitViewController alloc] init];
[svc addChildViewController:masterNavController];
[svc addChildViewController:detailNavController];
//svc.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
svc.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
self.window.rootViewController = svc;
[self.window makeKeyAndVisible];
return YES;
}
Wrap your display code in dispatch_async. Otherwise iOS seems to get confused with other animations running at the same time.
dispatch_async(dispatch_get_main_queue(), ^{
svc.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
});
or
dispatch_async(dispatch_get_main_queue()) {
svc.preferredDisplayMode = .PrimaryOverlay
}

No root view controller error on Xcode 5

I get this error on Xcode 5:
Application windows are expected to have a root view controller at the end of application launch
My code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[Flurry startSession:#"HJ4X7X6PB3942VGHQWWZ"];
screenRect = [[UIScreen mainScreen] applicationFrame];
if (screenRect.size.height > 500)
{
isFive = YES;
NSLog(#"is iPhone 5");
}else{
isFive = NO;
}
[[SQLiteOperator sharedOperator] openDatabase];
[self setupLang];
[self handleTabBarLanguage];
[self handleAppUpdatePopUpLanguage];
_banner_view_controller = [[BannerViewController alloc] initWithNibName:#"BannerViewController" bundle:nil];
[_banner_view_controller send_request];
[_banner_view_controller didHidden];
[_navigation_controller.view addSubview:_banner_view_controller.view];
[CoreData sharedCoreData].banner_view_controller = _banner_view_controller;
// Create content and menu controllers
//
DEMONavigationController *navigationController = [[DEMONavigationController alloc] initWithRootViewController:[[DEMOHomeViewController alloc] init]];
DEMOMenuViewController *menuController = [[DEMOMenuViewController alloc] initWithStyle:UITableViewStylePlain];
// Create frosted view controller
//
REFrostedViewController *frostedViewController = [[REFrostedViewController alloc] initWithContentViewController:navigationController menuViewController:menuController];
frostedViewController.direction = REFrostedViewControllerDirectionLeft;
frostedViewController.liveBlurBackgroundStyle = REFrostedViewControllerLiveBackgroundStyleLight;
// Make it a root controller
//
self.window.rootViewController = frostedViewController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
If you are using storyboard click on the project name in project navigator in Xcode. Then look for deployment info. Select Main Interface as your storyboard name. In app delegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// // Override point for customization after application launch.
// self.window.backgroundColor = [UIColor whiteColor];
// [self.window makeKeyAndVisible];
return YES;
}
And now try it.

How to use 2 storyboards for different screen sizes?

What and where do I put code for two storyboards one if they are running on a 3.5" screen and one for a 4" screen. I have two storyboards. One is named Main.storyboard and the other one is named Main2.storyboard.
The code goes into the AppDelegate.m file and looks similar to this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:#"AlternateStoryboard" bundle:nil];
UIViewController *vc = [mainstoryboard instantiateInitialViewController];
self.window.rootViewController = vc;
return YES;
}
You'll need to check the screen size first, of course, see the docs for UIScreen.
Something like this might help. In your AppDelegate's application:didFinishLaunchingWithOptions: method:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone
&& [UIScreen mainScreen].bounds.size.height == 568.0) {
//is 4 inch screen
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *viewController = [storyboard instantiateInitialViewController];
self.window.rootViewController = viewController;
}
else {
//is 3.5 inch screen
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main2" bundle:nil];
UIViewController *viewController = [storyboard instantiateInitialViewController];
self.window.rootViewController = viewController;
}
return YES;
}
The if/else statement checks the screen size and loads the appropriate storyboard.

Is it possible to unit test a WindowController thats initialised with a nib?

I have a simple Mac OS application that comes with the default MainMenu.xib. In there I have a second window for preferences and a PreferencesWindowController. I'd like to get the following test working:
#implementation TestPreferencesWindow
- (void)testProtectsUserPasswordByUsingAPasswordField
{
PreferencesWindowController *controller = [[PreferencesWindowController alloc] initWithWindowNibName:#"MainMenu"];
XCTAssertInstanceOf([[controller passwordField] class], NSSecureTextField);
}
#end
The problem is that [controller passwordField] is not initialised (because the nib isn't loading?) so it always returns nil.
How do I tell the nib to create all the bindings?
When I call [controller window] is gives the error, and returns nil:
Could not connect the action orderFrontStandardAboutPanel: to target of class PreferencesWindowController
For debugging I have tried the following:
NSBundle *bundle = [NSBundle mainBundle];
XCTAssertNotNil(bundle);
NSString *nibPath = [bundle pathForResource:#"MainMenu" ofType:#"nib"];
XCTAssertNotNil(nibPath);
PreferencesWindowController *controller = [[PreferencesWindowController alloc] initWithWindowNibPath:nibPath owner:self];
NSLog(#"%# %#", [controller window], [controller passwordField]);
However it still prints (null) (null) ...
To get rid of the warning:
NSBundle *bundle = [NSBundle mainBundle];
XCTAssertNotNil(bundle);
NSString *nibPath = [bundle pathForResource:#"MainMenu" ofType:#"nib"];
XCTAssertNotNil(nibPath);
NSApplication *app = [NSApplication sharedApplication];
PreferencesWindowController *controller = [[PreferencesWindowController alloc] initWithWindowNibPath:nibPath owner:app];
NSLog(#"%# %#", [controller window], [controller passwordField]);
No more warning, but still prints (null) (null) .. I feel like I'm getting closer though...
I got solution. Write below method in your .m file, and declare public in .h file
MyWindowController.m file
- (instancetype)initWithWindowNibPath:(NSString *)nibPath {
self = [super initWithWindowNibPath:nibPath owner:self];
if(self)
{
//initialize stuff
}
return self;
}
MyWindowController.h file
- (instancetype)initWithWindowNibPath:(NSString *)nibPath;
Now write your code:
NSBundle *bundle = [NSBundle mainBundle];
XCTAssertNotNil(bundle);
NSString *nibPath = [bundle pathForResource:#"MyWindowController" ofType:#"nib"];
XCTAssertNotNil(nibPath);
MyWindowController *controller = [[MyWindowController alloc] initWithWindowNibPath:nibPath];
NSLog(#"%# %#", [controller window], [controller passwordField]);
This is works perfect for me.
Reason:
owner value not properly set in initWithWindowNibPath method and therefore not set class's properties NSOutlet to nib's control.

SIGABRT error during interface change

(IBAction)switchAppointment {
AppointmentController *appt = [[AppointmentController alloc] initWithNibName:nil bundle:nil];
appt.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:appt animated:YES];
[appt release];
}
That is the code that I use to switch from one .xib to another, however on the line that says "self presentModalViewController:appt animated:YES" , I'm getting a SIGABRT error. My app crashes immediately when I try to go into that interface.
FYI too I'm on Xcode 4.2, but it was doing this before I downloaded the beta.
I have also same answer for the code:
nextView *second=[[nextView alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:second animated:YES];
[second release];
Yours
Miska

Resources