I have two class, PresentViewController and ModalViewController, In PresentViewController I call the ModalViewController in this format:
ModalViewController *targetController = [[ModalViewController alloc] init];
targetController.modalPresentationStyle = UIModalPresentationFormSheet;
targetController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:targetController animated:YES completion:nil];
// it is important to do this after presentModalViewController:animated:
targetController.view.superview.bounds = CGRectMake(0, 0, 400, 218);
In ModalViewController, I have a button who send a parameter to the class PresentViewController:
-(IBAction)apply{
PresentViewController *infoViewController = [[PresentViewController alloc] init];
[infoViewController setDiscount:[campoDesconto.text intValue]];
[self dismissViewControllerAnimated:YES completion:nil];
}
In PresentViewController the method setDiscount is as follows:
-(void)setDiscount:(int)value{
NSLog(#"Method is called!");
totalPrice.text = value;
}
This method is being called because I get a console message, but unfortunately this UILabel not updating your value, why this is happening and how can I solve?
When you call apply method, you haven't setup the view of infoViewController yet.
So you probably haven't created the totalPrice label yet, if you do NSLog(#"totalPrice: %#", totalPrice); in setDiscount:, it will probably output (null). You should save the discount value as a property, and set it in viewDidLoad as well as when setDiscount: method is called.
You're also setting an int to a NSString, this isn't correct.
PresentViewController.h
#interface PresentViewController : UIViewController
#property (nonatomic, assign) int discount;
#end
PresentViewController.m
#implementation PresentViewController
-(void)viewDidLoad
{
[super viewDidLoad];
// Setup detailLabel
detailLabel.text = [#(self.discount) stringValue];
}
-(void)setDiscount:(int)discount
{
_discount = discount;
detailLabel.text = [#(_discount) stringValue];
}
#end
That's because totalPrice is not probably instantiated before setDiscount: is called. Call setDiscount: after your view is loaded and totalPrice is instantiated to have the label text updated.
Related
Today I use MVC to build a photo album.But I can't get data in ViewControllerB that pass from ViewControllerA,I read this article here is link (Passing Data between View Controllers), and check all the steps I do.
Here is code in ViewControllerA:
PhotoViewController *photoVC = [[PhotoViewController alloc] initWithNibName:nil bundle:nil];
photoVC.images = images;
photoVC.index = index;
photoVC.view.backgroundColor = [UIColor lightGrayColor];
[self presentViewController:photoVC animated:YES completion:^{
// code
}];
Here is code in ViewControllerB:
#interface PhotoViewController : UIViewController
#property (nonatomic ,retain) NSMutableArray *images;
#property (nonatomic, assign) NSInteger index;
#end
here is .m file
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"%#", self.images);
}
But I got nothing, I don't know where I was wrong, how to make it right?? Thanks a lot.
I don't think you can instantiate your PhotoViewController from:
PhotoViewController *photoVC = [[PhotoViewController alloc] initWithNibName:nil bundle:nil];
Do this instead:
PhotoViewController *photoVC = [[PhotoViewController alloc] init];
Or you should pass the identifier to nibName, otherwise how can it find out which Nib file to load?
EDIT:
You should put this code section inside the animation completion block. UIViewController is not full instantiated when you pass data like you did.
[self presentViewController:photoVC animated:YES completion:^{
photoVC.images = images;
photoVC.index = index;
photoVC.view.backgroundColor = [UIColor lightGrayColor];
}];
EDIT 2:
Reason:
The nib file you specify is not loaded right away. It is loaded the
first time the view controller's view is accessed. If you want to
perform additional initialization after the nib file is loaded,
override the viewDidLoad method and perform your tasks there.
Storyboard equal between two controller and controller runing.
PhotoViewController *photoVC = [[PhotoViewController alloc] initWithNibName:nil bundle:nil];
photoVC.images = images;
photoVC.index = index;
photoVC.view.backgroundColor = [UIColor lightGrayColor];
[self presentViewController:photoVC animated:YES completion:^{
// code
}];
I have gone through most of the previous related posts, but although I have followed them correctly (as far as i understood), I simply am not able to trigger the delegate method for below code.
Objective: ModalView generates a string *SQL_String. Press DONE to dismiss the ModalView and trigger the delegate method in the parentview to get that *SQL_String.
SearchModalViewController.h
#protocol SearchControllerDelegate
- (void)didDismissModalView:(NSString *)SQL_String;
#end
#interface SearchModalViewController : UIViewController
#property (nonatomic, assign) id <SearchControllerDelegate> searchDelegate;
- (IBAction)handleDone:(id)sender;
SearchModalViewController.m
#interface SearchModalViewController ()
#end
#implementation SearchModalViewController
#synthesize searchDelegate;
- (IBAction)handleDone:(id)sender {
[self dismissView:sender];
}
- (void)dismissView:(id)sender {
[searchDelegate didDismissModalView:#"Test"];
[self dismissViewControllerAnimated:YES completion:nil];
}
DetailViewController.m (My parent View Controller)
#interface DetailViewController () <SearchControllerDelegate>
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
SearchModalViewController *searchModal = [[SearchModalViewController alloc] init];
searchModal.searchDelegate = self;
}
PROBLEM:
Below delegate method is not getting triggered.
- (void)didDismissModalView:(NSString *)SQL_String {
[self dismissViewControllerAnimated:YES completion:nil];
NSLog(#"The string = %#", SQL_String);
}
Any idea where I am doing wrong?
EDIT: Thank you guys. With your fast suggestions, I am able to close it down by adding below code instead of my previous IB connection.
- (IBAction)showSearchModal:(id)sender {
SearchModalViewController *searchModal = [self.storyboard instantiateViewControllerWithIdentifier:#"search"];
searchModal.searchDelegate = self;
searchModal.modalPresentationStyle = UIModalPresentationFormSheet;
searchModal.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:searchModal animated:YES completion:nil];
}
Here it goes
Change DetailViewController.m
- (IBAction)pushToSearch:(id)sender{
SearchModalViewController *searchModal = [self.storyboard instantiateViewControllerWithIdentifier:#"search"];
searchModal.searchDelegate = self;
[self presentViewController:searchModal animated:YES completion:nil];
}
And it will work.
Firstly, make sure your dismissView: of the SearchModalViewController is getting triggered.
Secondly, make sure your searchDelegate in the dismissView: method is not nil.
You need to set the delegate when you present the SearchModalViewController. The reason why your code doesn't currently work, is because the modal view controller's delegate is nil.
Update:
You set the delegate in prepareForSegue:sender:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)__unused sender
{
if ([[segue identifier] isEqualToString:#"modalSearch"])
{
SearchModalViewController *controller = (SearchModalViewController *)[segue destinationViewController];
controller.delegate = self;
}
}
line presentViewController crash app
#interface VVPassbook : NSObject
#property (nonatomic, retain) id delegate;
-(void)gotPassbookFromUrl:(NSURL *)passbookUrl;
#end
#import "VVPassbook.h"
#implementation VVPassbook
-(void)gotPassbookFromUrl:(NSURL *)passbookUrl
{
//present view controller to add the pass to the library
PKAddPassesViewController *vc = [[PKAddPassesViewController alloc] initWithPass:pass];
[vc setDelegate:(id)self.delegate];
[self.delegate presentViewController:vc animated:YES completion:nil];
}
#end
im call this method in AppDelegate.m in method
- (void)application:(UIApplication*)application didReceiveRemoteNotification:
(NSDictionary*)userInfo
{
VVPassbook *pass = [[VVPassbook alloc] init];
pass.delegate = self.window.rootViewController;
[pass gotPassbookFromUrl:MYURL ];
}
all times error
reason: 'Application tried to present a nil modal view controller on target <VVRightManuViewController: 0x15dd28460>.'
you should present a viewController from a UIViewController, i.e., self
(if self is a viewcontroller).
Note that you will get a "Attempt to present on whose view is not in the window hierarchy"-warning when self (this viewcontroller) is detached from the Main Window.
Solution: always use addChildViewController: to child viewcontrollers.
Why are you using self.delegate to push the view Controller,
simple write
[self presentViewController:vc animated:YES completion:nil];
in the place of
[self.delegate presentViewController:vc animated:YES completion:nil];
Really simple question i think.
i have a main view and a popover view.
i am trying to make a custom delegate which will enable me to close the popover view at certain times. My code is posted below. The real simple issue i am having is my code dosnt appear to be entering the delegate code. Any ideas as to why? It builds and runs but nothing appears to happen, i have put NSLog statments, the popover nslog appears but the function in
mainview dismissPopover does nothing.
Mainview.h
#interface MainScreen : UIViewController<DismissPopoverDelegate>
Mainview.m
- (void) dismissPopover:(NSNumber *)dataa
{ /* Dismiss you popover here and process data */
[popoverController dismissPopoverAnimated:YES];
NSLog(#"OLOLO");
}
Popover.h
#protocol DismissPopoverDelegate
- (void) dismissPopover:(NSNumber *)yourDataToTransfer;
#end
#interface SelectAgePopOver : UIViewController<UITableViewDataSource,
UITableViewDelegate,UIPopoverControllerDelegate>{
NSArray *items;
id<DismissPopoverDelegate> delegate;
}
#property (nonatomic, assign) id<DismissPopoverDelegate> delegate;
Popover.m
[self.delegate dismissPopover:selrow];
where i want the delegate called.
Thanks
the popover view is called by the following method in main view.m
controller = [[SelectAgePopOver alloc] initWithNibName:#"SelectAgePopOver" bundle:nil];
popoverController = [[UIPopoverController alloc] initWithContentViewController:controller];
[popoverController setDelegate:self];
popoverController.popoverContentSize = CGSizeMake(250, 294);
if ([popoverController isPopoverVisible]) {
[popoverController dismissPopoverAnimated:YES];
} else {
CGRect popRect = CGRectMake((self.AgeRangeTextField.frame.origin.x+50),
(self.AgeRangeTextField.frame.origin.y+50),
(self.AgeRangeTextField.frame.size.width),
(self.AgeRangeTextField.frame.size.height));
[popoverController presentPopoverFromRect:popRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
On where you instantiate the instance of the SelectAgePopOver, you need to set the delegate of the SelectAgePopOver instance to the MainScreen (self) in the Mainview.m, for example:
controller = [[SelectAgePopOver alloc] initWithNibName:#"SelectAgePopOver" bundle:nil];
;
controller.delegate = self;
Please try to set the controller delegate as shown above.
In the SelectAgePopOver.h class file, you do not need to set UIPopOverControllerDelegate though.
I have two views setup ( inside a TabBar). The DetailView with a button that calls a PopOver with a NavigationController+UITableView (RootView) loading data from CoreData. I have a problem passing data from the UITableView to the DetailView. I have a protocol declared in RootView and used in the DetailView.
Here is the code I use to create the PopOver from the button because I think I have some delegate issues. Any help will be amazing,
- (IBAction)zoneListButtonController
{
if (self.controladorPopOver == nil) {
ipadrootviewController = [[iPadRootViewController alloc] initWithNibName:#"iPadRootView" bundle:[NSBundle mainBundle]];
UINavigationController *ipadnavController = [[UINavigationController alloc]
initWithRootViewController:ipadrootviewController];
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:ipadnavController];
self.controladorPopOver = popover;
popover.delegate = self;
self.title = #"Countries";
popover.popoverContentSize = CGSizeMake(320, 300);
[self.controladorPopOver presentPopoverFromRect:CGRectMake(112, 20, 86, 27) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
[ipadnavController release];
[controladorPopOver release];
}
}
An instance of the SubZone1iPadController doesn't exist when you create the popover in DetailView so you can't set its delegate property directly from the DetailView.
One option is to also add the delegate property to the iPadRootViewController which you can set in the zoneListButtonController method. Then, when ipadrootviewController creates the SubZone1iPadController, pass along the delegate.
So in both ipadrootviewController and SubZone1iPadController, add a delegate property:
#property (nonatomic,assign) id <SubZone1Tap> delegate;
Then, in the zoneListButtonController method, set the delegate property on iPadRootViewController:
ipadrootviewController = [[iPadRootViewController alloc] init...
ipadrootviewController.delegate = self;
Then, where ipadrootviewController creates SubZone1iPadController:
SubZone1iPadController *sz1 = [[SubZone1iPadController alloc] init...
sz1.delegate = self.delegate;
[self.navigationController pushViewController:...
[sz1 release];
Finally, in the DetailView, make sure the delegate method is implemented. For example:
-(void)SubZone1Tap:(NSString *)name
{
NSLog(#"SubZone1Tap, name = %#", name);
//dismiss the popover if that's what you need to do...
[controladorPopOver dismissPopoverAnimated:YES];
}