"addChildViewController:" crashes on iPad but not iPhone - ios

I have an iPhone app that works great when running on the phone however crashes at launch when running on compatibility mode on the iPad. I use iAd in my project, specifically i'm using
Bannerviewcontroller.h and .m
from the iAd suite to present the banner programmatically.
in my App Delegate I wrap some view controllers as follows.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController *viewController1, *viewController2, *catVC3, *otherVC4;
UINavigationController *navController, *dognav, *catnav, *othernav;
viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController_iPhone" bundle:nil];
viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController_iPhone" bundle:nil];
catVC3 = [[catViewController alloc]initWithNibName:#"catViewController_iPhone" bundle:nil];
otherVC4 = [[otherViewController alloc]initWithNibName:#"otherViewController_iPhone" bundle:nil];
navController = [[UINavigationController alloc]initWithRootViewController:viewController1];
dognav = [[UINavigationController alloc]initWithRootViewController:viewController2];
catnav = [[UINavigationController alloc]initWithRootViewController:catVC3];
othernav = [[UINavigationController alloc]initWithRootViewController:otherVC4];
_tabBarController = [[UITabBarController alloc] init];
NSArray *controllers = [NSArray arrayWithObjects:navController,dognav,catnav,othernav,nil];
_tabBarController.viewControllers = controllers;
//wrap tabbar controller in adbanner controller
_bannerViewController = [[BannerViewController alloc] initWithContentViewController:_tabBarController];
self.window.rootViewController = _bannerViewController;
[self.window makeKeyAndVisible];
return YES;
Then the crash happens here in my
Bannerviewcontroller.m
#import "BannerViewController.h"
#implementation BannerViewController
{
ADBannerView *_bannerView;
UIViewController *_contentController;
}
- (id)initWithContentViewController:(UIViewController *)contentController
{
self = [super init];
if (self != nil) {
_bannerView = [[ADBannerView alloc] init];
_bannerView.delegate = self;
_contentController = contentController;
}
return self;
}
- (void)loadView
{
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[contentView addSubview:_bannerView];
[self addChildViewController:_contentController];
[contentView addSubview:_contentController.view];
[_contentController didMoveToParentViewController:self];
self.view = contentView;
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return [_contentController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
- (void)viewDidLayoutSubviews
{
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
_bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
} else {
_bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape;
}
CGRect contentFrame = self.view.bounds;
CGRect bannerFrame = _bannerView.frame;
if (_bannerView.bannerLoaded) {
contentFrame.size.height -= _bannerView.frame.size.height;
contentFrame.origin.y = _bannerView.frame.size.height;
bannerFrame.origin.y = contentFrame.size.height - contentFrame.size.height;
} else {
bannerFrame.origin.y = contentFrame.size.height;
}
_contentController.view.frame = contentFrame;
_bannerView.frame = bannerFrame;
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
[UIView animateWithDuration:0.35 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
[UIView animateWithDuration:0.35 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
#end
and throws this exception:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
Whats going on here? Thanks in advance!

The error tells, that _contentController is not initialized. Where / how do you assign it? I can't see it in the AppDelegate code.

Related

View shifted across to the right

I am trying to figure out why this tableView is shifted across to the right, it appears in every view the app uses, yet the app itself displays fine, it's only when the tableView appears is everything shifted out of the screen.
I believe the initializing is here;
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"Lets load the frame");
CGRect frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self.view setFrame: frame];
self.contentSizeForViewInPopover = CGSizeMake(320, 480);
m_mywork = nil;
dataArray = [LoadSessionController loadTableData:YES];
}
Here is the initializing from another class;
on iPad display is perfect.
- (void) ShowInitialMenu
{
InitialMenuController *MewMgrController = [[InitialMenuController alloc] initWithStyle:UITableViewStyleGrouped];
MewMgrController.delegate = self;
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController: MewMgrController];
if(![ColorSplashAppDelegate isiPad]){
[self presentViewController:navController animated:YES completion:nil];
}
else{
UIPopoverController* popover = [[UIPopoverController alloc] initWithContentViewController:navController];
popover.delegate = self;
[popover presentPopoverFromRect:CGRectMake(30.0, 940.0, 30.0, 480.0)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionDown
animated:YES];
ColorSplashAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
appDelegate.popoverController = popover;
}
[navController release];
[MewMgrController release];
[self enableUserAction:YES];
}
Try This.
-(void)viewDidLayoutSubviews
{
CGRect frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self.view setFrame: frame];
self.contentSizeForViewInPopover = CGSizeMake(320, 480);
m_mywork = nil;
}

self.window setRootViewController not working on xcode 6.1.1

I am facing some issues w.r.t XCode 6.1.1 , here is my code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[DBManager getSharedInstance] initWithdbFile];
[[DBManager getSharedInstance] createtableScripts];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
containerViewController =[[CprViewController alloc] init];
[containerViewController Setup];
[self.window setRootViewController:containerViewController.containerViewController];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
[self pickModel];
return YES;
}
Now the app works fine in older XCode i.e 5.1.1 but while simulating on XCode 6.1.1 the app launches the Launch image and there is no response i.e the execution ends at [self.window setRootViewController:containerViewController.containerViewController]; and it doesnt proceed to execute further lines of code. It shows no error in console. (The app however runs on device having latest OS (i.e iOS 8). Please help.
*Edited Post -- begins here
Thanks for helping out. Here’s the problem that i am facing,
This is in my AppDelegate file
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[DBManager getSharedInstance] initWithdbFile];
[[DBManager getSharedInstance] createtableScripts];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; //Now Removed!!!
containerViewController =[[CprViewController alloc] init];
[containerViewController Setup];
self.window.rootViewController = containerViewController.containerViewController;
self.window.backgroundColor = [UIColor whiteColor];//Now Removed!!!
[self.window makeKeyAndVisible];//Now Removed!!!
[self pickModel];
return YES;
}
Now i have removed the three lines just as you suggested and now the execution continues
Now this is my code for [containerViewController Setup];
-(void)Setup
{
SideMenuViewController *leftMenuViewController = [SideMenuViewController homeBookViewController];
CprStartPageViewController *accounts=[[CprStartPageViewController alloc] initWithNibName:#"CprStartPageViewController" bundle:nil];
self.navController= [[CprNavigationViewController alloc]
initWithRootViewController:accounts];
self.containerViewController = [MFSideMenuContainerViewController containerWithCenterViewController:self.navController leftMenuViewController:leftMenuViewController
rightMenuViewController:nil];
[leftMenuViewController.passBookTable selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:0];
}
The above code attaches a side menu (here i am attaching a left side menu) - No error in this code i.e the execution continues.
Now CprLoginViewController is my parentViewController
i.e the parentViewController for the 4 screen that i had mentioned and this is my initWithNibName for the 4 screens
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil parentViewController:(CprLoginViewController*) inVC
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil parentViewController:inVC];
if (self) {
// Custom initialization
}
return self;
}
and the error now occurs in CprLoginViewController where i am using a procedure called showNextPage to navigate between these 4 pages
-(void) showNextPage
{
if (currentPage > numberPages)
return;
CprLoginSubViewController *controller;
switch(currentPage)
{
case 0:
controller = [[Corppersondtl alloc] initWithNibName:#"Corppersondtl" bundle:nil parentViewController:self];
break;
case 1:
controller = [[CprLoginSub1ViewController alloc] initWithNibName:#"CprLoginSub1ViewController" bundle:nil parentViewController:self];
break;
case 2:
controller = [[CprLoginSub2ViewController alloc] initWithNibName:#"CprLoginSub2ViewController" bundle:nil parentViewController:self];
break;
case 3:
controller = [[CprLoginSub3ViewController alloc] initWithNibName:#"CprLoginSub3ViewController" bundle:nil parentViewController:self];
break;
case 4:
controller = [[CprLoginSub4ViewController alloc] initWithNibName:#"CprLoginSub4ViewController" bundle:nil parentViewController:self];
default:
break;
}
CGRect rBounds;
// add the required controller's view to scroll view
if (controller.view.superview == nil)
{
CGRect frame = self.scrollView.frame;
frame.origin.x = CGRectGetWidth(frame) * (currentPage);
frame.origin.y = 0;
controller.view.frame = frame;
[self addChildViewController:controller];
[self.scrollView addSubview:controller.view];
[controller didMoveToParentViewController:self];
// just scroll to appropriate page
rBounds = self.scrollView.bounds;
rBounds.origin.x = CGRectGetWidth(rBounds) * currentPage;
[self.scrollView scrollRectToVisible:rBounds animated:YES];
}
NSLog(#"scrollView is %lf", self.scrollView.frame.origin.y);
viewOriginalbounds = rBounds; //self.scrollView.frame;
currentPage++;
}
In the above code i am attaching a scrollview to scroll the screen upwards when keyboard appears for text inputs.
Now the line if (controller.view.superview == nil) is throwing exc_bad_access error.
Just delete that lines of code
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];

Custom UIViewController add issue

I Created a UIViewController that I want to add on the top of all of my views, the problem is that it's visible for only 1 sec and then disappears from the screen and deallocated. Why this is happening?
This is my code:
- (void)show
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.windowLevel = UIWindowLevelAlert;
self.window.screen = [UIScreen mainScreen];
[self.window makeKeyAndVisible];
UIWindow *mainWindow = [[[UIApplication sharedApplication] delegate] window];
[mainWindow setUserInteractionEnabled:NO];
[self.window addSubview:self.view];
self.view.alpha = 0.0f;
self.backgroundImage.image = [self takeSnapshot];
[UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.view.transform = CGAffineTransformIdentity;
self.view.alpha = 1.0f;
} completion:nil];
}
- (void)dealloc
{
NSLog(#"Screen deallocated.");
}
Looking at the graph of your objects,I assume self is some view controller.
your self.view is subview of Appdelegates UIWindow. When you do
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
your Appdelegate window gets released subsequently your view controller(self) will also be released.
So I would suggest you to retain UIWindow instance before actually releasing it.
You must save variable for your UIViewController in that place from where "show" method was called. For example - just create property…
#property (nonatomic, strong) CustomViewController *cvc;
Otherwise instance of your UIViewController will be released at the end of that method. Because your object won't have any strong references…
If you work with XIB, you can use this code: You have to create an UIView class, for example HeaderView. In your UIViewController [ I will call it BaseViewController] .h you have to add a property:
#property (nonatomic, strong) HeaderView *headerView;
and in .m you have to add this code:
- (id)init {
self = [super init];
if (self) {
[self configureMenuView:self];
}
return self;
}
- (void)configureMenuView:(UIViewController *)vc {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"HeaderView" owner:self options:nil];
for( id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[HeaderView class]]) {
self.headerView = (BannerView *)currentObject;
self.headerView.frame = CGRectMake(0, 0, 768, 1024);
self.headerView.backgroundColor = [UIColor clearColor];
[vc.view addSubview:self.headerView];
break;
}
}
[self.bannerView.closeHeaderButton addTarget:self action:#selector(closeHeaderrView) forControlEvents:UIControlEventTouchUpInside]; // it's only an example if you want add some button in your header.
So, in every view controller you have to import this class: BaseViewContoller and to add it like parent:
#interface TestViewController : HeaderViewController
Hope it works for you :)

Custom Navigation Transitions on iOS 7, how to manage the keyboard?

TabBarController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
PlaylistViewController *playlistViewController = [[PlaylistViewController alloc] init];
UIViewController *otherViewController = [[UIViewController alloc] init];
UINavigationController *playlistNavigationController = [[UINavigationController alloc] initWithRootViewController:playlistViewController];
playlistNavigationController.delegate = self;
self.viewControllers = #[playlistNavigationController, otherViewController];
playlistNavigationController.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemDownloads tag:kTabBarTagPlaylist];
playlistNavigationController.tabBarItem.title = #"Playlist";
otherViewController.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemMore tag:kTabBarTagOther];
playlistNavigationController.navigationBar.tintColor = [UIColor redColor];
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
if (operation == UINavigationControllerOperationPush) return [[FadeTransition alloc] init];
else if (operation == UINavigationControllerOperationPop) return [[SlideTransition alloc] init];
return nil;
}
PlaylistViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor redColor];
UIBarButtonItem *storeBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Store"
style:UIBarButtonItemStylePlain
target:self
action:#selector(test)];
self.navigationItem.leftBarButtonItem = storeBarButtonItem;
UIBarButtonItem *currentlyPlayingButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Now playing"
style:UIBarButtonItemStylePlain
target:self
action:#selector(test)];
self.navigationItem.rightBarButtonItem = currentlyPlayingButtonItem;
self.navigationItem.title = #"Playlist";
self.playlistTableViewController = [[PlaylistTableViewController alloc] initWithStyle:UITableViewStylePlain];
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
searchBar.placeholder = #"Search";
searchBar.delegate = self;
self.playlistTableViewController.tableView.tableHeaderView = searchBar;
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.searchController.delegate = self;
self.searchController.searchResultsDataSource = self;
self.searchController.searchResultsDelegate = self;
[self addChildViewController:self.playlistTableViewController];
[self.view addSubview:self.playlistTableViewController.view];
self.playlistTableViewController.view.frame = self.view.bounds;
self.playlistTableViewController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
[self.playlistTableViewController didMoveToParentViewController:self];
}
FadeTransition.m
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
return 0.5;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
/* view controllers */
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
/* views */
UIView *containerView = [transitionContext containerView];
[containerView addSubview:fromVC.view];
[containerView addSubview:toVC.view];
/* settings */
toVC.view.alpha = 0.0f; /* not visible at start */
[UIView animateWithDuration:[self transitionDuration:transitionContext]
delay:0
options:UIViewAnimationOptionTransitionNone
animations:^{
toVC.view.alpha = 1.0f; /* 100% visible at the end */
}
completion:^(BOOL finished) {
[fromVC.view removeFromSuperview];
[transitionContext completeTransition:YES];
}];
}
This is how it looks like:
When I touch one of the results, a new UIView gets pushed and animated by FadeTransition.
The keyboard automatically gets slided down, but I need to leave the keyboard opened (it should stay behind), how can I do it?

