Problem
If you click a button to display a popover from a UI Tab Bar item, but navigate away from the tab's page before the popover has a chance to display, the app will crash with the following error:
"Popovers cannot be presented from a UIBarButtonItem that is not in a toolbar or navigation bar already."
Steps to Reproduce
Drop the following in an app.js. It will open a window in the tab group, close the window, try to display a popover, and then crash. No intervention is required by you.
var tab, win;
var tabs = Ti.UI.createTabGroup();
tabs.addTab(tab = Ti.UI.createTab({
window: win = Ti.UI.createWindow()
}));
tabs.open();
win.addEventListener('open', cycle);
function cycle() {
var action = Ti.UI.createButton({
title: 'Show Popover'
});
action.addEventListener('click', function(e) {
Ti.UI.iPad.createPopover({
width: 250, height: 100,
title: 'Test Popover Crash'
}).show({ view: action });
});
var child = Ti.UI.createWindow({
rightNavButton: action
});
child.addEventListener('close', function() {
setTimeout(cycle, 1000);
});
tab.open(child);
setTimeout(function() {
action.fireEvent('click');
}, 1000);
setTimeout(function() {
child.close();
child.rightNavButton = null;
}, 500);
}
Error
2011-09-22 08:34:30.394 play[6948:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Popovers cannot be presented from a UIBarButtonItem that is not in a toolbar or navigation bar already.'
*** Call stack at first throw:
(
0 CoreFoundation 0x024cbbe9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x026205c2 objc_exception_throw + 47
2 CoreFoundation 0x02484628 +[NSException raise:format:arguments:] + 136
3 CoreFoundation 0x0248459a +[NSException raise:format:] + 58
4 UIKit 0x00c467df -[UIPopoverController presentPopoverFromBarButtonItem:permittedArrowDirections:animated:] + 194
5 play 0x0018a7d7 -[TiUIiPadPopoverProxy updatePopoverNow] + 263
6 play 0x0018a600 -[TiUIiPadPopoverProxy show:] + 1824
7 Foundation 0x006829a6 __NSThreadPerformPerform + 251
8 CoreFoundation 0x024ad01f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
9 CoreFoundation 0x0240b28b __CFRunLoopDoSources0 + 571
10 CoreFoundation 0x0240a786 __CFRunLoopRun + 470
11 CoreFoundation 0x0240a240 CFRunLoopRunSpecific + 208
12 CoreFoundation 0x0240a161 CFRunLoopRunInMode + 97
13 GraphicsServices 0x0408b268 GSEventRunModal + 217
14 GraphicsServices 0x0408b32d GSEventRun + 115
15 UIKit 0x0091242e UIApplicationMain + 1160
16 play 0x0000396a main + 410
17 play 0x00002235 start + 53
18 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
[DEBUG] Session did end with error (null)
(from [1df642e2a3852b1d2035743be51cbfb64e1331cd]) [#3291 state:fixed-in-qa] Display a warning and short-circuit popover display when the presenting view isn't in the current window. https://github.com/appcelerator/titanium_mobile/commit/1df642e2a3852b1d2035743be51cbfb64e1331cd"> https://github.com/appcelerator/titanium_mobile/commit/1df642e2a385...
Tested with Titanium SDK version: 1.7.0 (03/08/11 09:53 1df642e) on
iPad 3.2
iPad 4.3
This still happens in some contexts.
Steps to reproduce: Add a popover to the rightNavButton -> Click to open -> click somewhere to close -> click to open, etc.. If you do it fast enough on device it will crash with the following stack trace: http://pastie.org/1704513">http://pastie.org/1704513
It is important to note that it only happens if you are really fast or an app is doing some background processing so the popover doesn't disappear right away. It's difficult to reproduce.
See Rick's comment above about why this is getting reopened.
I updated the example to not require any interaction to reproduce the crash.
Updated sample app.js to continuously open/close window, to make sure that the right nav button is always properly set even after being cleaned up.
Checked this against SDK in pull 486. On device, the sample code cycles and does not crash. Each cycle, the following appears in the log: Sep 22 09:56:25 unknown UIKitApplication:com.appcelerator.timob3291[0x60e8][3368]
Must be a timing issue. Doesn't crash for me on simulator, meaning there's still a race/scheduling issue in here somewhere. Probably going to have to throw in a lock.
Testing indicated that there's still a timing issue. Testing on device in a different app confirmed this. Reopening.
These two tickets are both about popovers crashing in tab groups. A fix for this may fix the other, although the exceptions are different.
Confirmed fixed by TIMOB-5337.
Verified fixed with iPad (4.3.5) and iPad 2 (4.3.5).
Standardizing summary and labels.