Iconize icon indicating copy to clipboard operation
Iconize copied to clipboard

Disappearing toolbar icons

Open codingL3gend opened this issue 8 years ago • 26 comments

Icons in the toolbar items are disappearing whenever i switch tabs within a view.

codingL3gend avatar Apr 11 '17 16:04 codingL3gend

Same problem when toolbar icons are bound to a command. When the command's can execute changes, the icons desapear. You can have a look on this short sample reproducing the problem: https://ufile.io/72pg9

BenDevelopment avatar May 23 '17 16:05 BenDevelopment

@BenDevelopment I was able to work around this by using an OnAppearing function on the tabs themselves and setting visibility to false and then true for the toolbar items.

codingL3gend avatar May 23 '17 18:05 codingL3gend

@codingL3gend thank you for your reply. But in my case I have no tabs. I only have a IconNavigationPage containing my page.

BenDevelopment avatar May 23 '17 18:05 BenDevelopment

@BenDevelopment are you doing a Navigation.PushAsync(new IconNavigationPage(page)); or a new IconNavigationPage(page)

codingL3gend avatar May 23 '17 18:05 codingL3gend

@codingL3gend yes I'm doing a: MainPage = new IconNavigationPage (new Contact page())

BenDevelopment avatar May 23 '17 18:05 BenDevelopment

@BenDevelopment looking at your code, is it when the message variable is getting set that the icon disappears?

codingL3gend avatar May 23 '17 19:05 codingL3gend

@codingL3gend yes that's it

BenDevelopment avatar May 23 '17 20:05 BenDevelopment

@BenDevelopment in that setter can you check to see what the Visibility is of the toolbar item button at that time. If its false, try setting it to true to see if it stays. or also trying to set it to false and then true right after as well to see if that keeps it there.

codingL3gend avatar May 23 '17 20:05 codingL3gend

I will try tomorrow. Another thing to know is that when the ToolBarItem disappear, I still can click on it. The icon is no longer visible but the "button" still exists.

BenDevelopment avatar May 23 '17 22:05 BenDevelopment

I was looking at this today. It seems to me that Xamarin.Forms is triggering a repainting of the Toolbar Icon when a bound property changes (in my case, IsEnabled). It fails to look up the icon file (no surprise there) hence errors like the following:

Could not load image named: {0}: fa-ellipsis-v 04-12 10:40:44.831 W/ResourceType( 2685): No package identifier when getting value for resource > number 0x00000000 04-12 10:40:44.831 E/BitmapFactory( 2685): Unable to decode stream: java.io.FileNotFoundException: fa-ellipsis-v: open failed: ENOENT (No such file or directory)

It seems that Xamarin.Forms update comes after iconize updates the toolbar icons which explains why the toolbar button is still fully functional - just not visible.

pcresswell avatar May 24 '17 00:05 pcresswell

@codingL3gend I've checked the Visibility property ans it's always to True. @pcresswell I seems that you're right. You can try it by replacing the ContactPage.xaml from my sample by this code:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:iconize="clr-namespace:FormsPlugin.Iconize;assembly=FormsPlugin.Iconize"
             xmlns:vm="clr-namespace:App2.ViewModels;"
             x:Class="App2.Views.ContactPage">
    <ContentPage.BindingContext>
        <vm:ContactViewModel />
    </ContentPage.BindingContext>
    <ContentPage.ToolbarItems>

        <iconize:IconToolbarItem Icon="md-close" Command="{Binding CancelCommand}" Text="Cancel" IconColor="White" IsVisible="True" x:Name="testIcon"/>
        <iconize:IconToolbarItem Icon="md-send" Command="{Binding SendCommand}" Text="Send" IconColor="White"/>
    </ContentPage.ToolbarItems>
    <StackLayout>
        <Label Text="Try writing something below, you will see the icons on the toolbar disappear."/>
        <Entry Grid.Row="1" Text="{Binding Message, Mode=TwoWay}" Placeholder="Enter text"/>
        <Switch IsToggled="{Binding Source={x:Reference testIcon}, Path=IsVisible}" />
        <Label Text="{Binding Source={x:Reference testIcon}, Path=IsVisible}"/>
    </StackLayout>
</ContentPage>

Once the icon disapear, you can change the Switch value to "refresh" the view, then the icon reapear. Any idea to fix so we can suggest a PR?

BenDevelopment avatar May 24 '17 07:05 BenDevelopment

I've made a very dirty temporary workaround:

  public static class RefreshIconizeToolBar
    {
        private static bool avoid;

        public static void Register(Page Page)
        {
            Page.Appearing += Page_Appearing;
        }

        private static void Page_Appearing(object sender, EventArgs e)
        {
            foreach (var item in (sender as Page).ToolbarItems)
                if (item is IconToolbarItem)
                    (item as IconToolbarItem).Command.CanExecuteChanged += (a, b) =>
                    {
                        if (!avoid)
                            refreshToolBarItems((sender as Page));
                    };
        }

        private static void refreshToolBarItems(Page contentPage)
        {
            avoid = true;
            if (contentPage.ToolbarItems != null)
                foreach (var item in contentPage.ToolbarItems)
                    if (item is IconToolbarItem)
                    {
                        var backupVisibility = (item as IconToolbarItem).IsVisible;
                        (item as IconToolbarItem).IsVisible = false;
                        (item as IconToolbarItem).IsVisible = backupVisibility;
                        (contentPage.BindingContext as ViewModelBase).RaisePropertyChanged(null);
                    }
            avoid = false;
        }
    }

