View controller unset his tag when pushed into nevigation controller - objective-c

... I guess.
This is the situation:
here a simple method, in a view controller, where we can push a botton to go in another view:
- (IBAction)actionNext:(UIButton *)sender {
self.numeriUtiliListaViewController = [[ALCNumeriUtiliListaViewController alloc] init];
[self.numeriUtiliListaViewController.view setTag:[sender tag]];
[self.delegate vai:self.numeriUtiliListaViewController title:#"Numeri Utili"];
}
the delegate's method is:
- (void)vai:(id)view title:(NSString *)title
{
ALCParentViewController *viewController = (ALCParentViewController *)view;
viewController.delegate = self;
NSLog(#"tag: %d",[viewController.view tag]);
[self.myNavigationController pushViewController:viewController animated:YES];
}
This system works well, but the only thing is the tag that i've logged in this last method, here it was print correctly, but in the view loaded by the navigation controller, when i try to catch the value in the viewDidLoad, it's 0.
Any ideas?
Thanks in advance
Update 1 2013-01-30:
if i try to print the the tag in the viewWilAppear method of the viewcontroller pushed in the navigationcontroller, i'll give the right value... why? i don't know

Whats happening here is that in your actionNext method, when you are setting the tag of the viewController's view using : self.numeriUtiliListaViewController.view, as soon as you access the view propert of the viewController, viewDidLoad method is called in the viewController. So even before the setTag function is executed, viewDidLoad has already been executed, and it is showing tag = 0. But your viewWillAppear/viewDidAppear methods will be called only when the actual view appears and by then setTag has been executed, so it shows correct value.
Makes sense? Hope this helps

Related

pop and refresh viewcontroller

I have three viewcontroller. when I get to the third viewcontroller, I use poptorootviewcontroller to pop to my first view controller, but when I use popviewcontroller in my third viewcontroller (i want to go back to my second viewcontroller) its poping but all the info that I edit in my second viewcontroller are there, and I want the secondviewcontroller to be new (reset this viewcontroller), like this viewcontroller to be reloaded.
here is my code in the third viewcontroller:
-(IBAction)playAgain:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
how can I do it?
thanks!
In the second viewcontroller, you should write a method viewWillAppear like below,
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//set initial values here
}
This method will call when your controller is about to appear. So while third viewcontroller will get popped, this method will get called and you can reset values.

Superview is Nil after Second Launch of View Controller

I've spent hours and I cant figure this out. I have a detail view controller (UITableView) which is launched here:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
EventLocationDetailController *newDetailViewController = [[EventLocationDetailController alloc] initWithNibName:#"EventLocationDetailController" bundle:nil];
self.eventDetailController = newDetailViewController;
[self.navigationController pushViewController:self.eventDetailController animated:YES];
[newDetailViewController release];
}
In the detail view controller there is a button method which calls the below method to display a slide-in-slide-out animation confirming the users choice:
-(void)confirmLastActionWithMessage:(NSString *)message {
ConfirmActionViewController *newConfirmActionViewController = [[ConfirmActionViewController alloc] initWithNibName:#"ConfirmActionViewController" bundle:nil];
self.confirmActionViewController = newConfirmActionViewController;
[newConfirmActionViewController release];
[[self.view superview] addSubview:self.confirmActionViewController.view];
}
Protocol method called by the ConfirmActionViewController indicating that the animation is finished.
-(void)didFinishConfirmDisplay:(UIView *)viewToRemoveFromSuperview {
[viewToRemoveFromSuperview removeFromSuperview];
}
This works perfect the first time I press the button. If I pop the detail controller and push it back on to the stack and press the button again, nothing happens and the detail controller's superview is nil every time I invoke the method after that. Superview is not nil in the viewWillAppear method for the detail view, only when It gets to the confirmLastActionWithMessage method. No other user interaction happens in between. How do I get the superview back? I have a similar code that works without animation.
I've also noticed that the detail view controller hasn't called dealloc when popped off the stack. Not sure where the problem is.
Thanks.
EDIT 1
OK. I replaced the addSubview line with this one:
[self.view insertSubview:self.confirmActionViewController.view atIndex:0];
and the animation view appeared underneath one of the table cells. Could one of the table cells steal the superview?
Well I don't really understand why you should add the subview to the superview. Why not add it just to self.view
I may not be able to explain why there is no superview but try either adding the controller view to self.view or
[[[[UIApplication sharedApplication] delegate] window] addSubview:yourview];
This will render the view on top of everything.

-(void)viewWillAppear:(BOOL)animated doesn't called

My application is view based in my app in one view i write view will appear but this method doesn't call. My code is
-(void)viewWillAppear:(BOOL)animated
{
NSLog(#"view will Appear");
[tableView reloadData];
}
Can anyone tell why viewWillAppear method not called.
Sorry I forgot To tell You That This method call first time but when i remove a subview from this view viewWillAppear not called. Please Suggest me how to solve this problem.
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(#"view will Appear");
[tableView reloadData];
}
if still it is not calling then try to call through code , as per example [classobj viewWillAppear:NO];
The viewWillAppear and other related methods are called to the viewcontroller that are linked with the rootViewController of the mainWindow.
So if you are using a view based application, the viewWillAppear method of the first view controller will work properly and others wont.
I think that the problem you are seeing is that viewWillAppear: is a method on a UIViewController, and not a method on UIView. viewWillAppear: is called on the view controller to indicate that the controller's view will become visible.
If you have added the code above to a class based on UIView, that code won't get called. You need to move that code to your view controller -or- you might achieve the result that you are looking for by implementing the didMoveToSuperview method in your UIView based class instead.
didMoveToSuperview will be called on your view when your view is added to another view using addSubview:.
Hi Here I did instead
[self.view addSubview:viewcontroller.view];
I Used this:
[self presentModalViewController:viewcontroller animated:YES];
and write this method now my problem is solved.
-(void)viewWillAppear:(BOOL)animated
{
NSLog(#"==========view will appear");
}

UISearchBar Not appearing

I have view controller, into the view i have put a table view, and a search bar into the table's header... the search bar is not showing up, just the empty table view.
Do i need to do something additional? I'm pretty sure its to do with the view outlet of the UIViewController, set to View...
Thanks
For anyone else who may be landing on this question, I had a very similar situation where a UITableViewController with a UISearchBar added to it wasn't displaying. If you find yourself in this situation, double check that you are actually calling:
initWithNibName:#"MyNibName" bundle:nil
to init your view controller instead of the common Table View init of:
initWithStyle:UITableViewStylePlain
I was foolishly adding the search bar to the Nib, and then loading it with the style init (which skips the Nib entirely and loads the table view from scratch)
try setting the tableHeaderView of your tableView to your searchBar.
self.tableView.tableHeaderView = searchBar;
if you are using IB, be sure to connect the outlets so that it gets referenced.
Try this,l it worked for me:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.tableView.tableHeaderView = _searchBar;
[_searchBar becomeFirstResponder];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[_searchBar resignFirstResponder];
self.tableView.tableHeaderView = _searchBar;
}
-(void) scrollViewDidScroll:(UIScrollView *)scrollView
{
searchBar.frame = CGRectMake(0,MAX(0,scrollView.contentOffset.y),320,44);
}
If you set your view controller as a part of tabbar controller, besides "Class" property in IB set the "NIB name" property. It takes me several hours to figure it out.
Fixed using a UISearchBar with controller.

UIViewController parentViewController access properties

I know this question has been asked several times and I did read existing posts on this topic but I still need help.
I have 2 UIViewControllers - parent and child. I display the child UIViewController using the presentModalViewController as below:
ChildController *child =
[[ChildController alloc] initWithNibName:#"ChildView" bundle:nil];
[self presentModalViewController:child animated:YES];
[child release];
The child view has a UIPickerView. When user selects an item from UIPickerView and clicks done, I have to dismiss the modal view and display the selected item on a UITextField in the parent view.
In child's button click delegate, I do the following:
ParentController *parent =
(ParentController *)[self.navigationController parentViewController];
[parent.myTextField setText:selectedText];
[self dismissModalViewControllerAnimated:YES];
Everything works without errors. But I don't know how to load the parent view so that it displays the updated UITextField.
I tried
[parent reloadInputViews];
doesn' work. Please help.
Delegation is the way to go. I know some people that may be looking for an easier solution but trust me I have tried others and nothing works better than delegation. So anyone having the same problem, go read up on delegation and follow it step by step.
In your subviewcontroller.h - declare a protocol and declare delegate mthods in it.
#protocol myDelegate
-(void)clickedButton:(subviewcontroller *)subController;
#end
In your subviewcontroller.h, within #interface:
id<myDelegate> delegate;
#property (nonatomic, assign) id<myDelegate> delegate;
NSString *data;
-(NSString *)getData;
In your subviewcontroller.m, synthesize myDelegate. Add the following code to where you want to notify your parentviewcontroller that the subview is done doing whatever it is supposed to do:
[delegate clickedButton:self];
and then handle getData to return whatever data you want to send to your parentviewcontroller
In your parentviewcontroller.h, import subviewcontroller.h and use it's delegate
#import "subviewcontroller.h"
#interface parentviewcontroller : VUIViewController <myDelegate>
{}
In your parentviewcontroller.m, implement the delegate method
- (void)clickedButton:(subviewcontroller *)subcontroller
{
NSString *myData = [subcontroller getData];
[self dimissModalViewControllerAnimated:YES];
[self reloadInputViews];
}
Don't forget memory management!
If a low-memory warning comes in during your modal view's display, the parent's view will be unloaded. Then parent.myTextField is no longer referring to the right text field until the view is reloaded. You can force a reload of the view just by calling parent.view;
However, a better idea might be to have the parent view have a String property that can be set by the child view. Then, when the parent view reappears, put that data into the text field, inside viewWillAppear: for example. You'd want to have the value set to some default value for when the parent view initially shows up too.
-(void) viewWillAppear:(BOOL) animated doesn't get called for me either, exactly when it's a modal view controller. No idea why. Not incorrectly overridden anywhere in this app, and the same problem occurs on the other 2 apps I'm working on. I really don't think it works.
I've used the delegate approach before, but I think that following approach is pretty good as well.
I work around this by adding a private category to UIViewController, like so:
.h file:
#interface UIViewController(Extras)
// returns true if this view was presented via presentModalViewController:animated:, false otherwise.
#property(readonly) BOOL isModal;
// Just like the regular dismissModalViewController, but actually calls viewWillAppear: on the parent, which hasn't been working for me, ever, for modal dialogs.
- (void)dismissModal: (BOOL) animated;
#end
and .m file:
#implementation UIView(Extras)
-(BOOL) isModal
{
return self == self.parentViewController.modalViewController;
}
- (void)dismissModal: (BOOL) animated
{
[self.parentViewController viewWillAppear: animated];
[self dismissModalViewControllerAnimated: animated];
}
#end
which I can now call like this when I want to dismiss the dialog box:
// If presented as a modal view, dismiss yourself.
if(self.isModal)
[self dismissModal: YES];
and now viewWillAppear is correctly called.
And yes, I'm donating a bonus 'isModal' property, so that the modal view can tell how it was being presented, and dismiss itself appropriately.