Pass data in UISplitViewController - ios

I want to pass data from Master view controller to Detail view controller according to the picture below. I am using protocols and Delegates to pass data. There is no problem to pass data from A to B. It happens when I try to pass data from A to C.
But the app is returning the error:
014-07-05 01:03:00.043 PassingDataBack[2216:70b] -[UIViewController
didSelectData:]: unrecognized selector sent to instance 0x8e3d2d0
2014-07-05 01:03:00.047 PassingDataBack[2216:70b] *** Terminating app
due to uncaught exception 'NSInvalidArgumentException', reason:
'-[UIViewController didSelectData:]: unrecognized selector sent to
instance 0x8e3d2d0'
I believe the problem is in the AppDelegate file that i wrote:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UISplitViewController *splitViewController = (UISplitViewController *) self.window.rootViewController;
splitViewController.delegate = [splitViewController.viewControllers lastObject];
DetailViewController *detailViewController = (DetailViewController *)[[splitViewController.viewControllers objectAtIndex:1] topViewController];
MasterViewController *masterViewController = (MasterViewController *)[[splitViewController.viewControllers objectAtIndex:0] topViewController];
masterViewController.delegate = detailViewController;
// Override point for customization after application launch.
return YES;
}
Could you help to find the solution?

Related

3D Touch for Shortcuts Crashes

