viewdidappear not getting called when canceling UIImagePicker - ios6

After I cancel the image picker, the viewWillAppear gets called but the viewDidAppear does not get called. And subsequent loading of that view by going up and back down the stack does not help it.
Only if I switch to another Tab and then switch back, do I get the viewdidappear calling.
I use this code to cancel the image picker (iOS 6)
-(void) imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[self dismissViewControllerAnimated:NO completion:^{
self.imgScrollView.hidden=NO;
}];
}

You are trying to dismiss the viewController which presented the imagePickerController, try using picker instead of self something like this:
-(void) imagePickerControllerDidCancel:(UIImagePickerController*)picker
{
[picker dismissViewControllerAnimated:NO completion:
^{
self.imgScrollView.hidden=NO;
}];
}

Related

Stopping reload timer for grid in ATK4

I'm testing ATK4 for some scenarios to decide, if I can go with it. One of these Scenarios is a status page for groups and members, which should reload automatically the grids, which contains dynamic group and member informations.
The grid reload I've implemented like described in this Thread Agile toolkit : how to automatically reload grid
Here's the code for the members page:
<?php
class page_members extends Page {
function init(){
parent::init();
$page = $this;
$page->api->stickyGET('group_id');
$grid = $page->add('Grid');
$model = $grid->setModel('Member');
if ($_GET['group_id'])
$model->addCondition('group_id', $_GET['group_id']);
$page->js(true)->univ()->setInterval(
$grid->js()->reload()->_enclose()
,10000);
}
}
If I call it from the Browser with the group_id parameter, it works like expected. But this page will called from a group page into a frameURL with the following code:
<?php
class page_groups extends Page {
function init(){
parent::init();
$page = $this;
$grid = $page->add('Grid');
$model = $grid->setModel('Group');
$grid->addColumn('button','members');
if($_GET['members']){
$grid->js()->univ()
->frameURL('Members' ,$page->api->url('../members',array('group_id'=>$_GET['members'])))
->execute();
}
$page->js(true)->univ()->setInterval(
$grid->js()->reload()->_enclose()
,10000);
}
}
If I click on button 'members' from group 1, the members page for group 1 open in a frame and refreshes every 10 seconds. That's okay. But if I close the frame and open a new frame by clicking on 'members' button from group 2, the grid cycling through group 1 and 2 while refreshing the grid.
I think, the problem is the timer, created by the setInterval() function, which has to be cleared by clearInterval(id) before the frame is closed. The setInterval() function has a return value, but I don't know, how I can handle it over to the clearInterval(id) function in the ATK4 Framework?
Description:
Problem exists because setInterval is added to global window object and because window object itself is not reloaded (using AJAX we only reload parts of DOM tree) setInterval method continues to be called even when you close modal dialog or reload "page" container.
In short it is written here: http://www.w3schools.com/jsref/met_win_setinterval.asp
The setInterval() method will continue calling the function until clearInterval() is called, or the window is closed.
So, possible workarounds in this case will be one of these:
use setTimeout instead of setInterval and reload widget with new setTimeout call every time
use clearInterval when you close modal dialog window to get rid of old globally registered intervals
A lot of useful information about setInterval can be found here: https://developer.mozilla.org/en/docs/Web/API/window.setInterval
Testcase:
class page_company extends Page
{
function init()
{
parent::init();
$page = $this;
$grid = $page->add('Grid');
$model = $grid->setModel('Company');
$grid->addColumn('button','company');
if ($_GET['company']) {
$grid->js()->univ()
->frameURL('Employees', $page->api->url('../employee', array(
'company_id'=>$_GET['company'])))
->execute();
}
}
}
class page_employee extends Page
{
function init()
{
parent::init();
$page = $this;
$page->api->stickyGET('company_id');
$grid = $page->add('Grid');
$model = $grid->setModel('Employee');
if ($id = $_GET['company_id']) {
$model->addCondition('company_id', $id);
}
// NOTE:Important is that you add setTimeout JS chain to grid not page!
// That's because you reload only grid and you need to receive
// this JS chain from server on each reload to keep it reloading.
// $page is not reloading, only $grid is!
$grid->js(true)->univ()->setTimeout(
$grid->js()->reload()->_enclose()
,5000);
}
}
This way everything works fine except situation when you close one modal dialog and open new one in less that 5 seconds (setTimeout time). Problem is the same - setTimeout also is added to global window object and as result it still get executed after these 5 seconds even if you close your modal dialog in the mean time.
Last Edit
With newest ATK commit in Github you can now initialize periodic reloads of any View with just 1 simple chain.
So instead of something like this (which don't work):
$grid->js(true)->univ()->setTimeout(
$grid->js()->reload()->_enclose()
,5000);
now you can simply call:
// reload grid every 5 seconds
$grid->js(true)->reload(null,null,null,5000);
NOTE: you should apply this to exactly that View object which you want to reload periodically.

Going back using a NavigationController crashes when accessing the same ViewController

Below is the hierarchy in question.
The "ViewController - MyConnection" in the top left is my main ViewController. I implement a NavigationController system. From the main VC a user can go to the "Choose Server VC" or the "Choose Test Type" VC using Push. Having done that a user can then press back and return to the main VC, no problem.
A user can also Push to the "Preferences" VC from the main VC. From the prefences VC a user can also go to the "Choose Server VC" or the "Choose Test Type" VC, again without issue.
However, when going back to the preferences VC AND THEN back to the Main VC the app crashes!
Using the debugger the viewWillAppear gets called in the Main VC but that's where if fails.
I'm sure it's something simple I'm missing. All the segues have unique names.
The debugger doesn't offer a great amount of detail about what is causing the crash. Any way to get more detail out of the debugger?
EDITS:
viewWillAppears in ViewController-MyConnection:
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView reloadData];
}
In Preferences VC:
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView reloadData];
}
There are no ViewWillAppear methods in the other two VCs

