How to refresh a view when resuming from Multitasking? - iphone

I have an app which is targeted to iOS 4 and above.I have a custom view, which is having
1.Scroll view
2.Custom drawing inside scroll view.
Now when my app is resuming from background,I want to refresh/reload this scroll view.
setNeedsDisplay is not working here as it usually meant for loading custom drawings and here I want to reload my scroll view contents.
Thanks in advance.

If I understand your question correctly, setNeedsDisplay does not work for you in this case because you need to "reload" the data that the UIScrollView handles before doing the redraw.
If this is right, I would define a method in your controller that does the reloading part; then, I would call this method from applicationDidEnterForeground or applicationWillEnterForeground; the reload method will need to call setNeedsDisplay after reloading the data.
I am sorry if this answer seems very generic to you. If you explain more or post some code, I can try and be more specific.

Have you tried redraw inside viewDidAppear?
- (void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[yourScrollView setNeedsDisplay];
}

setNeedDisplay calls the drawRect which is repainting operation. If you want to refresh the content only simply create one method in viewController and notify this method using performSelectorOnMainThread if you created new thread whenever thread complete (or you receive Data).

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

ViewWillAppear on iPad

my question is that i use ios 4.1 and viewWillAppear is not call when i go via
[self.view addSubView:self.mySecondView.view];
then and in the first view i alloc second view on ViewDidLoad .. i just want to call ViewWillApear on Second View because want to do the task dynamic.
is their some thing alternative... because InitWithNibName method also fire when alloc and init occur.. i want to fire some method when i add to that view.
Thanks
The same issue is discussed before,Just go through below SO links.
iPhone viewWillAppear not firing
viewDidLoad gets called, viewWillAppear does not get called, view does not appear on screen
http://forums.macrumors.com/showthread.php?t=575530
here is the tutorial post
http://www.idev101.com/code/User_Interface/UINavigationController/viewWillAppear.html

How to "refresh" UIView

I have data being refreshed in a modalViewController and when that data gets refreshed, the parent controller needs to refresh its data as well. I tried doing a [tableView reloadData]; but it didn't work properly since the actual array values aren't being refreshed. Is there a way for me to reload a controller without the user seeing any animation?
Thanks for any help!
Are you refreshing the data off the main thread? If so, you need to call the reloadData method using the following method:
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
So for a tableView it would be something like:
[tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
The underlying view can get released while the modal view is showing, so you shouldn't try to modify it directly. Instead, you can use the viewWillAppear: method on the main view controller to make any necessary updates.
I'm not sure what you mean that "the actual array values aren't being refreshed". How the two view controllers exchange data depends a lot on what you are trying to accomplish. If the modal view is only used in one place, the main controller can access its properties directly. Or maybe you want a dedicated class to hold the state... Again, depends on the context.

UIScrollView notifications

I'm coding an app that works much like Apple's Weather.app: There's a UIPageControl at the bottom and a UIScrollView in the middle of the screen.
In my code, I implemented the - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView method to figure out when the user did move to a new page. If they move to a new page, I load the adjacent pages' data, as to make further page-switching faster. (In one of Apple's examples, the - (void)scrollViewDidScroll:(UIScrollView *)sender is used, but that causes my app to shortly hang when loading a new page, so it's not suitable.)
That code works very well.
I'm using scrollRectToVisible:: to programmatically scroll inside the scrollview when the user clicks the UIPageControl. The problem is that the scrollRectToVisible: doesn't post a notification to the UIScrollViewDelegate when it's done scrolling - so the code responsible for loading adjacent pages never get's called when using the UIPageControl.
Is there any way to make the UIScrollView notify its delegate when it gets called by the scrollRectToVisible: method? Or will I have to use threads in order to prevent my app from freezing?
Thanks!
-- Ry
How about -scrollViewDidEndScrollingAnimation:?
If it doesn't work, try to listen to the UITextSelectionDidScroll notification. (Of course, it's undocumented.)
Alternatively, an SDK-safe method is measure the time taken for the animation and send a delayed notification at the call site of -scrollRectToVisible:.
You could add this delegate method instead:
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
The scroll view calls this method at the end of its implementations of the UIScrollView and setContentOffset:animated: and scrollRectToVisible:animated: methods, but only if animations are requested.

How do I create a reusable Loading Screen?

How do I create a loading screen that can be reused at any given time. I'm aware of the Default.png but I need the flexibility to plug in a loading screen at any point during the application life cycle.
This is what I have thus far.
//inside a method that gets called by a UIButton
LoadingViewController* loadController = [[LoadingViewController alloc] initWithNibName:#"Loading" bundle:nil vertical:NO];
[self.view addSubview: loadController.view];
//some method call that takes a few seconds to execute
[self doSomething];
//This loads some other view, my final view
[self.view addSubview: someOtherView]
but it seems that the loading view is never displayed. Instead the previous view stays there until the "someOtherView" gets added. I put trace logs and the code does seem to get executed, I even replaced [self doSomething] with a sleep(2), but the intermediate loading view is never displayed.
If I remove [self.view addSubview:someOtherView]; then after a few seconds...(after doSomething finishes executing) the load view is displayed since there is no view that is pushed on top of it, however this is obviously not the functionality I want.
Can explain this behavior? Is there something about the rendering cycle that I am misunderstanding because it doesn't seem like the view (on the screen at least) is instantly updated, even though I call a [self.view addSubview: loadController.view];
Would I need to create a separate thread?
In general, for changes in the UI to be made visible to the user, control must return to the main runLoop. You are only returning to the runLoop after taking the loading view down and replacing it with the other view. One strategy for dealing with this is to move the code that does the loading onto another thread. NSOperation and NSOperationQueue can be used for this.
An even simpler approach is to use performSelectorInBackground:withObject to do the processing. Once processing is complete the UI can be updated again to show the data. It is important to remember that the UI updates must be carried out on the main thread. Use performSelectorOnMainThread:withObject:waitUntilDone: to accomplish this from the loading thread.
This sounds like a lot of complication but it is really as simple as breaking your single method up into three separate methods as follows:
Display the loading view and start the background process - this is the button action method.
Do the background loading - called from the button action function with performSelectorInBackground:withObject.
Remove the loading view and update the display with the data - called from the background thread with performSelectorOnMainThread:withObject:waitUntilDone.
I created a subclass of UIView where I initialized how my loading-view should work and look like. (My view appeared and slided in from the bottom with an nice animation).
I then added code that handled whether the loading-view should be visible or not in a subclass of UIViewController.
I then let all my viewcontrollers be an subclass of my new viewcontrollerclass which made it possible for me to do:
[self showloadingMessage:#"loading..."];
in all my viewcontrollers...