My app is a single-view NavigationController as a root view controller style app. In it, I have a few different shortcut items for using 3D Touch. I have them all set up in the Info.plist fine (I've done this before with a Tab Bar app and it worked fine), but it crashes every time an shortcut action is pressed. Here is my the code used in AppDelegate in Obj-C.
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler {
UINavigationController *nav = (UINavigationController *) self.theMainView.view;
NSLog(#"%#", shortcutItem.type);
if ([shortcutItem.type isEqualToString:#"com.316apps.Fritch.inviteFriends"]) {
ImagePicker *vimeo= [[ImagePicker alloc] init];
[nav pushViewController:vimeo animated:YES];
}
if ([shortcutItem.type isEqualToString:#"com.316apps.Fritch.viewAlerts"]) {
NewsViewController *dvController8 = [[NewsViewController alloc] initWithNibName:#"NewsViewController" bundle:[NSBundle mainBundle]];
[nav pushViewController:dvController8 animated:YES];
}
if ([shortcutItem.type isEqualToString:#"com.316apps.Fritch.viewDirectory"]) {
DirectoryViewController *dvController8 = [[DirectoryViewController alloc] init];
[nav pushViewController:dvController8 animated:YES];
}
}
Crash Log:
com.316apps.Fritch.viewDirectory
2017-01-19 22:44:23.305906 Fritch[3956:925348] -[UILayoutContainerView pushViewController:animated:]: unrecognized selector sent to instance 0x101837530
2017-01-19 22:44:23.306768 Fritch[3956:925348] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UILayoutContainerView pushViewController:animated:]: unrecognized selector sent to instance
UINavigationController *nav = (UINavigationController *) self.theMainView.view;
The reason of crashing is you are getting the view, not ViewController. So self.theMainView.view cannot convert to UINavigationController. If your self.theMainView is correct, fix that crash by using:
UINavigationController *nav = (UINavigationController *) self.theMainView;

'NSInvalidArgumentException' on UILocalNotifcation Load

When loading my application from a local notification I am trying to read its payload. To do so I have the following code:
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Loading Stuff
UILocalNotification *localNotif =
[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
[(UITabBarController *)self.window.rootViewController setSelectedIndex:1];
UINavigationController *nav = [[(UITabBarController *)self.window.rootViewController viewControllers] objectAtIndex:1];
IMTRewardsViewController *rvc = [storyboard instantiateViewControllerWithIdentifier:#"rewardsView"];
[rvc loadPushNotification:localNotif];
[nav pushViewController:rvc animated:NO];
}
return YES;
}
IMTRewardsController.h:
-(NSDictionary *)loadPushNotification:(UILocalNotification *)notification;
IMTRewardsController.m:
- (NSDictionary *)loadPushNotification:(UILocalNotification *)notification
{
NSLog(#"%#",notification.userInfo);
return notification.userInfo;
}
When I load my application from a local notification I receive the following error:
<Error>: -[UIViewController loadPushNotification]: unrecognized selector sent to instance 0x14e70b30
<Error>: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController loadPushNotification]: unrecognized selector sent to instance 0x14e70b30'
Any idea as to how to fix this issue and keep it from cropping up in the future?
There error indicates the view controller you've pulled back is only a UIViewController, and not a IMTRewardsViewController like you're expecting. Are you sure you set the custom class property to that type in the storyboard?
You might need to cast it first. The storyboard returns an UIViewController
IMTRewardsViewController *rvc = (IMTRewardsViewController *)[storyboard instantiateViewControllerWithIdentifier:#"rewardsView"];

Core data and Master-Detail template, getting runtime exception.

I am trying to modify Master Detail project template generated by xcode.
But getting following problem:
2013-08-03 20:08:59.749 StudentsAtWork[20236:a0b] Unknown class cblMasterViewController in Interface Builder file.
2013-08-03 20:08:59.900 StudentsAtWork[20236:a0b] -[UITableViewController setManagedObjectContext:]: unrecognized selector sent to instance 0x8ec8120
2013-08-03 20:08:59.904 StudentsAtWork[20236:a0b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITableViewController setManagedObjectContext:]: unrecognized selector sent to instance 0x8ec8120'
*** First throw call stack:
(0x1a009b8 0x17818b6 0x1a9cc13 0x19f0cfb 0x19f08de 0x61ee 0x57bea9 0x57c6e9 0x57db5e 0x593a6c 0x593fd9 0x57f7d5 0x38ce906 0x38ce411 0x197c3e5 0x197c11b 0x19a6b30 0x19a610d 0x19a5f3b 0x57d2b1 0x57f4eb 0x6d7d 0x2060725)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
What I did basically, removed the generated master and detail view controller class and created my own MasterViewController class like following:
header file:
#import <UIKit/UIKit.h>
#interface cblMasterViewController : UITableViewController
#property (nonatomic,strong) NSManagedObjectContext* managedObjectContext;
#end
Implementation file:
#import "cblMasterViewController.h"
#interface cblMasterViewController ()
#end
#implementation cblMasterViewController
#synthesize managedObjectContext;
....
....
#end
and my app delegate code is as follows:
#import "cblAppDelegate.h"
#import "cblMasterViewController.h"
#implementation cblAppDelegate
#synthesize managedObjectContext = _managedObjectContext;
#synthesize managedObjectModel = _managedObjectModel;
#synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
splitViewController.delegate = (id)navigationController.topViewController;
UINavigationController *masterNavigationController = splitViewController.viewControllers[0];
cblMasterViewController *controller = (cblMasterViewController *)masterNavigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
} else {
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
cblMasterViewController *controller = (cblMasterViewController *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
//}
return YES;
}
Also I have deleted detail view from my storyboard.
I am new in using storyboard. So I am not sure what is going wrong here.
Can anyone give me some clue?
Thanks.

Universal Master-Detail Application with Core Data and tab controller for iphone storyboard gets unrecognized selector sent to instance error

I started a Master-Detail Application in X-Code. I chose the options to be universal, core data, and git repo. When the application comes up, I went into the iphone story board, added a tab view controller, moved the nav/table/detail views it starts with to be in the tab controller as the third tab (in reality I want it to be the fourth). I then chose the tab controller to be the initial view the program should start with when in iphone mode. It builds successfully but does not allow the program to finish loading. The error that comes out is recorded below:
2013-05-11 21:35:00.302 FearlessAndThorough[6318:907] -[UITabBarController topViewController]: unrecognized selector sent to instance 0x1c592020
2013-05-11 21:35:00.306 FearlessAndThorough[6318:907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITabBarController topViewController]: unrecognized selector sent to instance 0x1c592020'
*** First throw call stack:
(0x337f33e7 0x3b4ee963 0x337f6f31 0x337f564d 0x3374d208 0xc9e43 0x35662aa1 0x35662625 0x3565a833 0x35602d1f 0x356027ad 0x356021ef 0x3731a5f7 0x3731a227 0x337c83e7 0x337c838b 0x337c720f 0x3373a23d 0x3373a0c9 0x3565946d 0x356562b9 0xc9ab5 0x3b91bb20)
libc++abi.dylib: terminate called throwing an exception
(lldb)
I am hoping that someone has done this before and can give me a little insight as to the proper procedure or steps to take when setting up a tab view controller type app that will then convert into a master detail application for ipad.
Here is the current app delegate's didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
splitViewController.delegate = (id)navigationController.topViewController;
UINavigationController *masterNavigationController = splitViewController.viewControllers[0];
MasterViewController *controller = (MasterViewController *)masterNavigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
} else {
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
}
return YES;
}
Your problem is that you added a tab bar controller to the front of your iPhone storyboard, but in your "else" clause you say the root view controller of the window is a navigation controller -- it's not, the tab bar controller that you added is. If you put a log in as the second line in that else clause, you will see that navigationController is actually a tab bar controller, not a navigation controller. That else clause needs to look like this:
UITabBarController *tbc = (UITabBarController *)self.window.rootViewController;
UINavigationController *navigationController = tbc.viewControllers[3];
MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
I'm not sure about the "3" in tbc.viewControllers. I can't tell from your description which tab that navigation controller is in, so you might need to change that.
I think I got your problem.
Did you use a UITabbar object in the Xcode navigator :
Because to manage views with a TabbarController, the best way is to embed your view in a Navigation Controller, like below :
Then you got your first view embedded in a navigation controller :
You can now add a new viewController in the field and add it to the TabbarController by control-dragging from the TabbarController and select the Relationship item :
Then you got 2 views in a navigationController :
And nothing to do in the appDelegate.
Then do the last step for any other view you want embedded in the navigationController.
Hope this helps.
// Change your else part in appdelegate to this it may works.
else {
UITabBarController *tabBarController = (UITabBarController *) self.window.rootviewController;
// For third view in tabbar controller
UINavigationController *navigationController = [tabBarController viewControllers] objectAtIndex: 2];
navigationController = (UINavigationController *)self.window.rootViewController;
MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
}

Change initial View Controller of Master-Detail-Application

I created a new iPhone project on a Master-Detail-Application. As I need a login before, I added at the storyboard a new ViewController, checkmarked "is initial View Controller" and assigned the new created class LoginViewController to this ViewController.
Furthermore but not relevant (in my opinion), i created a segue and connected it from the ViewController to the NavigationController (of the Master-Detail-Template).
The AppDelegate.m was changed to launch the new controller at startup:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
/* // Old Master-Detail-View-Controller
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
*/
(LoginViewController *)self.window.rootViewController;
return YES;
}
This will end up in the error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: '-[UICollectionViewController loadView] loaded the "Qn5-Rj-iPA-view-IRE-eP
-ILZ" nib but didn't get a UICollectionView.'
I have as well tried this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
LoginViewController *loginViewController = [[LoginViewController alloc] init];
self.window.rootViewController = loginViewController; //Set the view controller
[self.window makeKeyAndVisible];
return YES;
}
Resulting in a similar error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: 'UICollectionView must be initialized with a non-nil layout parameter'
Where is my mistake?
What I do not get is, where the hell the UICollectionView in the error message comes from. I did never create one or add one??
My LoginViewController inherits by mistake form UICollectionViewController instead of UIViewController. I fixed that and it works.
This explained the strange errormessage which i did not understood in the first place. As always the truth is in the sourcecode. Rechecking helps.
You don't have to do anything to load view controllers in the AppDelegate. As long as your stroyboard is the one that is loaded in project settings, it should load automatically.

Resources