Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iOS]: frame.topmost().currentPage is not the same instance as the page being loaded in page.loaded event handler. #779

Closed
NathanaelA opened this issue Sep 19, 2015 · 18 comments
Labels
Milestone

Comments

@NathanaelA
Copy link
Contributor

During page.loaded event, frame.topmost() does not have the proper information for getViewById to work. In fact currentPage = null. However on Android this does work during the page.loaded event.

This also causes a Page.showModal(x) to fail during the page.loaded event.

@NathanaelA NathanaelA changed the title frame.topmost() issue on ios frame.topmost() & page hiarchy issue on ios. Sep 19, 2015
@N3ll
Copy link
Contributor

N3ll commented Oct 9, 2015

Hey, @NathanaelA , the recommended way to access the current page is by taking the object of the args parameter of page.loaded.

 exports.load = function(args){
    var currentPage = args.object;
};

@NathanaelA

This comment was marked as abuse.

@N3ll
Copy link
Contributor

N3ll commented Oct 9, 2015

@NathanaelA - that clarified the issue :)

We reproduced the problem with v1.3.0 and it is working fine.

main-page.xml

<Page loaded="pageLoaded" >
    <Label id="label" text="Text"/>
</Page>

main-page.js

var page;
var label;
exports.pageLoaded = function(args) {
    page = args.object;
    label = page.getViewById("label");
    console.log("id" + label);
}

Can you send us some code and tell which version you are using, so we can reproduce it exactly?

@NathanaelA

This comment was marked as abuse.

@NathanaelA

This comment was marked as abuse.

@N3ll
Copy link
Contributor

N3ll commented Oct 12, 2015

@NathanaelA - first, I would like to point out something in the getInfo(). The method topmost() returns a Frame, so it is a bit misleading to name your variable thePage. If you would like to get the page, you can access the instance property currentPage (https://docs.nativescript.org/ApiReference/ui/frame/Frame.html).

About the other problems - there is a difference how the pages are loaded in iOS and Android and that is why it crashes in iOS. What you can do is use the navigatedTo instead of loaded.

@NathanaelA

This comment was marked as abuse.

@N3ll
Copy link
Contributor

N3ll commented Oct 13, 2015

@NathanaelA - you are totally right! We will surely discuss it in the team and work towards improving it.

@N3ll N3ll added this to the 1.5 (Under Review) milestone Oct 13, 2015
@hamorphis
Copy link
Contributor

I will investigate this.

@hamorphis hamorphis self-assigned this Oct 20, 2015
@hamorphis hamorphis changed the title frame.topmost() & page hiarchy issue on ios. [iOS]: frame.topmost().currentPage is not the same instance as the page being loaded in page.loaded event handler. Oct 20, 2015
hamorphis added a commit that referenced this issue Oct 20, 2015
Fixed #779: frame.topmost().currentPage is not the same instance as t…
@hamorphis hamorphis reopened this Jan 28, 2016
@hamorphis
Copy link
Contributor

With the new page transitions that I am about to introduce, I will have to revert this change. On both platforms the page will first be loaded and then will become the current page, since there might be a transition involved. Even if there is not transition involved the order should remain the same.

@NathanaelA

This comment was marked as abuse.

@hamorphis
Copy link
Contributor

@NathanaelA Yes. It turns out that the natural order of things will be the following on both platforms:

  1. navigatingTo
  2. loaded
  3. the page becomes frame.currentPage
  4. navigatedTo

Also, in case you need to show modals in iOS, you should be doing it from the navigatedTo event handler from now on, since I am going to revert the ugly hack that I introduced several months ago in order to make the iOS order the same as the Android order. Since I will change the Android order once I push the Transitions Feature, the iOS order of things will no longer need to be hacked to align it with the Android version.

@NathanaelA

This comment was marked as abuse.

@hamorphis
Copy link
Contributor

After merging the Page Navigation Transitions(#1473) pull request into the master branch, the page lifecycle is now the following on both platforms.

navigatingTo event is raised
loaded event is raised
the page becomes frame.currentPage
navigatedTo event is raised

Also, in case you need to show modals in iOS, you should be doing it from the navigatedTo event.

@davecoffin
Copy link
Contributor

@hamorphis @N3ll My problem with this is there is no good way to get the top level Page on iOS. In my app, I have 4 different tabs, which are loaded into their own files like this:

<TabView selectedIndexChanged="onSelectedIndexChanged" selectedColor="#30A9FF">
    <TabView.items>
        <TabViewItem title="''" iconSource="{{ selectedIndex == 0 ? 'res://shiftsicon_selected' : 'res://shiftsicon' }}" xmlns:ShiftsView="views/nanny/home/shifts">
            <TabViewItem.view>
                <ShiftsView:shifts />
            </TabViewItem.view>
        </TabViewItem>
        <TabViewItem title="''" iconSource="{{ selectedIndex == 1 ? 'res://photosicon_selected' : 'res://photosicon' }}" xmlns:PhotosView="views/photothumbs">
            <TabViewItem.view>
                <PhotosView:photothumbs />
            </TabViewItem.view>
        </TabViewItem>
        <TabViewItem title="''" iconSource="{{ selectedIndex == 2 ? 'res://messagesicon_selected' : 'res://messagesicon' }}" xmlns:MessagesView="views/messages">
            <TabViewItem.view>
                <MessagesView:messages />
            </TabViewItem.view>
        </TabViewItem>
        <TabViewItem title="''" iconSource="{{ selectedIndex == 3 ? 'res://kidicon_selected' : 'res://kidicon' }}" xmlns:MyKidsView="views/nanny/home/mykids">
            <TabViewItem.view>
                
                <MyKidsView:mykids />
            </TabViewItem.view>
        </TabViewItem>
    </TabView.items>
</TabView>

Within the js files for each tab, I have no good way of performing some operation that requires the context of the parent page. For example, if I want to do showModal from within a tab's file, I need to do something like this:

parent = page.parent.parent.parent.parent.parent;
if (page.android) parent = page.parent.parent.parent.parent;

parent.showModal...

That is hacky, and creates problems when the layout changes. if I console.log currentPage, i get something like Page<2>, and if i console log args.parent.parent.parent etc until I find the page, I get my actual page that has an ID of home_page like this Page<home_page>

Is there still no cross platform way of getting the displayed page?

@manijak
Copy link

manijak commented Feb 9, 2018

Is this still valid? I keep getting the Parent page is not part of the window hierarchy. Close the current modal page before showing another one error when trying to show a modal in my main view.

My page instance is from the navigatedTo event.

@ghost
Copy link

ghost commented May 23, 2018

same error to me:

Parent page is not part of the window hierarchy. Close the current modal page before showing another one

@lock
Copy link

lock bot commented Aug 26, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked and limited conversation to collaborators Aug 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

5 participants