How do I determine when Dispatcher.BeginInvoke completes?

I have a Silverlight 5 application that uses ImageTools for Silverlight to save a Canvas to a PNG image. I understand that I need to work with the Canvas on the UI thread and have the following code, which works:
if (saveFileDialog.ShowDialog() == true)
{
var stream = saveFileDialog.OpenFile();
writeableBitmap.Dispatcher.BeginInvoke(delegate
{
ExtendedImage extendedImage = writeableBitmap.ToImage();
new PngEncoder().Encode(extendedImage, stream);
});
}
The problem is that if the Canvas is very large it can take a noticeable time for the code in the BeginInvoke to complete. Since this is running on the UI thread it freezes the browser window during its execution.
After the user selects the location of where to save the exported image, I'd like to popup some child window that tells the user, "Please wait...", then run the image saving code posted above, and afterwards hide the child window automatically, but I'm not having much luck accomplishing that.
For starters, the BeginInvoke code runs asynchronously, so how do I know when it has completed?
If you need to call ToImage() on the UI Thread thats fine, but it doesnt mean you have to encode the image too.
Something like this will ensure the UI stays responsive.
if (saveFileDialog.ShowDialog() == true)
{
using (var stream = saveFileDialog.OpenFile())
{
writeableBitmap.Dispatcher.BeginInvoke(delegate
{
ExtendedImage extendedImage = writeableBitmap.ToImage();
System.Threading.ThreadPool.QueueUserWorkItem(item =>
{
new PngEncoder().Encode(extendedImage, stream);
});
});
}
}

Qooxdoo on window ready

I was just trying to fire an event after the qooxdoo application is ready, so I started with the "Hello World" app and appended the recommendation at the very end of the main function:
main : function(){
// Hello World part...
qx.event.Registration.addListener(window, "ready", function() { alert("application ready"); });
}
but, it didn't appear to fire in chrome or firefox (I didn't test IE), so I dug some more and found this and it worked.
if (qx && qx.event && qx.event.Registration)
{
var manager = qx.event.Registration.getManager(window);
var handler = manager.findHandler(window, "ready");
if (handler.isApplicationReady()) {
alert("application ready");
}
}
Can anyone tell my why the recommended method does not work or am I putting it in the wrong place?
Thanks!
Did you get the "recommendation" from the "From jquery to qooxdoo" document?! (It always helps if you cite your sources).
I think you are mixing things here. First, "window ready" is not the same as "application ready". I think "window ready" (as shown in a linked manual page) is a low-level event of the global JS window object. If you are running a high-level qooxdoo application (as it appears) this event has long passed when you register for it in your main method. So the event handler is never run.
In your second code sample you are not listening for an event, but checking a status with isApplicationReady(). This status can return true long after the event that turned the app from non-ready to ready has passed.
override simply the finalize function in the member area of the Application
finalize : function()
{
// Call super class
this.base(arguments);
alert("Hello World");
}
More simple!!!
QX Core Widget "appear" event is equal the same as "onReady" event such in other JS Frameworks like YUI, JQuery or whatever....
http://www.qooxdoo.org/5.0.2/api/#qx.ui.core.Widget~appear!event
has the same effect.
best, Tamer

How do I repeatedly call a method when my iOS 4 app is in the background?

I am writing an app for iOS 4 that needs to play a sound (or vibrate) at regular (user-specified) intervals when in the background. I do not want to use local notifications because there is no need to have a clickable alert appear.
This code (from Apple's docs) gets triggered when my app switches to the background:
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
NSLog(#"I am now in the background");
// Here I need something like this:
[self performSelector:#selector(myMethod) withObject:nil afterDelay:5.0];
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
The [self performSelector: ...] line gets executed when the app is switched to the background, but the myMethod method is not called until the app is switched back to the foreground (not in 5 seconds, as set at the afterDelay: parameter). So, how can I cause the method to be called while the app is still in the background?
Nevermind! Scheduling local notifications can do what I need.
It is better to use local notifications along with UIApplication cancelAllLocalNotifications to clear out existing notifications which the user has not dismissed. Perfect! Plus, the user gets the added benefit if a popup message to let them know what the sound (or vibrate) was for.

Resources