Create UIView on previous UIViewController from another UIViewController - ios

How can I create a UIView on my previous UIViewController after popping the current UIViewController.
On my previous UIViewController I have a function that can be accessed on other UIViewControllers:
-(void)setMovieCompare:(NSString *)_movieName {
NSLog(#"Movie Compare %#",_movieName);
UIView *vw2ndPlayer = [[UIView alloc] initWithFrame:CGRectMake(0, 44, 320, 166)];
[self.view addSubView:vw2ndPlayer];
}
Then on my current UIViewController I have:
VideoPlayerViewController *_VideoPlayerViewController = [[VideoPlayerViewController alloc] initWithNibName:nil bundle:nil];
[_VideoPlayerViewController setMovieCompare:mediaObject.name];
[self.navigationController popViewControllerAnimated:YES];
It is causing me a:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString appendString:]: nil argument'
*** First throw call stack:
(0x31a3e2a3 0x398a297f 0x31a3e1c5 0x31a0d773 0x72461 0x74077 0x33865595 0x7600b 0x7aa6d 0x3390828d 0x3398af81 0x3234c277 0x31a135df 0x31a13291 0x31a11f01 0x31984ebd 0x31984d49 0x3553b2eb 0x3389a301 0x6e89d 0x39cd9b20)
libc++abi.dylib: terminate called throwing an exception

That code crashes because it's trying to read the vc from a nibNamed:nil. Even if you got that working, it wouldn't work. The code isn't changing the VideoPlayerVC that pushed the current vc, it's just allocating a new one (trying to) and changing a view on that new one, which gets released right after that method finishes.
The way to see the presenting view controller in a navigation container is to access self.navigationController.viewControllers.
NSArray *vcs = self.navigationController.viewControllers;
VideoPlayerViewController *previousVC = vcs[MAX(0, vc.count-2)];
[previousVC setMovieCompare ...];
Reaching down the navigation array may not be the best thing, especially of other view controllers can present the current vc. An alternative design is the delegate pattern, where the VideoPlayerVC sets itself as the pushed vs's delegate before pushing.

Related

Issues with rootViewController and Home Screen Quick Actions

