Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-16129] iOS: NavigationWindows do not respect zIndex

GitHub Issuen/a
TypeBug
PriorityHigh
StatusClosed
ResolutionWon't Fix
Resolution Date2014-01-09T21:38:00.000+0000
Affected Version/sRelease 3.2.0
Fix Version/s2014 Sprint 01, 2014 Sprint 01 API, Release 3.3.0
ComponentsiOS
Labels3.2.0, alloy, navigationwindow, zindex
ReporterShawn Berg
AssigneeVishal Duggal
Created2014-01-05T18:25:33.000+0000
Updated2017-03-22T17:30:30.000+0000

Description

NavigationWindows seem to appear on top of each other in the order in which they are opened. Setting the zIndex property on them in Alloy XML files, TSS files, or via JavaScript seems to have no effect at all. Regardless of what the zIndex is set to the NavigationWindow opened most recently is always on top of all other NavigationWindows and elements. Changing the zIndex programmatically has no effect either. I've attached a super simple Alloy example. When these 2 NavigationWindows open you *should* see the green NavigationWindow (top) taking up the majority of the screen, but instead you see the red NavigationWindow (bottom) taking up the majority of the screen.

Attachments

FileDateSize
index.js2014-01-05T18:25:33.000+0000112
index.xml2014-01-05T18:25:33.000+0000294
Recipe-List.png2014-01-06T02:37:57.000+0000227472
Recipe-List-with-Expanded-Nav-Bar.png2014-01-06T02:37:57.000+0000257339