Use it like that:

  public MyPage()
        {
            InitializeComponent();
            RefreshIconizeToolBar.Register(this);
        }

This only fix the problem with command can execute changed, but you can register any event you need.

BenDevelopment avatar May 24 '17 11:05 BenDevelopment

@BenDevelopment nice hack. glad you were able to work around it.

codingL3gend avatar May 24 '17 15:05 codingL3gend

I believe this is resolved with the 2.0.0 beta on nuget. Can you take a look?

jsmarcus avatar May 31 '17 01:05 jsmarcus

p.s. - There are breaking changes with this build. Everything has been simplified by making it only support Xamarin.Forms. All the modules can (and should) be installed in all projects (even the icons). The FormsPlugin project/module has been deprecated and the number of libraries required has been cut in half or in third depending.

jsmarcus avatar May 31 '17 02:05 jsmarcus

Same issue here when using BindingObject for Icon property. Glad to see @jsmarcus working on the new release. Also hope to see the new controls of Icon in Entry and Icon in Button(with Text).

Li-Yanzhi avatar May 31 '17 07:05 Li-Yanzhi

tested 2.0.0.24-beta on XF IOS App.

Added IconToolbarItem. Bind to command Flip CanExecute

Noted that the icon no longer disappeared when flipping the state of command. So in this area, it looks like it's working fine.

But (and I'm not certain if this related) I noticed that the icons (I'm testing with Material Design icon set) were all out of sorts. Tests a few and they didn't match. for example:

"md-add" gave me -> screen shot 2017-05-31 at 11 18 29 pm

md-alarm -> Didn't yield an icon (displayed missing file "?"). md-album -> Fish icon

pcresswell avatar Jun 01 '17 03:06 pcresswell

@pcresswell Can you provide a repo? My sample project shows the correct icons for those.

jsmarcus avatar Jun 01 '17 13:06 jsmarcus

Try this: https://github.com/pcresswell/iconize-test

I've probably done something wrong so assume nothing. Let me know where I went wrong. Just using the iOS app.

play around with the icon here:

<iconize:IconToolbarItem Icon="md-add" />

pcresswell avatar Jun 02 '17 01:06 pcresswell

I get the same behavior in the iOS sample app. All icons are displayed as a ? in a box or just the name of the icon:

simulator screen shot 02 06 2017 08 17 38

gmwilhelm avatar Jun 02 '17 06:06 gmwilhelm

Looks like the icons are not embedded in the nuget packages right now for IOS. I am using the latest 2.0.0.24-beta and just added the fonts to my IOS project under resources and then the icons rendered fine.

MikeBairdRocks avatar Jun 20 '17 03:06 MikeBairdRocks

You have to copy and paste iconize-fontawesome.ttf file into iOS Resources, then in Info.plist file you should add this

    • <key>UIAppFonts</key>
      
    • <array>     
      
    • <string>iconize-fontawesome.ttf</string>	
      
    • </array> 
      

armaganX avatar Nov 20 '17 10:11 armaganX

@armaganX Friend, your approach doesn't work. I added the font names and there's no change

castrojr913 avatar Jan 23 '18 14:01 castrojr913

@gmwilhelm @armaganX I found a workaround :) : Copy ttf files (e.g. iconize-fontawesome.ttf) to Resources folder on iOS Project. You can find them here: https://github.com/jsmarcus/Iconize/tree/master/src/Fonts

castrojr913 avatar Jan 23 '18 14:01 castrojr913

I'm hitting the same issue as the OP. I've grabbed the latest beta, and have intentionally not done any magic bits to flip "CanExecute" in hopes of

a) finding a real solution b) not having any janky code in the project, as there are other developers on this project as well.

Any movement on a real fix?

ChaseFlorell avatar Feb 09 '18 03:02 ChaseFlorell

I made a small tweak to @BenDevelopment 's work around so that we don't have to call a static method on the constructor of pages that need the refresh.

    public sealed class MyNavigationPage : IconNavigationPage
    {
        public FccNavigationPage()
        {
            BarBackgroundColor = Color.FromHex("#003E6B");
            BarTextColor = Color.White;

            Pushed += (sender, args) => { InitializeToolbarIconRefresh(args.Page); };
        }


        private void InitializeToolbarIconRefresh(Page page)
        {
            if (!(page is TabbedPage tabbedPage)) return;

            foreach (var child in tabbedPage.Children)
                child.Appearing += (sender, args) =>
                {
                    foreach (var item in ((Page) sender).ToolbarItems)
                        if (item is IconToolbarItem iconItem)
                        {
                            var originalVisibility = iconItem.IsVisible;
                            iconItem.IsVisible = false;
                            iconItem.IsVisible = originalVisibility;
                        }
                };
        }
    }

ChaseFlorell avatar Feb 09 '18 13:02 ChaseFlorell