My detailviewcontroller is called myDetailVC , with tableVC which is just a table on the side of myDetailVC.
in myDetailVC, I have a button that is supposed to show a popoverviewcontroller. However, it crashes when I press it.
in my .h file:
#property (strong, nonatomic) UIPopoverController *masterPopOverController;
and .m:
- (IBAction)goToPDF:(id)sender
{
viewPDFViewController *MPPWV =[[viewPDFViewController alloc] initWithNibName:nil bundle:nil];
self.masterPopOverController = [[UIPopoverController alloc] initWithContentViewController:MPPWV];
[self.masterPopOverController presentPopoverFromRect:[sender frame] inView:[sender superview] permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[self.masterPopOverController setPopoverContentSize:CGSizeMake(100, 100) animated:NO];
}
Everything is connected fine in my xib, since I tested it by making it push to a viewcontroller instead of a popover. Can someone help me with this?
First, it looks like you're loading it up with a view controller that doesn't have anything in it:
viewPDFViewController *MPPWV =[[viewPDFViewController alloc] initWithNibName:nil bundle:nil];
Try specifying a Nib name, if you have one. It's possible that you don't have a NIB for that view controller. If that's the case you probably have a designated initializer -init method that you should be calling on it. Do that instead of calling -initWithNibName:
Second, it doesn't look like you're retaining the view controller you're loading into the pop over. It's possible that they require strong references. Try retaining it via property (or an ivar):
#property (nonatomic, strong) viewPDFViewController * MMPPWV;
Then when you access it do so via self:
self.MPPWV = [[viewPDFViewController alloc] initWithNibName:nil bundle:nil];
Related
I am attempting to display a view controller from .xib that indicates to a user that an update to the app is available. For some reason, the following code seems to do nothing:
if ([serverObject[#"newServerBuilt"] isEqualToString:#"YES"]) {
//we want to display the text from the server to user
NSString * displayText=serverObject[#"displayText"];
ForceUpdate * forceUpdateViewController = [[ForceUpdate alloc] initWithNibName:#"ForceUpdate" bundle:nil];
forceUpdateViewController.textToShow=displayText;
[self presentViewController:forceUpdateViewController animated:NO completion:nil];
}
Does anyone know why? As you can see, I'm allowing myself to display an update view controller based upon a customizable message on the server.
Also, when I click on a textlabel in the .xib, it says the textlabel connects to the "File's ownder" but should it connect to "Forced Update"?
and the forced update.h looks like so:
#import <UIKit/UIKit.h>
#interface ForceUpdate : UIView
#property (nonatomic, strong) NSString * textToShow;
#end
I guess you would be doing it in AppDelegate.m file. if YES then you need to presentViewController from [[[UIApplication sharedApplication] keyWindow] rootViewController] insetead self.
[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:forceUpdateViewController animated:NO completion:nil];
i have three view controller with three different XIB, let's say ViewControllerA, ViewControllerB and ViewControllerC and every view controller has UIView variable named view in it's property. so it would be something like this :
#property (readwrite, retain) UIView *view;
first, scene ViewControllerA loaded, then after i touched a button scene of ViewControllerB appears. but i deliberately not removing UIView of ViewControllerA from super view.
Then after i touched a button the scene navigate to ViewControllerC. here, before navigate to ViewControllerC i want remove UIView both of ViewControllerA and ViewControllerB from super view
removing UIView of ViewControllerB is not a problem, i can do something like this in ViewControllerB method :
[self.view removeFromSuperview];
but how can i remove UIView of ViewControllerA?
thanks
If you want totally independent of each other view controllers, you could switch them in appDelegate.window.rootViewController. Only create variable appDelegate that points to UIApplication.
And handle the animations by yourself.
Example:
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
UIViewController *controller1 = [ViewControllerA alloc] initWithNibName:#"ViewControllerA" bundle:nil];
UIViewController *controller2 = [ViewControllerB alloc] initWithNibName:#"ViewControllerB" bundle:nil];
appDelegate.window.rootViewController = controller1;
appDelegate.window.rootViewController = controller2;
I have a button that open another viewController(familyView) when clicked.
In familyView there is another button which suppose to bring me back to the mainViewController(ViewController.xib) but I don't know how to call the main viewController.
My method to call familyView
UIViewController* familyView = [[UIViewController alloc] initWithNibName:#"familyView" bundle:[NSBundle mainBundle]];
[self.view addSubview:familyView.view];
I hope you could help on how to call the main ViewController ? do I have to use the same method to call it? like this I mean:
UIViewController* mainView = [[UIViewController alloc] initWithNibName:#"viewController" bundle:[NSBundle mainBundle]];
[self.view addSubview:mainView.view];
If yes, is there a better way to implement this? in my demo project, I'm trying to make 7 views full with data and a button to go back and forth.
EDIT:
If I use UIView would that be best for me instead of using different viewControllers with their implementations and interfaces files?
My project will have views, and each view has data on it parsed from a different html page.
There are two method that can be used.
UINavigationController
Delegates
From your question it seems that a UINavigationController is the best option but I will show you both.
UINavigationController
When you load your mainViewController from your app delegate your going to need to wrap it in a nav controller like so:
AppDelegate.h
#property (strong, nonatomic) UINavigationController *navController;
AppDelegate.m
#synthesize navController = _navController;
//in didFinishLaunchingWithOptions:
UIViewController *mainViewController = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
navController = [[UINavigationController alloc] initWithRootViewController:mainViewController];
self.window.rootViewController = nav1;
[self.window makeKeyAndVisible];
Now in your MainViewController you have the convince of UINavigationController.
When you want to push to a child from a parent you can simply do:
ChildViewController *child = [[ChildViewController alloc]...];
[self.navigationController pushViewController:child animated:YES];
If you in your ChildViewController and want to go back simply do:
[self.navigationController popViewControllerAnimated:YES];
This is the "Drill Down" technique.
(I know "Drill Down" has more meaning than simply that but it provides a good frame of reference.)
Delegate
Now the other method that you have is to setup delegates between the classes. So if your in childView and need to call your parent, you will have a channel to do so.
In your MainViewController.h setup it like so:
#import <UIKit/UIKit.h>
//This is our delegate
#protocol TalkToParentDelegate <NSObject>
//This is our delegate method
- (void)helloParent;
#end
#interface MainViewController : UIViewController <TalkToParentDelegate>
...
..
#end
In your MainViewController.m make sure add the delegate method.
- (void)helloParent {
NSLog(#"Hello child, let me do something here");
}
In your ChildViewController.h setup it like so:
#import <UIKit/UIKit.h>
//Add header of class where protocol was defined
#import "MainViewController.h"
#interface ChildViewController : UIViewController
//Create a property we can set to reference back to our parent
#property (strong, nonatomic) id <TalkToParentDelegate> delegate;
#end
Now, in your MainViewController.m , whenever you present your ChildViewController do this:
ChildViewController *child = [[ChildViewController alloc]...];
//Set the delegate reference to parent
child.delegate = self;
//present the view
Last but not least, no when you in your child you can call methods on your parent (MainViewController) like so:
[self.delegate helloParent];
So here are two methods that you can use.
I would like to note however, you can use these together. Say you had a UINavigationController but still needed a child to talk to its parent, you can setup a delegate so that's possible.
Hope this helps.
I know similiar questions have been asked before, but please bear with me as I am totally new at Objective C (have good knowledge on C).
My case is that I have a tab bar controller with two windows. When I press a button in "second" I change a variable changeName. I want to use the value of changeName in my "first" view controller but stumbled on to some problems:
To reach the other viewcontroller I found this from SO (unfortunately I forgot where):
-(NSString *)newName{
// Create a UIStoryboard object of "MainStoryBoard_iPhone" named storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:(NSString *)#"MainStoryBoard_iPhone" bundle:(NSBundle *)nil];
// Create a UIViewController object of the wanted element from MainStoryBoard_iPhone
UIViewController *secondview = [storyboard instantiateViewControllerWithIdentifier:(NSString *)#"secondBoard"];
return secondview.changeName;
}
Which I have in my first.m. MainStoryBoard_iPhone is the name of the .xib/storyboard-file.
but no. Error says
Property 'changeName' not found on object of type 'UIViewController *'
In my second.h I have
#property (readwrite, retain) NSString *changeName;
and in second.m
#synthesize changeName;
All help is appreciated, but please keep in mind that I have only used OOP for two days.
Thank you all in advance
EDIT: And what input should I have here?
- (void)viewDidLoad
{
[super viewDidLoad];
mylabel.text = Name; // or [mylabel.text Name] or something?
}
You need to cast the view controller returned to your customized second view controller (as UIViewController does not have the property changeName).
So do the following :
// Create a UIViewController object of the wanted element from MainStoryBoard_iPhone
SecondViewController *secondview = (SecondViewController *)[storyboard instantiateViewControllerWithIdentifier:(NSString *)#"secondBoard"];
I assume SecondViewController is the name of your second controller.
In my case I wanted to pass a string from FirstViewController to set a text field in SecondViewController, so:
1- In SecondViewController.h
#property (strong, nonatomic) IBOutlet UITextField *someTextField;// this is linked to a UITextField
2- In FirstViewController.m:
#import "SecondViewController.h"
3- I will do this after a press of a button in the FirstViewController:
SecondViewController *SecondView = [[SecondViewController alloc]
initWithNibName:#"SecondViewController" bundle:nil];
//set fields values
SecondView.someTextField.text = #"HeLLO from First";
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController: SecondView];
//show AdView
[self.navigationController presentViewController:nav animated:YES completion:nil];
4- This is it!
5- There is a case, if I'm in FirstViewController and wanted to set a string property in the SecondViewController with the same way, the string won't get the value till you press a some kinda button in SecondViewController, it won't get it like in viewDidLoad for example! don't know why.
I'm currently working on a view based app for the iPad that has 3 seperate views on the main page. A custom menu up the top, a status list on the side, and a main view. The issue I am having with the main view is trying to add a navigation controller.
In AppPadViewController.h
#interface AppPadViewController.h : UIViewController {
MainViewController *MainView;
}
#property (nonatomic,retain) IBOutlet MainViewController *MainView;
And in AppPadViewController.m
#synthesize MainView;
- (void) viewDidLoad {
[super viewDidLoad];
MainView.navigationItem.title = #"Home";
UINavigationController *mainNavController = [[UINavigationController alloc] initWithNibName:#"MainView" bundle:[NSBundle mainBundle]];
self.MainView = [MainViewController alloc] initWithRootViewController:mainNavController];
}
And in the nib I have added the view where I would like it, and tied it in to the MainView, and then added the MainViewController and tied it to the File Owner and view.
When I run this, I get an 'Unrecognized Selector" error thrown on the initWithRootViewController line.
Can anyone see any problem with the code, or suggest a better way to add a navigation controller to a sub view?
You have your two view controllers reversed. Try something like this:
self.MainView = [[MainViewController alloc] initWithNibName:#"MainView" bundle:[NSBundle mainBundle]];
UINavigationController *mainNavController = [[UINavigationController alloc] initWithRootViewController:MainView];