I'm working sample app by storyboard.
When made popoverview, I used the way - 'Embed in navigation controller'.
But I'm getting a big trouble of delegate usage.
It's that don't delegate to popover view's.
[ViweController.m]
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:#"PopRootViewController"]){
NSLog(#"[segue destinationViewController] :%#", [segue destinationViewController]);
rootViewController = [[RootViewController alloc] init];
rootViewController.delegate = (id)self;
NSLog(#"%#---%#---%#", rootViewController.delegate, self, rootViewController);
}
}
-(void)didTap22 {
NSLog(#"delegate step 1 success!! ");
}
The result of this source like this :
[segue destinationViewController] :<UINavigationController: 0x88660a0>
<ViewController: 0x6b795e0>---<ViewController: 0x6b795e0>---<RootViewController: 0x6b7da60>
but [RootViewController] don't receive the delegation.
[RootViewController.m]
#implementation RootViewController
#synthesize items, delegate;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
....
self.items = mutableFetchResults;
NSLog(#"333333..... %#, ....... %#", self.delegate, self);
}
results :
333333..... (null), ....... <RootViewController: 0x8866520>
RootViewController's delegation is null.
I can't find solution about this.
Anybody help me, please!
I suspect you didn't declare your delegate UIPopoverControllerDelegate in the class declaration of your view controller.
This line is suspicious:
rootViewController.delegate = (id)self;
you don't need to cast self normally if you made the declaration I am mentioning.
Related
I have implemented protocol in my app,
I have declared protocol method in loginViewController and i am calling protocolMethod from confirmViewController
Here is my code snippet:
loginViewController.h
#protocol FirstControllerDelegate<NSObject>
#required
-(void)protocolMethod;
#end
#interface loginViewController : UIViewController<FirstControllerDelegate>
#end
loginViewController.m
- (IBAction)loginBtnClicked:(id)sender {
confirmViewController *obj = [confirmViewController new];
obj.delegate=self;
[self performSegueWithIdentifier:#"confirmloginsegue" sender:self];
}
-(void)protocolMethod{
NSLog(#"--- This is not callled ---");
[self dismissViewControllerAnimated:NO completion:nil];
}
Code for
confirmViewController.h
#interface confirmViewController : UIViewController
#property (nonatomic, assign) id <FirstControllerDelegate> delegate;
#end
confirmViewController.m
(IBAction)continueClicked:(id)sender {
[_delegate protocolMethod]; //Calling protocol method...
[self dismissViewControllerAnimated:YES completion:nil];
}
Where i am doing mistake?
Please help and thanks in advance!
Wrong Approach and delegate initialisation
In this lines:-
confirmViewController *obj = [confirmViewController new];
obj.delegate=self;
[self performSegueWithIdentifier:#"confirmloginsegue" sender:self];
--- You are loosing the object here
Solution
In your attribute inspector give the identifier for that confirmViewController, now push the vc and set the delegate for the object confirmViewController like this:-
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
ConfirmViewController *confirmViewController = [storyboard instantiateViewControllerWithIdentifier:#"ConfirmViewController"];
confirmViewController.delegate=self;
[self.navigationController pushViewController:confirmViewController animated:YES];
The delegating class does not exist for long enough to matter:
- (IBAction)loginBtnClicked:(id)sender {
confirmViewController *obj = [confirmViewController new];
obj.delegate=self;
[self performSegueWithIdentifier:#"confirmloginsegue" sender:self];
// obj is destroyed here
}
You need to implement prepareForSegue and set delegate there e.g.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
confirmViewController *destViewController = (confirmViewController *)segue.destinationViewController;
destViewController.delegate=self;
}
for further detail check this link:- http://www.appcoda.com/storyboards-ios-tutorial-pass-data-between-view-controller-with-segue/
You have to set delegate there. please,make some correction in your code like:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
confirmViewController *destViewController = (confirmViewController *)segue.destinationViewController;
destViewController.delegate=self;
}
You shoul use preparefrosegue to set your delegate object. so your code should be like this,
- (IBAction)loginBtnClicked:(id)sender {
[self performSegueWithIdentifier:#"confirmloginsegue" sender:self];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
confirmViewController *obj = [confirmViewController new];
//or
confirmViewController *obj = [segue destinationViewController];
obj.delegate=self;
}
hope this will help ;)
If u are using View controller
SettingsHubViewController *settingVC = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"yourStoryBoardIdentifier"];
settingVC.delegate = self;
If u are using XIB load the NIB after that set the settingVC.delegate = self;
its working for me (I created OverLay view and loaded in main class)
I have a main UIViewController and named AddInformationController. In this mainViewController I have two UIContainerView. Each of them embed with a UITableViewController. The table view controllers are named InformationSegmentController and ResultSegmentController.
I put this in AddInformationController:
InformationSegmentController *isc = [self.storyboard instantiateViewControllerWithIdentfier:#"InformationSegmentController"];
ResultSegmentController *rsc = [self.storyboard instantiateViewControllerWithIdentifier: #"ResultSegmentController"];
[self addChildViewController: isc];
[self addChildViewController: rsc];
In either the InformationSegmentController class or ResultSegmentController class, I tried to Log this:
NSLog(#"%#",self.parentViewController);
But unfortunately, it is a nil. How can I get the parentViewController correctly? Do I have to use the prepareForSegue?
// Question Update:
I found that I don't have to call addChildViewController method again if I create those childViewControllers directly in my storyboard.
I have tried to NSLog(#"%#", self.childViewControllers) in my AddInformationController and the result contains InformationSegmentController class and ResultSegmentController class.
But the problem is when I call NSLog(#"%#", self.parentViewController) on both childViewContorllers in viewDidLoad, the results is nil.
You have to try like this
//add childview
[self addChildViewController:aVC];
[self.view addSubview:aVC.view];
[aVC didMoveToParentViewController:self];
//remove
[self removeFromParentViewController];
[self didMoveToParentViewController:nil];
[self.view removeFromSuperview];
Hope it Helps you.
OR
another way to get PerentViewController in ChildViewControler is Make #property (strong, nonatomic) AddInformationController *ParentVC; in Your ChildViewController.h and assign viewController from your ParentViewController Like
InformationSegmentController *isc = [self.storyboard instantiateViewControllerWithIdentfier:#"InformationSegmentController"];
isc.ParentVC = self;
[self addChildViewController: isc];
Give identifiers to both the segues to your container views(suppose "InformationSegmentControllerSegue" and "ResultSegmentControllerSegue" ,namely) and use prepareForSegue in your AddInformationController like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"InformationSegmentControllerSegue"]) {
InformationSegmentController *container1 = segue.destinationViewController;
}
else if([[segue identifier] isEqualToString:#"ResultSegmentControllerSegue"]) {
ResultSegmentController *container2 = segue.destinationViewController;
}
}
Hope this helps you.
Ok this really makes me headache. I have ViewController (using replace) that I assign its delegate property
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"spoSelectionDemoPlanSegue"])
{
SPOSelectionViewController * vc = [segue destinationViewController];
vc.delegate = self;
NSLog(#"spo segue %#", vc.delegate); //returns current ViewController
}
}
SPOSelectionViewController.h
#property (nonatomic, assign) id<SPOInputDelegate> delegate;
SPOSelectionViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"delegate didload spo %#", delegate); //returns (null)
}
Somehow it prints null! However there is my other ViewController (using popover) that I try to assign its delegate and it does not null. Anyone can give me suggestion?
As I expected and this is silly, since the storyboard's segue is to a navigationController, so actually the destinationViewController is the navigationController not SPOSelectionViewController.
So I solved it by this way:
UINavigationController* navController = segue.destinationViewController;
SPOSelectionViewController * vc = (SPOSelectionViewController*)navController.topViewController;
vc.delegate = self;
I'm trying to pass data(_claimReportToDetailView) from viewDidLoad (of MasterVC) to DetailVC. It's always null.
#interface LAMasterViewController ()
{
NSArray *_claimReports;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_claimReports = [[LADataModelController getSingleton] getClaimReportsOrderedByAccessedDate];
LADetailViewController *detailViewController = [[LADetailViewController alloc] init];
detailViewController.claimReportToDetailView = (LAClaimReport *)_claimReports[0];
NSLog(#"claim%#",detailViewController.claimReportToDetailView); // captures here properly.
}
#interface LADetailViewController : UIViewController
#property(nonatomic ) LAClaimReport *claimReportToDetailView;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"sdfdf%#", _claimReportToDetailView); // logs null always.
}
Your viewDidLoad seems strange. You have this line:
LADetailViewController *detailViewController = [[LADetailViewController alloc]init];
Yet you say that the view controller is on the storyboard.
I think what is happening is that you are creating this VC, and setting it's property, but the Storyboard is loading a completely new VC, for which you haven't set the property.
Usually, the way you pass information to VCs on Storyboards is in the prepareForSegue: method.
You have to pass the data to the details view controller in prepareForSeque method in master view controller:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) { //<-make shire the segue identifier match one in storyboard
_claimReports = [[LADataModelController getSingleton] getClaimReportsOrderedByAccessedDate] ;
LADetailViewController *vc = (LADetailViewController*)[sender destinationViewController];
vc.claimReportToDetailView = (LAClaimReport *)_claimReports[0];
}
}
This should fix your project. Give it a try
//Allocating LADetailViewController instance
LADetailViewController *detailViewController = [[LADetailViewController alloc]init];
//Connecting it the specified VC on storyboard
detailViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"yourVCID"];
//Now the connection is set, so pass the data you need
detailViewController.claimReportToDetailView = (LAClaimReport *)_claimReports[0];
//Depending on present or push you should try one of the 2 lines
[self.navigationController pushViewController:detailViewController animated:YES];
//or
[self presentViewController:detailViewController animated:YES completion:nil];
This happens because whenever you navigate from one UIViewController to other, it is initialized again, so rather than setting value in viewDidLoad, try to set value on the event when you perform navigation and make navigation through code rather than with segue.
I have a ViewController that has a couple of buttons on it created in Interface Builder. The first button will display a popover linked up in IB, it is linked to a UINavigationController and has a TableView under it with a class of PopupViewController.
The second button, I have an action setup for goToCategory and when clicking on that, I want to set a property on the PopupViewController
ViewController.m
//go to category
-(IBAction)goToCategory:(id)sender{
NSLog(#"GO TO CAT");
//PopupViewController *popupVC = [self.storyboard instantiateViewControllerWithIdentifier:#"popoverVC"];
//popupVC.currentLevel = 1;
[self performSegueWithIdentifier:#"popoverSegue" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSLog(#"seg1");
if ([[segue identifier] isEqualToString:#"popoverSegue"]){
//PopupViewController *popupVC = (PopupViewController *)[[segue destinationViewController] visibleViewController];
//PopupViewController *popupVC = [segue destinationViewController];
PopupViewController *popupVC=[[[segue destinationViewController]viewControllers]objectAtIndex:0];
popupVC.test = #"just a test";
NSLog(#"seg2");
}
}
PopupViewController.h
#property (nonatomic, strong) NSString *test;
PopupViewController.m
#synthesize test;
-(void)viewDidLoad{
NSLog(#"test: %#", test); //returns test: (null)
}
I've found a lot of answers on SO, hence some of the commented out lines in my prepareForSegue. But none of these set the value of test. PopupViewController *popupVC = [segue destinationViewController]; throws an error due to it referring to the UINavigationController so I can't use that as it is, even though that seems to be the way to do it in a lot of answers I've seen. But no matter which way I try doing it, the output is always null?
UPDATE:
PopupViewController *popupVC = (PopupViewController *)[[segue destinationViewController] visibleViewController]; and PopupViewController *popupVC=[[[segue destinationViewController]viewControllers]objectAtIndex:0]; from my prepareForSegue above both work on the 6.1 simulator. My iPad's iOS is 5.1.1 which it isn't working on. Is there something different I need to do for iOS 5?
Try this
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"seg1");
if ([[segue identifier] isEqualToString:#"popoverSegue"])
{
UINavigationController *navController = (UINavigationController*)[segue destinationViewController];
PopupViewController *popupVC = [navController topViewController];
popupVC.test = #"just a test";
NSLog(#"seg2");
}
}