【问题标题】:How to make multiline text on tab items in iOS如何在 iOS 中的选项卡项上制作多行文本
【发布时间】:2020-05-20 04:14:55
【问题描述】:

我在TabbedPage 上有 5 个标签,最后 2 个标签的标题名称很长,在 Android 上,当没有剩余空间用于文本时,它显示 3 个点为 ...。

例如。

tab 1 title - Title 1 for Tab1
tab 2 title - Title 2 for Tab2
tab 3 title - Title 3 for Tab3
 Android - Title 1 f... | Title 2 f... | Title 3 f...

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

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

iOS 上 MultiLine TabbedPage Title 的任何解决方案,如下所示

我当前的渲染器代码

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

【问题讨论】:

    标签: xamarin.forms xamarin.ios


    【解决方案1】:

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

    你可以使用Custom TabbedRenderer来实现它。

    [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) + "...";
                        }
                    }
                }
            }
        }
    }
    

    这里MainPage里面的代码是TabbedPagepublic partial class MainPage : TabbedPage

    在这里,我将 TabBar Text 的有限长度设置为 6Xaml 如下:

    <?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>
    

    效果:

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

    我已经找到了在tabbar item中实现多行标题的方法,需要修改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) 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);
                }
            }
        }
    }
    

    【讨论】:

    • 谢谢,我会试一试,然后确认一下。
    • @Blu 你好,我找到了在iOS中为TabbedPage制作多行标题的解决方案,你有时间可以看看。但是您应该知道,Apple 不建议开发人员修改该设计。
    • 嗨,实际上我尝试了您的代码,但它使我的应用程序崩溃为异常System.IndexOutOfRangeException for line UILabel label = view.Subviews[1] as UILabel..an UpVote 寻求帮助:)
    • 我已经用我拥有的当前代码编辑了我的问题。我需要你在屏幕截图中显示的内容!谢谢
    • @Async- Okey ,这与 Xamarin 无关。 Apple 不建议在 tabbar item 中制作多行标题。如果需要那个效果,你可以这个uiTabBarItem.ImageInsets = new UIEdgeInsets(0, 0, 5, 0)来修改标签和图标之间需要的tababr项目的空间。看看这个讨论:stackoverflow.com/questions/57260325/… :-)
    【解决方案2】:

    我认为最简单的方法(即避免使用自定义渲染器)是使用 TitleView

    这是官方的 Microsoft 示例。 https://docs.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/navigation-titleview/

    这是一篇博文。 https://www.andrewhoefling.com/Blog/Post/xamarin-forms-title-view-a-powerful-navigation-view

    在该 TitleView 中,您可以使用 Label 并设置 LineBreakMode 属性。

    【讨论】:

    • 谢谢你的建议,但我已经知道了,我已经清楚地提到了,我可以按照你的建议做,但我需要别的东西。请仔细阅读一遍。
    • 如果“清楚地提到它”,你的意思是“我可以创建 MultiLine ContentPage n 它自己可以正常工作”那么就足够公平了。除此之外,我没有看到任何提到“TitleView”这个词。我已经读过很多遍了。无论如何,您应该能够将 TitleView 应用到您的 TabbedPage 而不是 ContentPage。如果您提供代码示例,我很乐意进一步了解。
    • @rssllgrrtt 嗨,你解决了吗?如果需要三个点,我有一个解决方案。但是现在没有多线解决方案。
    • @JuniorJiang-MSFT 从那以后我就再也没看过。我不太确定原始海报是在谈论页面标题(您在顶部看到的那个)还是标签栏上的标题。鉴于他们没有提供任何额外的信息、代码或屏幕截图,然后我得到了反对票,我想我还是别管这个了。祝你好运:)
    • @rssllgrrtt 你说得对。 Blu 没有显示关于 queston 的截图,也许你的答案会是 Blu 想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多