Можно ли использовать значки системы на вкладках в Xamarin Forms?

Есть ли способ указать значок "system", который будет отображаться на вкладке при использовании Xamarin Forms? Я хотел бы использовать значки, такие как "Избранное", "Закладка", "История" и т.д., Но я не хочу предоставлять все свои собственные изображения для различных платформ.

Используя Xamarin.iOS, вы можете использовать этот синтаксис:

tab1.TabBarItem = new UITabBarItem (UITabBarSystemItem.Favorites, 0);

Однако я не могу найти, как это сделать в кросс-платформенном проекте Xamarin.Forms.

Это мой текущий код:

var profilePage = new ContentPage {
    Title = "Profile",
    //This requires my own images to be added to the project whereas
    //I wish to use built-in images which are platform specific for
    //Favourites, Bookmark, More, etc...
    //Icon = "Profile.png",
    Content = new StackLayout {
        Spacing = 20, Padding = 50,
        VerticalOptions = LayoutOptions.Center,
        Children = {
        new Entry { Placeholder = "Username" },
        new Entry { Placeholder = "Password", IsPassword = true },
        new Button {
            Text = "Login",
            TextColor = Color.White,
            BackgroundColor = Color.FromHex("77D065") }}}};

var settingsPage = new ContentPage {
    Title = "Settings",
    Content = new StackLayout {
        Spacing = 20, Padding = 50,
        VerticalOptions = LayoutOptions.Center,
        Children = {
            new Entry { Placeholder = "Username" },
            new Entry { Placeholder = "Password", IsPassword = true }}}
        };


MainPage = new TabbedPage { Children = {profilePage, settingsPage} };

Ответ 1

Для iOS

вам нужен пользовательский рендерер для вашей страницы. В моем примере это класс CustomTabsPage. Вы не можете просто использовать значки системы для создания UIImage. Нам нужно использовать UITabBarItem. Проблема в том, что UITabBarItem не позволяет изменять ни заголовок, ни изображение/значок. Но мы можем скопировать изображение из него.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using UIKit;
using ButtonRendererDemo;
using ButtonRendererDemo.iOS;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(CustomTabsPage), typeof(CustomTabsPageRenderer))]
namespace ButtonRendererDemo.iOS
{
    public class CustomTabsPageRenderer : TabbedRenderer
    {

         #region Sytem Image with custom title

        public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);

            foreach (var item in TabBar.Items)
            {
                item.Image = GetTabIcon(item.Title);
            }
        }

        private UIImage GetTabIcon(string title)
        {
            UITabBarItem item = null;

            switch (title)
            {
                case "Profile":
                    item = new UITabBarItem(UITabBarSystemItem.Search, 0);
                    break;
                case "Settings":
                    item = new UITabBarItem(UITabBarSystemItem.Bookmarks, 0);
                    break;
            }

            var img = (item != null) ? UIImage.FromImage(item.SelectedImage.CGImage, item.SelectedImage.CurrentScale, item.SelectedImage.Orientation) : new UIImage();
            return img;
        }

        #endregion
    }
}

введите описание изображения здесь

Для Android

все проще

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ButtonRendererDemo;
using ButtonRendererDemo.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms.Platform.Android.AppCompat;
using Android.Support.Design.Widget;

[assembly: ExportRenderer(typeof(CustomTabsPage), typeof(CustomTabsPageRenderer))]
namespace ButtonRendererDemo.Droid
{
    public class CustomTabsPageRenderer : TabbedPageRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
        {
            base.OnElementChanged(e);

            //var layout = (TabLayout)ViewGroup.GetChildAt(1); //should be enough but just for robustness we use loop below

            TabLayout layout = null;
            for (int i = 0; i < ChildCount; i++)
            {
                layout = GetChildAt(i) as TabLayout;
                if (layout != null)
                    break;
            }
            if (layout != null)
            {
                for (int tabIndex = 0; tabIndex < layout.TabCount; tabIndex++)
                    SetTabIcon(layout, tabIndex);
            }
        }

        private void SetTabIcon(TabLayout layout, int tabIndex)
        {
            var tab = layout.GetTabAt(tabIndex);

            switch (tabIndex)
            {
                case 0:
                    tab.SetIcon(Resource.Drawable.icon2);//from local resource
                    break;
                case 1:
                    tab.SetIcon(Resource.Drawable.ic_media_play_dark);//from Android system, depends on version !
                    break;
            }
        }
    }

}

введите описание изображения здесь

Ответ 2

Чтобы использовать значки, вам нужна структура, специфичная для платформы. В Xamarin.Forms для этого:

Icon = "youricon.png";

Вам нужно:

  • iOS: поместите изображение в /Resources/youricon.png
  • Android: поместите изображение в /Resources/drawable/youricon.png
  • Win Phone: поместите изображение в корень проекта приложения Windows Phone.

Ответ 3

Вы должны написать собственный визуализатор TabbedPage для проекта iOS:

public class YourTabbedRenderer : TabbedRenderer {
        public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);
            var items = TabBar.Items;

            for (var i = 0; i < items.Length; i++) {
                // set your icons here, you could do some string comparison (check tab title or tab icon resource name)
                // items[i].Image = 
                // items[i].SelectedImage = 
            }
        }
    }

http://developer.xamarin.com/guides/cross-platform/xamarin-forms/custom-renderer/