jsmarcus / Iconize

Use icon fonts in your Xamarin.Forms application!
Other
204 stars 70 forks source link

Disappearing toolbar icons #17

Open codingL3gend opened 7 years ago

codingL3gend commented 7 years ago

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

BenDevelopment commented 7 years ago

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

codingL3gend commented 7 years ago

@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.

BenDevelopment commented 7 years ago

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

codingL3gend commented 7 years ago

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

BenDevelopment commented 7 years ago

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

codingL3gend commented 7 years ago

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

BenDevelopment commented 7 years ago

@codingL3gend yes that's it

codingL3gend commented 7 years ago

@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.

BenDevelopment commented 7 years ago

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.

pcresswell commented 7 years ago

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.

BenDevelopment commented 7 years ago

@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 commented 7 years ago

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.

codingL3gend commented 7 years ago

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

jsmarcus commented 7 years ago

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

jsmarcus commented 7 years ago

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.

Li-Yanzhi commented 7 years ago

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).

pcresswell commented 7 years ago

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

jsmarcus commented 7 years ago

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

pcresswell commented 7 years ago

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:

gmwilhelm commented 7 years ago

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

MikeBairdRocks commented 7 years ago

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.

armaganX commented 6 years ago

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> 
castrojr913 commented 6 years ago

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

castrojr913 commented 6 years ago

@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

ChaseFlorell commented 6 years ago

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 commented 6 years ago

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;
                        }
                };
        }
    }