IOS UINavigationController, pushViewController not working

Good evening,
I currently have two UIViewControllers. My appDelegate looks like this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
struct CGRect rect = [[UIScreen mainScreen] bounds];
rect.origin.x = rect.origin.y = 0.0f;
_viewController = [[sandboxViewController alloc] init];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:_viewController];
_window = [[UIWindow alloc] initWithFrame:rect];
[_window makeKeyAndVisible];
[_window addSubview:nc.view];
return YES;
}
The viewController looks like this:
- (void)loadView {
self.view = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 480.0f)];
self.view.backgroundColor = [UIColor whiteColor];
self.navigationItem.title = #"Master View";
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[infoButton addTarget:self action:#selector(switchView:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:infoButton];
}
- (void)switchView:(id)obj {
if(![self navigationController])
NSLog(#"navigationController IS NIL!!!");
if(!_secondView)
_secondView = [[secondViewController alloc] init];
[self.navigationController pushViewController:_secondView animated:YES];
}
By clicking on the info button, that was added to the right side on the navigation bar, I want to switch to the secondView. This, however, is not happening because navigationController logs as nil ! What am I missing here?
Any help is truly appreciated!
You don't have to create the window, it should already exist.
//_window = [[UIWindow alloc] initWithFrame:rect]; //remove this line
[self.window makeKeyAndVisible]; //use the ivar
[self.window addSubview:nc.view];

Resources