Xamarin 如何在iOS中为TabbedPage创建多行标题

Xamarin 如何在iOS中为TabbedPage创建多行标题,xamarin,xamarin.forms,xamarin.ios,Xamarin,Xamarin.forms,Xamarin.ios,我在TabbedPage上有5个标签&最后2个标签有很长的标题名,在Android上,它显示3个标签为。。。当没有足够的空间容纳文本时 例如 但在iOS上,它不显示3dot,而是显示完整的文本,甚至可以覆盖另一个选项卡的标题。有点文本重叠 基本上,我希望我的标签页标题是多行的,我使用不同的内容页作为标签页。 我可以创建多行内容页面,它可以自己正常工作。但当我将多行标题内容页设置为TabbedPage的选项卡时,它只显示第一行标题 iOS上多行选项卡页面标题的任何解决方案如下 我的当前渲染器代码

我在TabbedPage上有5个标签&最后2个标签有很长的标题名,在Android上,它显示3个标签为。。。当没有足够的空间容纳文本时

例如

但在iOS上,它不显示3dot,而是显示完整的文本,甚至可以覆盖另一个选项卡的标题。有点文本重叠

基本上,我希望我的标签页标题是多行的,我使用不同的内容页作为标签页。 我可以创建多行内容页面,它可以自己正常工作。但当我将多行标题内容页设置为TabbedPage的选项卡时,它只显示第一行标题

iOS上多行选项卡页面标题的任何解决方案如下

我的当前渲染器代码

[assembly: ExportRenderer( typeof( TabbedPage ), typeof(ExtendedTabbedPageRenderer ) )]
 namespace testBlu.iOS.Renderers
 {
   public class ExtendedTabbedPageRenderer : TabbedRenderer
   {
    public override void ViewDidAppear( bool animated )
    {
        base.ViewDidAppear( animated );
        if( TabBar.Items != null )
        {
            UITabBarItem[] tabs = TabBar.Items;
            foreach( UITabBarItem tab in tabs )
            {
                UITextAttributes selectedColor = new UITextAttributes { TextColor = UIColor.Black };
                UITextAttributes fontSize = new UITextAttributes { Font = UIFont.SystemFontOfSize( 12 )};
                tab.SetTitleTextAttributes( selectedColor, UIControlState.Normal );
                tab.SetTitleTextAttributes( fontSize, UIControlState.Normal );
            }
        }
    }
  }
}

我认为最简单的方法,即避免自定义渲染器,是使用标题视图

这是微软的官方样本。

这里有一篇博文。


在该标题视图中,您可以使用标签并设置属性。

如果需要在Android上显示三个相同的点,这里有一个解决方案。稍后,如果有多行的解决方案,将在此处更新

您可以使用来实现它

[assembly: ExportRenderer(typeof(MainPage), typeof(ExtendedTabbedPageRenderer))]
namespace AppTab3.iOS
{
    public class ExtendedTabbedPageRenderer : TabbedRenderer
    {
        public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);
            var tabs = Element as TabbedPage;
            if(tabs != null)
            {
                for( int i = 0;i < TabBar.Items.Length;i++)
                {
                    if (TabBar.Items[i] == null) return;

                    if(TabBar.Items[i].Title.Length > 6)
                    {
                        string showText = TabBar.Items[i].Title;
                        TabBar.Items[i].Title = showText.Substring(0, 5) + "...";
                    }
                }
            }
        }
    }
}
其效果是:

=============================================更新=============================

public override void ViewWillAppear(bool animated)
{
    base.ViewWillAppear(animated);
    var tabs = Element as TabbedPage;

    if (tabs != null)
    {
        for (int i = 0; i < TabBar.Items.Length; i++)
        {

            if (TabBar.Items[i] == null) continue;

            if (TabBar.Items[i].Title.Length > 6)
            {
                string[] splitTitle = TabBar.Items[i].Title.Split(" ");
                if (null != splitTitle[1])
                {
                    if (splitTitle[1].Length > 4)
                    {
                        string showText = splitTitle[1];
                        splitTitle[1] = showText.Substring(0, 3) + "...";
                    }
                }

                TabBar.Items[i].Title = splitTitle[0] + "\n" + splitTitle[1];

                UITabBarItem item = TabBar.Items[i] as UITabBarItem;
                UITextAttributes selectedColor = new UITextAttributes { TextColor = UIColor.Black };
                UITextAttributes fontSize = new UITextAttributes { Font = UIFont.SystemFontOfSize(12) };
                item.SetTitleTextAttributes(selectedColor, UIControlState.Selected);
                item.SetTitleTextAttributes(fontSize, UIControlState.Selected);

                UIView view = item.ValueForKey(new Foundation.NSString("view")) as UIView;
                UILabel label = view.Subviews[1] as UILabel;
                //label.Text = "Hello\nWorld!";
                label.Lines = 2;
                label.LineBreakMode = UILineBreakMode.WordWrap;

                //var frame = label.Frame;
                //label.Frame = CGRect.FromLTRB(frame.Location.X, frame.Location.Y, frame.Size.Width, frame.Size.Height + 10);
            }
        }
    }
}
我已经找到了在tabbar项中实现多行标题的方法,需要修改TabbedRenderer中的代码,如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:d="http://xamarin.com/schemas/2014/forms/design"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            mc:Ignorable="d"
            xmlns:views="clr-namespace:AppTab3.Views"
            x:Class="AppTab3.Views.MainPage">

    <TabbedPage.Children>
        <NavigationPage Title="Browse">

            <NavigationPage.Icon>
                <OnPlatform x:TypeArguments="FileImageSource">
                    <On Platform="iOS" Value="tab_feed.png"/>
                </OnPlatform>
            </NavigationPage.Icon>
            <x:Arguments>
                <views:ItemsPage />
            </x:Arguments>
        </NavigationPage>

      ...

        <NavigationPage Title="Page Five Long Title Page Five Long Title">
            <NavigationPage.TitleView>
                 <Label Text="About Five Long Title" MaxLines="4"/>
            </NavigationPage.TitleView>
            <NavigationPage.Icon>
                <OnPlatform x:TypeArguments="FileImageSource">
                    <On Platform="iOS"
                        Value="tab_about.png" />
                </OnPlatform>
            </NavigationPage.Icon>
            <x:Arguments>
                <views:AboutPage />
            </x:Arguments>
        </NavigationPage>

    </TabbedPage.Children>