Comments

  1. Shawn Berg 2014-01-05

    Appears that this issue can also be replicated in classic Titanium so it's likely not an alloy issue. See the update by sfeather on the gist: https://gist.github.com/ShawnCBerg/8271743
  2. Stephen Feather 2014-01-05

    Q&A for reference: http://developer.appcelerator.com/question/161187/navigationwindows-do-not-respect-zindex
  3. Shawn Berg 2014-01-06

    UI Mockup showing why I need NavigationWindows to respect zIndex values. You'll see the expandable/collapsable navigation bar at the bottom of the screen. This navigation bar is a window that has a high zIndex (9999). The views above (Recipe List, for example) are all NavigationGroups which I'm now converting to NavigationWindows with a low zIndex (1). When the nav bar is expanded (user taps More) I simply change the top property causing it to appear on top of the NavigationGroup/NavigationWindow above. If I can't get the NavigationWindow to respect it's low zIndex I'll never be able to implement this. I'm in the process of converting now to upgrade my app from Ti SDK 3.1.1 > 3.2.0 and iOS 7. This worked perfect with NavigationGroups, just doesn't with NavigationWindows.
  4. Stephen Feather 2014-01-06

    Example more closely replicating Shawn's need:

    index.xml

       <Alloy>
       	<Window id='mainWindow'/>
       	<Window id='tabGroup'>
       		<View id='tab1' class='tab' onClick='raiseNav1'>
       			<Label text='tab1' color='white'/>
       		</View>
       		<View id='tab2' class='tab' onClick='raiseNav2'>
       			<Label text='tab2' color='white'/>
       		</View>
       		<View id='tab3' class='tab' onClick='raiseNav3'>
       			<Label text='tab3' color='white'/>
       		</View>
       		<View id='tab4' class='tab' onClick='raiseNav4'>
       			<Label text='tab4' color='white'/>
       		</View>
       	</Window>
       	<NavigationWindow id='nav1' class='navWindow' backgroundColor='#262626'>
       		<Window/>
       	</NavigationWindow>
       	<NavigationWindow id='nav2' class='navWindow' backgroundColor='#00ff00'>
       		<Window/>
       	</NavigationWindow>
       	<NavigationWindow id='nav3' class='navWindow' backgroundColor='#0000ff'>
       		<Window/>
       	</NavigationWindow>
       	<NavigationWindow id='nav4' class='navWindow' backgroundColor='#ff0000'>
       		<Window/>
       	</NavigationWindow>
       </Alloy>
       

    index.tss

       '#mainWindow':{
       	backgroundColor: 'white', zIndex: 1, orientationModes: [Ti.UI.LANDSCAPE_LEFT]
       }
       
       '#tabGroup':{
       	height: 50, bottom: 0, backgroundColor: 'black', zIndex: 9999, layout: 'horizontal'
       }
       
       '.tab':{
       	width: '25%'
       }
       
       '.navWindow':{
       	zIndex: 0
       }
       

    index.js

       
       function raiseNav1(){
       	console.log('raising nav1')
       	$.nav1.zIndex = 10;
       	$.nav2.zIndex = 0;
       	$.nav3.zIndex = 0;
       	$.nav4.zIndex = 0;
       	console.log('nav1 zIndex: '+$.nav1.zIndex);
       	console.log('nav2 zIndex: '+$.nav2.zIndex);
       	console.log('nav3 zIndex: '+$.nav3.zIndex);
       	console.log('nav4 zIndex: '+$.nav4.zIndex);
       	console.log('tab bar zIndex: '+$.tabGroup.zIndex);
       }
       
       function raiseNav2(){
       	console.log('raising nav2')
       	$.nav1.zIndex = 0;
       	$.nav2.zIndex = 10;
       	$.nav3.zIndex = 0;
       	$.nav4.zIndex = 0;
       	console.log('nav1 zIndex: '+$.nav1.zIndex);
       	console.log('nav2 zIndex: '+$.nav2.zIndex);
       	console.log('nav3 zIndex: '+$.nav3.zIndex);
       	console.log('nav4 zIndex: '+$.nav4.zIndex);
       	console.log('tab bar zIndex: '+$.tabGroup.zIndex);
       }
       
       function raiseNav3(){
       	console.log('raising nav3')
       	$.nav1.zIndex = 0;
       	$.nav2.zIndex = 0;
       	$.nav3.zIndex = 10;
       	$.nav4.zIndex = 0;
       	console.log('nav1 zIndex: '+$.nav1.zIndex);
       	console.log('nav2 zIndex: '+$.nav2.zIndex);
       	console.log('nav3 zIndex: '+$.nav3.zIndex);
       	console.log('nav4 zIndex: '+$.nav4.zIndex);
       	console.log('tab bar zIndex: '+$.tabGroup.zIndex);
       }
       
       function raiseNav4(){
       	console.log('raising nav4')
       	$.nav1.zIndex = 0;
       	$.nav2.zIndex = 0;
       	$.nav3.zIndex = 0;
       	$.nav4.zIndex = 10;
       	console.log('nav1 zIndex: '+$.nav1.zIndex);
       	console.log('nav2 zIndex: '+$.nav2.zIndex);
       	console.log('nav3 zIndex: '+$.nav3.zIndex);
       	console.log('nav4 zIndex: '+$.nav4.zIndex);
       	console.log('tab bar zIndex: '+$.tabGroup.zIndex);
       }
       
       /** Test set 1
       * Expected Behavior: app should start with a white screen and black tab bar
       * Clicking the tabs should raise a NavWindow using its zIndex
       *
       * Actual Behavior: NavWindows are not raised
       *
       **/
       
       $.nav1.open();
       $.nav2.open();
       $.nav3.open();
       $.nav4.open();
       $.mainWindow.open();
       $.tabGroup.open();
       
       /** Test set 2
       * Expected Behavior: app should start with a white screen and black tab bar
       * Clicking the tabs should raise a NavWindow using its zIndex
       *
       * Actual Behavior: zIndex is ignored and black tab bar is hidden behind a red  
       * NavigationWindow having a lower zIndex
       *
       **/
       
       // $.mainWindow.open();
       // $.tabGroup.open();
       // $.nav1.open();
       // $.nav2.open();
       // $.nav3.open();
       // $.nav4.open();
       
       
       
       console.log('Initial values');
       console.log('nav1 zIndex: '+$.nav1.zIndex);
       console.log('nav2 zIndex: '+$.nav2.zIndex);
       console.log('nav3 zIndex: '+$.nav3.zIndex);
       console.log('nav4 zIndex: '+$.nav4.zIndex);
       console.log('mainWindow zIndex: '+$.mainWindow.zIndex);
       console.log('tab bar zIndex: '+$.tabGroup.zIndex);
       
       
       
  5. Ritu Agrawal 2014-01-06

    Moving this ticket to engineering as per Tony's suggestion. http://developer.appcelerator.com/question/161187/navigationwindows-do-not-respect-zindex
  6. Tony Lukasavage 2014-01-06

    [~ragrawal] the question link that you reference states explicitly that this is _not_ an Alloy-specific issue. Please move this ticket to the appropriate project, in this case TIMOB.
  7. Ritu Agrawal 2014-01-06

    [~tlukasavage] My apologies. Moving this to TIMOB.
  8. Shawn Berg 2014-01-08

    Is there any timetable for getting this resolved? I see it's marked as a high priority. We have commitments to some clients that I need to address and I don't want to back myself into a corner more than I already am.
  9. Ingo Muschenetz 2014-01-08

    We're reviewing this now. It would likely go into 3.2.1 or 3.2.2, depending on the ease of fix and risk associated, but we need to do a little investigation first.
  10. Vishal Duggal 2014-01-09

    zIndex is a property used to position the view relative to its siblings in the parents child stack. Since windows by definition are top level controllers, they have no siblings. This is a doc bug that will be addressed. What you are trying to accomplish can be done via Ti.UI.Tabgroup and Ti.UI.iOS.NavigationWindow but requires a few changes. 1. NavigationWindow must be able to hide the UINavigationController built into the tab. This can be done by modifying the viewWillAppear method of the TiUIiOSNavWindowProxy class to support the navBarHidden property
        -(void)viewWillAppear:(BOOL)animated
        {
            if (controller!=nil)
        	{
        		id navBarHidden = [self valueForUndefinedKey:@"navBarHidden"];
        		BOOL nbhidden = [TiUtils boolValue:navBarHidden def:NO];
        		[[controller navigationController] setNavigationBarHidden:nbhidden animated:NO];
        	}
            if ([self viewAttached]) {
                [navController viewWillAppear:animated];
            }
            [super viewWillAppear:animated];
        }
        
    2. You need to be able to hide the UITabBar of the UITabBarController. This is not currently possible for the initial window in a tab group. But can be faked by setting the height of the tab group to me more than that of the screen. 3. You need to replace the tab bar with your own control. This can either be done by adding the fake controls to the NavigationWindow, individual windows hosted by the NavigationWindow or the tab group itself(undocumented, so support might be dropped in future release). Then you switch tabs with the activeTab property of the tabGroup. That being said, here is some skeletal code that is set up for the iPhone idiom in portrait mode. You can start from here and modify to meet your needs.
        
        
        function genTab(index) {
            var win = Ti.UI.createWindow({title:'WINDOW '+index, backgroundColor:'white'});
        
            var navWin = Ti.UI.iOS.createNavigationWindow({navBarHidden:true, window:win});
        
            var label = Ti.UI.createLabel({text:'I AM WINDOW '+index, bottom:0});
        
            win.add(label);
        
            var tab = Ti.UI.createTab({window:navWin, title:'TAB '+index});
        
            return tab;
        }
        
        
        
        var tabGrp = Ti.UI.createTabGroup({top:0, bottom:-50});//50 is tabBar height in portrait
        var view = Ti.UI.createView({layout:'horizontal',height:Ti.UI.SIZE});
        
        tabGrp.add(view);
        
        var curSelected = 0;
        
        function clickhandler(e)
        {
            var newSelected = e.source.selectId;
            if (newSelected != curSelected) {
                curSelected = newSelected;
                Ti.API.info('CLICK '+curSelected);
                tabGrp.activeTab = curSelected;    
            }
        }
        
        var tabs = [];
        for(var i=0;i<10;i++) {
            tabs.push(genTab(i))
            var v = Ti.UI.createView({backgroundColor:'black',width:'25%',height:40,top:1});
            var l = Ti.UI.createLabel({color:'white',selectId:i, text:'TAB '+i})
            l.addEventListener('click',clickhandler);
            v.add(l);
            view.add(v);
        }
        
        tabGrp.tabs = tabs;
        
        tabGrp.open();
        
  11. Vishal Duggal 2014-01-09

    Workaround in comments above
  12. Stephen Feather 2014-01-09

    Vishal, excellent. Thank you. Shawn, if you need help rolling a custom sdk for your project (its not really that bad, and a lot of us use custom sdks for different client projects) just let me know. But for this use, simply editing the sdk source files should do it for you.
  13. Shawn Berg 2014-01-10

    Honestly, I'm a bit confused about this approach. Before I dig too deep, is this the easiest way to have a custom tab bar at the bottom of the screen that's collapsible/expandable? That's really all I need to accomplish and with the number of apps that have this it seems like it should be easier to do. I'm hoping you're thinking there's more to it than this, but this is really my only need. Thanks for looking into this so promptly! I'm still running 3.1.1 so it all works. Is there a reason this worked previously with NavigationGroups and Windows and not now with NavigationWindows and Windows? I can show you my code, but in 3.1.1 the Tabs themselves (at the bottom of the screen) are contained in a normal Window, and there are stacked NavigationGroups above that I show/hide depending on the selected tab. It seems odd that this would be possible in earlier versions of iOS/Titanium and then all of a sudden be taken away. Maybe I just don't fully understand? Thanks so much, guys! Looking forward to your response.
  14. Vishal Duggal 2014-01-13

    NavigationGroup was a ViewProxy so could be added to a regular window as a child and hence supported the zIndex property. NavigationWindow is a WindowProxy so has no siblings and the zIndex property is irrelevant in the Titanium platform. Regarding why the NavigationWindow is a WindowProxy and not a ViewProxy please have a look at this thread. http://developer.appcelerator.com/question/157332/migrate-from-navigationgroup-to-navigationwindow---cant-add-object-to-a-window-anymore
  15. Lee Morris 2017-03-22

    Closing ticket as the issue will not fix and with reference to the above comments.

JSON Source