Reload data for UIView\UIViewController? - iphone

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];

Related

How to refresh UIViewController programmatically?

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];

Unable to remove view using removeFromSuperview method

I am not able remove view. I am adding view using addsubview method but when I use RemoveFromSuperView.
// Here I am adding view from login button
medicalViewObject=[[MedicalInfoViewController alloc] initWithNibName:#"MedicalInfoViewController" bundle:nil];
[self.view addSubview:medicalViewObject.view];
//here I am writing RemoveFromSuperView in another ViewController
-(void)BackToMainView
{
[self.view removeFromSuperview];
}
It is not working because you are sending removeFromSuperview to the wrong view object. This is what you need:
[medicalViewObject.view removeFromSuperview];
EDIT:
Your question suggests that you have a view (because you did not include the name of this view in your question, I will simply call it MainView) and then you add a subview called medicalViewObject to your MainView. You also have a method call "BackToMainView" which you want to perform the removeFromSuperview function. Your question suggests that some user action in your medicalViewObject (such as a button press) is supposed to call the "BackToMainView" method.
If this is all correct, then my answer above is correct. But based upon your comment, it sounds like you will also need to implement a delegate protocol in your medicalViewObject, and then have your "MainView" adopt the protocol.
In your declaration of the delegate in your medicalViewObject, you need to have a method call like this:
-(void)backButtonWasPressed;
and in the implementation of your MainView it should look something like this:
-(void)backButtonWasPressed
{
[medicalViewObject.view removeFromSuperview];
}
So now, whatever user action you are using in your medicalViewObject to go back to the main view (whether a button or some other object) it needs to call the following:
[delegate backButtonWasPressed];
Depending on your situation it may look a little different, but this a fairly common way to accomplish what you are trying to do. I hope this helps.
when you call [self.view removeFromSuperview]; you are telling whatever view controller you are in to remove its own view. You should be calling that line from within that exact same MedicalInfoViewController or telling medicalViewObject from the outside to remove its view like [medicalViewObject.view removeFromSuperview];

Problem showing some controls that are part of an UIView

In my app I have a custom UIView subclass (let's call it MyView) which contains three buttons and two labels. I add this view to a view controller which also has a table view (I add the instance of MyView at the bottom).
Because of the business logic rules, the labels and one button out of three are hidden in the beginning. So I do this in viewDidLoad:
self.myView.label1.hidden = YES;
self.myView.label2.hidden = YES;
self.myView.button1.hidden = YES;
which works fine. So these three are hidden and the remaining two buttons are visible.
Now this view controller is also a delegate for another class. At some point in time an event occurs in this other class which calls a notification method in my view controller.
In this notification method I have now to show the hidden controls. So I obviously tried the following:
self.myView.label1.hidden = NO;
self.myView.label2.hidden = NO;
self.myView.button1.hidden = NO;
but it doesn't work, they don't appear.
Any idea what I'm doing wrong? Do I need to somehow "repaint" self.myView after this so that the controls become visible? What am I missing here?
Many thanks in advance!
Edit
I have added some NSLogs after setting them visible and the logs show something like this:
label1.hidden = 0
label2.hidden = 0
button1.hidden = 0
So as per the logs, they should be visible.
Ok, so I solved the problem. I moved the code that sets the visibility of the controls in another method and I call this method like this:
[self performSelectorOnMainThread:#selector(updateControls) withObject:nil waitUntilDone:NO];
So what do you know, the notification method was called in another thread (I didn't know this, the library I am using is actually not mine and there's nothing in the docs about this fact).
Anyway, it's nice that it works now.
Thanks all!
Have you confirmed that your notification method is getting called? You shouldn't need to specifically refresh the view, but if you are sure that your method is called, then you can also try adding [self.myView setNeedsDisplay]; into your notification method.

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.

Problem with iPhone shakes: viewDidAppear isn't called when loading viewController

I'm trying to detect a shake on the iPhone device, so for what i've read I need to set my view controller as first responder on the viewDidAppear method. This method is supposed to be called automatically, but for some reason this method is never called. Only viewDidLoad is called.
this is my code (I put only the relevant parts):
BuildHouseViewController.h:
#interface BuildHouseViewController : UIViewController {
BuildHouseViewController.m:
- (void)viewDidLoad {
[super viewDidLoad];
[self.view becomeFirstResponder];}
-(void)viewDidAppear:(BOOL)animated{
[self becomeFirstResponder];
[super viewDidAppear:animated];}
-(BOOL)canBecomeFirstResponder {
return YES;}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{
NSLog(#"shake");
if ( event.subtype == UIEventSubtypeMotionShake )
{ }
if ( [super respondsToSelector:#selector(motionEnded:withEvent:)] )
[super motionEnded:motion withEvent:event];
}
I added breakpoints on the viewDidAppear method and it is never called. Shakes are never detected, I suppose it is because as this methods are never called, so the view controller can never become first responder. I don't understand why this is happening.
Any help will be appreciated.
Edit:
I call the view from another view using:
[self.view addSubview:nextScreen.view];
The view is displayed on screen
Thanks for the quick answers.
I've found something interesting. I tried loading the same view I'm having problems with in different ways and I'm getting different results
-As I said before if I call it from another view using:
[self.view addSubview:nextScreen.view];
viewDidLoad is never called and I cannot detect shakes.
-Now if I call it from the AppDelegate using:
[window addSubview:nextScreen.view];
viewDidLoad is called!! and I am able to detect shakes, however this solution is not possible, I should be able to call it from another view
-If I call it from another view using:
[self presentModalViewController:nextScreen animated:YES];
viewDidLoad is called!! However I don't want to use a modal view controller, but it appears to be the only solution to my problem, shakes are detected.
It is strange that the first method doesn't load the view correctly, is it a bug??
The [self becomeFirstResponder] and the like don't actually make that become the first responder. The method gets called when the view is going to become the first responder. So that's not doing what you think it is.
Secondly, the viewDidAppear will only be called when the view, well, did appear. Is it showing up on the screen? Where are you telling it to be displayed? You need to either add the view controller's view as a subview of another view, or pushed onto a navigation controller stack, or pushed as a modal view.
viewDidAppear:(BOOL)animated only gets called when the view is shown by UINavigationController or UITabBarController. If you add a view controller's view to a subview (such as a scrollview or what have you), it won't get called. You would think it would but you'd be wrong. Just got bit by this myself.
Further to #Genericrich's comments, you can manually call viewDidAppear after you put the subview in yourself.
[self.view addSubview:theViewController.view];
[theViewController viewDidAppear:FALSE];
This worked for me. Hope it helps someone else.