</TabbedPage>
public override void ViewWillAppear(bool animated)
{
    base.ViewWillAppear(animated);
    var tabs = Element as TabbedPage;

    if (tabs != null)
    {
        for (int i = 0; i < TabBar.Items.Length; i++)
        {

            if (TabBar.Items[i] == null) continue;

            if (TabBar.Items[i].Title.Length > 6)
            {
                string[] splitTitle = TabBar.Items[i].Title.Split(" ");
                TabBar.Items[i].Title = splitTitle[0] + "\n" + splitTitle[1];

                UITabBarItem item = TabBar.Items[i] as UITabBarItem;
                UIView view = item.ValueForKey(new Foundation.NSString("view")) as UIView;
                UILabel label = view.Subviews[1] as UILabel;
                //label.Text = "Hello\nWorld!";
                label.Lines = 2;
                label.LineBreakMode = UILineBreakMode.WordWrap;

                //var frame = label.Frame;
                //label.Frame = CGRect.FromLTRB(frame.Location.X, frame.Location.Y, frame.Size.Width, frame.Size.Height + 20);
            }
        }
    }
}
其效果是:

注意:虽然这种方法可以实现,但是苹果不建议这样做。这会影响界面的美观,使Tabbar项的框架形状发生变形

==============================================使用共享代码更新=======================

public override void ViewWillAppear(bool animated)
{
    base.ViewWillAppear(animated);
    var tabs = Element as TabbedPage;

    if (tabs != null)
    {
        for (int i = 0; i < TabBar.Items.Length; i++)
        {

            if (TabBar.Items[i] == null) continue;

            if (TabBar.Items[i].Title.Length > 6)
            {
                string[] splitTitle = TabBar.Items[i].Title.Split(" ");
                if (null != splitTitle[1])
                {
                    if (splitTitle[1].Length > 4)
                    {
                        string showText = splitTitle[1];
                        splitTitle[1] = showText.Substring(0, 3) + "...";
                    }
                }

                TabBar.Items[i].Title = splitTitle[0] + "\n" + splitTitle[1];

                UITabBarItem item = TabBar.Items[i] as UITabBarItem;
                UITextAttributes selectedColor = new UITextAttributes { TextColor = UIColor.Black };
                UITextAttributes fontSize = new UITextAttributes { Font = UIFont.SystemFontOfSize(12) };
                item.SetTitleTextAttributes(selectedColor, UIControlState.Selected);
                item.SetTitleTextAttributes(fontSize, UIControlState.Selected);

                UIView view = item.ValueForKey(new Foundation.NSString("view")) as UIView;
                UILabel label = view.Subviews[1] as UILabel;
                //label.Text = "Hello\nWorld!";
                label.Lines = 2;
                label.LineBreakMode = UILineBreakMode.WordWrap;

                //var frame = label.Frame;
                //label.Frame = CGRect.FromLTRB(frame.Location.X, frame.Location.Y, frame.Size.Width, frame.Size.Height + 10);
            }
        }
    }
}

谢谢你的建议,但我已经知道&我已经清楚地提到了,我可以按照你的建议去做,但我还需要别的东西。请仔细再读一遍。如果你说得很清楚,你的意思是我可以自己创建多行内容页面,这样就足够了。除此之外,我看不到有人提到TitleView这个词。我已经读了很多遍了。无论如何,您应该只能够将标题视图应用于选项卡页,而不是内容页。如果您提供代码示例,我很乐意进一步研究。@rssllgrrtt您好,您解决了吗?如果需要三个点,我有一个解决方案。但是现在没有多行解决方案了。@JuniorJiang MSFT我从那以后就没看过了。我不太确定最初的海报是在谈论你在顶部看到的页面标题还是标签栏上的标题。考虑到他们没有提供任何额外的信息、代码或屏幕截图,然后我得到了反对票,我想我最好还是不要管这个。祝你好运:@rssllgrrtt你说得对。Blu没有显示关于queston的屏幕截图,也许你的答案会是Blu想要的。谢谢,我会尝试一下,然后确认一下。@Blu嗨,我找到了在iOS中为TabbedPage制作多行标题的解决方案,你有时间可以看一看。但是你应该知道苹果不建议开发者修改这些设计。嗨,事实上我试过你的代码,但它作为一个例外系统破坏了我的应用程序。IndexOutOfRangeException for line UILabel label=view.Subviews[1]as UILabel..向上投票寻求帮助:我用当前的代码编辑了我的问题。我需要的正是你在屏幕截图中显示的内容!thanks@Blu好的,若选项卡项不包含图标,那个么您应该从索引0中获取标签,例如:UILabel label=view.subview[0]作为UILabel。