How to refresh UIViewController programmatically? - iphone

I have a ViewController in which the user selects a card (a custom UIButton) out of a UIScrollView. I have intercepted the touch event selecting the card and identified it, and then removed it from the data source, but it still exists in the UISubView. How do I get rid of it? Refreshing the view should show it removed from the view. How do I do that?

you can do it in one of two places:
in your viewcontroller
directly in the view
you need to call the function setNeedsDisplay
if you do it from the viewController then [yourViewOutletVariable/viewParameter setNeedsDisplay];
if you write it in the view itself then [self setNeedsDisplay];
hope this helps

You can either let view controller observe your models or update your views manually.
I'm not very clear about your question, what is still remaining on your view?
For automatically update views when model changes, I suggest ReactiveCocoa.

Once you have a handle on your view:
UIView *v = ...;
[v removeFromSuperview];
You could also call the setNeedsDisplay method on your scroll view after calling removeFromSuperview.

If your point is to refresh "UIViewController", then:
[self viewDidLoad];

Related

Reload data for UIView\UIViewController?

When I am moving the buttons on the screen from a function, [self makeButtons], nothing happends unless I push a viewcontroller, then pop back. Is there a reload data function for ViewController, as it is for UITableViews? I am using NavigationController, and I am adding subviews to a UISrollView and moving other buttons on the screen. The method is called after fetching data with ASIFORMHTTPRequest.
EDIT: I am sorry I didn't specify more.
I have a method that is sending a [request startAsynchronous] (ASIFORMHTTPrequest).
I have a NSMutableArray containing all my buttons. When the request is done, a method called doneGettingRequest, which looks like this.
- (void) doneGettingRequest(ASIFORMHTTPRequest *) request {
[self removeButtons];
}
which is calling this method;
- (void) removeButtons {
NSLog(#"Removing buttons!");
for (UIButton *button in gameButtons) {
[button removeFromSuperview];
}
Everything works when I go to another view, then back again. The problem is it won't refresh if THAT view is being shown when the method is called (which will happend almost always). The gameButton is a NSMutableArray containing buttons that are currently being showed. When I am done removing them, I want to add some other buttons. The problem is, the buttons is not removed when the removeButtons is called. The message "Removing buttons!" however, is shown, so the method is being called.
Any suggestions?
Thanks
You can put your logic in your viewWillAppear.
This method is called before the receiver’s view is about to be added to a view hierarchy and before any animations are configured for showing the view.
You can override this method to perform custom tasks associated with displaying the view.
If you override this method, you must call super at some point in your implementation.
Have you tried
[view setNeedsDisplay];

presentModalViewController on parent viewcontroller

I have a viewcontroller, where I load subviews on. In those subviews I have a UIButton which will show a modalViewController. If I call the function on the main viewcontroller, I get the modal exactly in the middle as I want them to be, but if I call the exact same method in the view I've added as a subview the modal is presented somewhere on the right side of the screen. So now is my question: how can I present the modal on the super view instead? Or how do I put the modalview in center? Because the views I've added as subviews contains data which the modalpopup needs.
This is how I present the modal:
MapViewer *map = [[MapViewer alloc] init];
map.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:map animated:YES];
[map release];
Hope somebody can help me with this.
Thanks in advance!
Edit:
Maybe useful to be more clear:
AppDelegate.m
-> MainWindow.m
-> OtherViewController.m
So I add an x amount of OtherViewControllers as subviews to MainWindow. The OtherViewController contains the function mentioned above. But the map needs to be displayed as a modal on the MainWindow, and not on the OtherViewController so it gets nicely centered etc.
One thing you might do is set the target of the UIButton object to the main view controller using setTarget:action: method.
Ok I've managed to get it working using the notificationcenter so I can call a method on the MainWindow from other views. So if anyone is asking the same question, have a look at the notificationcenter :D

How to update or reset a UIView with a custom subview?

I have a UIView in a UIViewController to which I add a custom subview in the viewDidAppear method.
MyView *myView = [[MyView alloc] initWithLabelText:text];
[self.view addSubview:myView];
[myView release];
The text variable is a string used on a label in myView. This text changes every time you come back to the current view. But it seems that viewDidAppear does not reload the view - it rather loads a new view over the old one - so I have two labels over each other.
I tried to use viewWillAppear but it doesn't make any difference. I also tried to use [self.view setNeedsDisplay] - doesn't help. I also tried to make myView an instance variable, but it also didn't help.
What worked was to remove the view explicitly, when I declared it as an instance variable:
- (void)viewDidDisappear:(BOOL)animated
{
[_myView removeFromSuperview];
}
Although there is this workaround I would like to simply reset the view when getting back to it. Does anybody know how to do that? I would appreciate it ;)
Don't alloc and init the custom subview every time, only the first time viewDidAppear is called. Then retain it in a property for subsequent use.
The followings thing can ben considered.
viewDidLoad --> alloc and init your sub views
viewDidAppear --> update sub views
dealloc --> release sub views.

