How can I replace a page's content and maintain functionality on iOS?

ben_mooreben_moore GBMember

Hi,

I've written a notification mechanism for Xamarin forms that is designed to allow an application to display toast style notifications (or any other custom content) at the top of the screen. It works as follows (pseudocode):

// Initialisation (only done once)
var existingContent = app.MainPage.Content;
var newContent = new Container(); // have used AbsoluteLayout + Grid for this, doesn't make any difference
var overlayContainer = new StackPanel();
newContent.Children.Add(existingContent);
newContent.Children.Add(overlayContainer);
app.MainPage.Content = newContent;

// When displaying a notification
overlayContainer.Children.Add(notification);
// Wait for dismiss / timout
overlayContainer.Children.Remove(notification);

This works fine on Android, however on iOS the UI stops responding to touch input. I've tracked the point this happens to the replacement of MainPage.Content with the new container. I've tried without the overlay as well (i.e. just wrapping the existing content) to rule out the overlay blocking input. I can see the UI is still functioning as it updates in the background, it just doesn't respond to touch any more.

Any pointers on either restoring touch responsiveness to the page after replacing the content or solving this in another way would be greatly appreciated!

Thanks,
Ben

Answers

  • AndrewMobileAndrewMobile USMember ✭✭✭✭

    @ben_moore might be silly, but what if you add a BackgroundColor="Transparent" to the Container.
    Also, what is Container, is it a ContentView ?

    Another thing: suppose you call this functionality right from your page (add a test button on the page). Does it work?
    I'm thinking if there aren't any issues with the moment you call this functionality.

  • AndrewMobileAndrewMobile USMember ✭✭✭✭

    Also, does this happen for any Page?
    Maybe it's something related to one page, maybe you're enabling \ disabling controls which are bound to view-model or you're using triggers.

    On the other hand, I'm not sure it's a good thing to replace the page's content, no matter what the content is and the functionality int the view-model.
    You are practically removing the content view from the parent (the Page) and add it to another control(the Container).
    I'm thinking about different internal things which happen when doing this.
    Another way is this: for those Pages where you know you display toasts, use a Grid as the root control of the Page and change the mechanism to insert the "overlayContainer" in the Grid, like grid.Children.Add(overlayContainer)

  • ben_mooreben_moore GBMember

    @AndreiNitescu I've used Grid and AbsoluteLayout for the Container, both of which allow you to overlay content. Tried the transparency and that didn't seem to help either.

    The reason I'm replacing the content is that this was intended to be a generic solution for any forms app, so I wouldn't have control over the page layout. I'm sure I've seen similar patterns work on Windows Phone in the past and this works on Android fine, it's just iOS being awkward :)

  • AndrewMobileAndrewMobile USMember ✭✭✭✭

    @ben_moore I would do a test page where I am doing the same thing from a button (wrap content root with a simple control) and see how it works.

  • ben_mooreben_moore GBMember

    @AndreiNitescu FYI I managed to solve it.

    In the initialisation, I added the following after 'existingContent = app.MainPage.Content':
    app.MainPage.Content = null;
    existingContent.Parent = null;

    And now it works on both Android and iOS. I'm guessing that there is a link between the Parent property and how the UI input is handled.

  • AndrewMobileAndrewMobile USMember ✭✭✭✭

    @ben_moore thanks for the follow up.
    very nice catch!
    on the other hand not so nice because this looks to me like another bug in Xamarin Forms.
    I somewhat suspected there might be an issue with removing a view from parent and adding to another.
    great idea to set them to null. I suspect this is not handled correctly internally. Would be great if you could report this to the team with a simple demo.

    btw, do you plan to make this functionality available open source as a reusable feature?

  • adamkempadamkemp USInsider, Developer Group Leader mod

    Have you tried using InputTransparent = true on your overlay?

  • ben_mooreben_moore GBMember

    @AndreiNitescu this will be part of a larger open source framework, but will consider making a separate release for this - it's pretty lightweight and works nicely :)

    @adamkemp thanks for the suggestion, had already tried that one

  • AndrewMobileAndrewMobile USMember ✭✭✭✭

    @ben_moore sounds good. What's the 'larger open source framework'? Any Github should I watch?

Sign In or Register to comment.