I have the below Objective-C code to launch my app with Home Screen Quick Actions:
- (void)applyShortcutItem:(UIApplicationShortcutItem *)shortcutItem
{
ViewController *rootViewController = (ViewController *)[self.window rootViewController];
NSLog(#"Here %# - %#", rootViewController, shortcutItem);
if([shortcutItem.type isEqualToString:#"LaunchMode0"])
{
[rootViewController setShortcutAction:LaunchMode0];
}
else if([shortcutItem.type isEqualToString:#"LaunchMode1"])
{
[rootViewController setShortcutAction:LaunchMode1];
}
}
However, I keep getting runtime errors (unrecognized selected sent to instance) when I try to launch with the quick actions. Notably, it's these two lines where the app seems to trip up:
[rootViewController setShortcutAction:LaunchMode0]; and [rootViewController setShortcutAction:LaunchMode1];
It doesn't seem to like the rootViewController. Technically, the initial View Controller is the Navigation Controller, however the app launches to my main view controller (the app only has two views, the main one, and an about page).
There is more code above that code in my project, but this is the part that's giving me the error-- but let me know if seeing the other code would help (I didn't want the post to be too code heavy).
Thanks so much!
EDIT: as requested, here is the complete NSLog.
2019-09-23 18:18:01.317271-0400 AppName[1719:200993] Here <UINavigationController: 0x108802200> - <UIApplicationShortcutItem: 0x282bd1500; type: Mode1Shortcut, title: Mode 1>
2019-09-23 18:18:01.321819-0400 AppName[1719:200993] -[UINavigationController setShortcutAction:]: unrecognized selector sent to instance 0x108802200
2019-09-23 18:18:01.323462-0400 AppName[1719:200993] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationController setShortcutAction:]: unrecognized selector sent to instance 0x108802200'
*** First throw call stack:
(0x2045aa98c 0x2037839f8 0x2044c71c8 0x231033220 0x2045b01d4 0x2045b1e6c 0x102c14af0 0x102c148ec 0x230ffdf90 0x2308cc468 0x2308cd150 0x2308cc224 0x2308d0f24 0x230c012b0 0x206f275d8 0x102fecc78 0x102ff0840 0x206f61040 0x206f60cdc 0x206f61294 0x20453c728 0x20453c6a8 0x20453bf90 0x204536ecc 0x2045367c0 0x20673779c 0x231007c38 0x102c076d0 0x203ffa8e0)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
The problem is this:
ViewController *rootViewController = (ViewController *)[self.window rootViewController];
But you have stated that the root view controller is a UINavigationController. You need to get your ViewController from the nav controller.
UINavigationController *rootViewController = (UINavigationController *)self.window.rootViewController;
ViewController *viewController = (ViewController *)rootViewController.topViewController;
Then update the rest of the code to work on viewController.

crash passing parameter from one viewcontroller to another

I'm trying to pass parameter from one view controller to another, but application crashes with exception.
My code is this:
SelectedItemViewController *nextView = [storyboard instantiateViewControllerWithIdentifier:#"SelectedItemViewID"];
nextView.m_selectedItemId = [NSNumber numberWithInt:777];
[self presentViewController:nextView animated:YES completion:NULL];
And I have the following in my stack:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationController setM_selectedItemId:]: unrecognized selector sent to instance 0x9c765d0'
In your storyboard, the view controller with identifier SelectedItemViewID is a navigation controller, not a SelectedItemViewController. So, before you set m_selectedItemId you should access the navigation controllers root view controller (which should be your SelectedItemViewController).
I found solution here: instantiateViewControllerWithIdentifier and pass data
What should be done in case if you want to pass parameter to view controller via navigation controller:
UINavigationController *navigationController = [storyboard instantiateViewControllerWithIdentifier:#"SelectedItemViewID"];
SelectedItemViewController *nextView = navigationController.viewControllers[0];
nextView.m_selectedItemId = [NSNumber numberWithInt:777];
[self presentViewController:navigationController animated:YES completion:NULL];
When you select the view controller in your storyboard, is the class set to SelectedItemViewController?
Obviously you seem to have a #property ... m_selectedItemId (or at least setter method setM_selectedItemId) on SelectedItemViewController, otherwise your code wouldn't even compile. But it seems that [storyboard instantiateViewControllerWithIdentifier:#"SelectedItemViewID"] doesn't really return the expected SelectedItemViewController. Hence I have the feeling that you forgot to set the correct class name to SelectedItemViewController in your storyboard.

Cannot get back to previous interface

This is my first interface using a button to call another xib interface
-(IBAction)poli
UIViewController *ll = [[UIViewController alloc] initWithNibName:#"ViewController" bundle:nil];
[self presentModalViewController:ll animated:YES];
and second interface calling the previous one ....
-(IBAction)popaa
UIViewController *ui = [[UIViewController alloc] initWithNibName:#"Ra" bundle:nil];
[self presentModalViewController:ui animated:YES];
but there occurs a problem that shows
terminating app due to uncaught exception 'NSUnknownKeyException', reason: [<UIViewController 0x7433230> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key pol
could someone explain the problem, i just want the first xib to show the second and second to show the first xib via a button.
Check if your xibs has any warning. Usually setValue:forUndefinedKey: is thrown when you have added some view in xib but the same is not added to your class code or the outlet is not defined properly. In this case you have added some view pol to your xib but the same is not present in your ll or ui class.
Also your dismiss method should be,
- (IBAction)popaa
[self dismissViewControllerAnimated:YES];
}

Creating a floating view on iPad

My iPad application has a SplitViewController, a MasterViewController and a DetailViewController. From the DetailViewController, I need to create a temporary view (managed with a PaletteViewController: UIViewController, and designed in a xib file) that the user can move on the screen to be able to see what content is backwards.
in DetailViewController.m:
#synthesize paletteViewController=_paletteViewController;
(...)
- (IBAction) loadPalette: (id) sender{
if (_paletteViewController == nil) {
self.paletteViewController = [[PaletteViewController alloc] init];
}
self.paletteViewController.delegate=self;
[self.paletteViewController setModalPresentationStyle:UIModalPresentationFormSheet];
[self presentModalViewController:self.paletteViewController animated:YES];
(...)
I get an error message: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller .
Any idea?
I think you are in your paletteViewController and you are presenting modally paletteViewController over plaetteViewController . how is it possible.you can present paletteViewController over detailview or something(some paarent view).

iOS - NavigationController thinks it's getting the same controller pushed twice

I'm a bit confused about the following code. If I comment out the second statement, it successfully shows the view:
MyAppDelegate *delegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
delegate.navController.viewControllers = [NSArray arrayWithObject:aViewController];
[delegate.navController pushViewController:aViewController animated:YES];
[aViewController release];
Otherwise, it crashes on the following:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Pushing the same view controller instance more than once is not supported
I add a different view controller in the app delegate, but not this one. What could be making it think it's the same one?
delegate.navController.viewControllers = [NSArray arrayWithObject:aViewController];
[delegate.navController pushViewController:aViewController animated:YES];
First line set's aViewController as navController's only controller. Second line pushes aViewController to navController again so yeah, no wonder you get it twice. Depending on what you want to do, ditch one of those two lines.
If you want to set aViewController as only controller on navController, keep first line.
If you want to push aViewController as a new controller on navController, keep second line.

Resources