Refresh/reload view after syncing on the Internet

I'm writing iPhone application which periodically is syncing with the synchronization web service. Everything works ok, but unfortunately after synchronization user do not see any changes in the view if he visited it before.
I need to force to reload/refresh some of views. How could I do that with for example viewWillAppear method?
I've tried something like this in one of my view controllers:
-(void) viewWillAppear:(BOOL)animated
{
NSArray* sbw = [self.view subviews];
UIView* view;
for (view in sbw)
{
[view setNeedsDisplay];
}
[self.view setNeedsDisplay];
[super viewWillAppear];
}
But the subviews are not refreshing. Is there any method for forcing to reload/refresh view?
I know that viewWillAppear is executed when I move to this view but it's not refreshing - so how can I do that?
in tableviews you could use : [tableView reloadData]; to reload a tables content. If you just want to update the views content you could just change it. Lets say if you have a view class and a controller class MyUIView and MyUIViewController and MyUIView does contain an UILabel * myLabel you could change the label text inside the controller by:
[((MyUIView *)self.view).myLabel setText:#"This is a new text."];
so no need for forcing update.
You can write the method "viewWillAppear" in that you can write your code to be reloaded which may take the data from your data base.This method will be executed when ever the view starts to load.

How do I have a view controller run updating code when it is brought to the top of the stack of views?

I have a viewController (Planner) that loads two view controllers (InfoEditor and MonthlyPlan) when the application starts. MonthlyPlan is hidden behind InfoEditor (on load).
So my question is when I exchange InfoEditor for MonthlyPlan (MonthlyPlan gets brought to the top) how can I have data on the MonthlyPlan view be updated. An NSLog in viewDidLoad is being called when the application starts (which makes sense.) NSLogs in viewDidAppear and viewWillAppear aren't doing anything.
Any ideas?
Thanks!
-- Adding more details --
I'm creating the view hierarchy myself. A simple viewController that is just loading two other viewControllers. The two child viewControllers are loaded at the same time (on launch of application.) To exchange the two views I'm using this code:
[self.view exchangeSubviewAtIndex:1 withSubviewAtIndex:0];
The exchanging of the views is fine. The part that is missing is just some way of telling the subview, you're in front, update some properties.
There's a lack of details here. How are you "exchanging" the two views?
If you were using a UINavigationController as the container then viewWillAppear/viewDidAppear would be called whenever you push/pop a new viewController. These calls are made by the UINavigationController itself. If you ARE using a UINavigationController then make sure you have the prototypes correct for these functions.
- (void)viewWillAppear:(BOOL)animated
If you are trying to implement a view hierarchy yourself then you may need to make these calls yourself as part of activating/deactivating the views. From the SDK page of viewWillAppear;
If the view belonging to a view
controller is added to a view
hierarchy directly, the view
controller will not receive this
message. If you insert or add a view
to the view hierarchy, and it has a
view controller, you should send the
associated view controller this
message directly.
Update:
With the new details the problem is clear: This is a situation where you must send the disappear/appear messages yourself as suggested by the SDK. These functions are not called automagically when views are directly inserted/removed/changed, they are used by higher-level code (such as UINavigationController) that provides hierarchy support.
If you think about your example of using exchangeSubView then nothing is disappearing, one view just happens to cover the other wholly or partially depending on their regions and opacity.
I would suggest that if you wish to swap views then you really do remove/add as needed, and manually send the viewWillAppear / viewWillDisappear notifications to their controllers.
E.g.
// your top level view controller
-(void) switchActiveView:(UIViewController*)controller animated:(BOOL)animated
{
UIController* removedController = nil;
// tell the current controller it'll disappear and remove it
if (currentController)
{
[currentController viewWillDisapear:animated];
[currentController.view removeFromSuperView];
removedController = currentController;
}
// tell the new controller it'll appear and add its view
if (controller)
{
[controller viewWillAppear:animated];
[self.view addSubView:controller.view];
currentController = [controller retain];
}
// now tell them they did disappear/appear
[removedController viewDidDisappear: animated];
[currentController viewDidAppear: animated];
[removedController release];
}
I would just add an updataData method to each subview and call it at the same time you bring it to the front. You would need to add a variable to your root view controller to track the active subView:
[self.view exchangeSubviewAtIndex:1 withSubviewAtIndex:0];
if (subView1IsActive) [subView1Controller updateData];
else [subView2Controller updateData];