2

I got 5 tabs on TabbedPage & last 2 tabs have long title name, on Android, it shows 3dots as ... when there is no more room space remaining for text.

eg.

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

But on iOS it doesn't show 3dots, it shows complete text which can even override the title of another tab. Kind of text overlapping.

Basically I want my title of TabbedPage on multi-line, I use different content pages as tabs for my TabbedPage. I can create MultiLine ContentPage n its working fine on its own. But when I set the MultiLine title content page as a tab for my TabbedPage, it only shows the first-line title.

Any solution for MultiLine TabbedPage Title on iOS like below Image from Junior Jiang - MSFT

My Current renderer code

[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 );
            }
        }
    }
  }
}
ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196
Blu
  • 821
  • 4
  • 17

2 Answers2

2

If need to show three dots the same with Android , here is a solution for you . Later if have solution for multi-lines will update here .

You can use Custom TabbedRenderer to implement it .

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

Here MainPage inside code is a TabbedPagepublic partial class MainPage : TabbedPage

And here I set the limited length of TabBar Text is 6 . The Xaml is as follow :

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

The effect :

enter image description here

================================Update=============================

I have found the way to implement multiline title in tabbar item , need to modify code in TabbedRenderer as follow :

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

The effect:

enter image description here

Note : Althouh this way can implement it , however Apple not recommands to do this . It will affect the beauty of interface ,and make the frame of Tabbar item's shape distortion .

=============================Update with shared code=======================

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);
            }
        }
    }
}
Junior Jiang
  • 12,430
  • 1
  • 10
  • 30
  • Thanks, i will give it a try n then confirm you about it. – Blu Feb 06 '20 at 08:39
  • @Blu Hi , I have found the solution to make multiline title for TabbedPage in iOS , you can have a look at it when you have time. But you should know that Apple not recommand developer to modify that designs . – Junior Jiang Feb 13 '20 at 05:52
  • Hi, actually i tried your code but its crashing my app as an exception `System.IndexOutOfRangeException` for line `UILabel label = view.Subviews[1] as UILabel`..an UpVote for the help :) – Blu Feb 13 '20 at 10:25
  • I have edited my question with the current code i'm having. And i need exactly what you showed in your screen shot! thanks – Blu Feb 13 '20 at 10:33
  • @Blu OK, If Tabbar Item not contains icon , you should get label from index `0` , for example :`UILabel label = view.Subviews[0] as UILabel ` . – Junior Jiang Feb 14 '20 at 02:15
  • @Blu I have updated answer with combining your shared code . In my local site , I need to set `UILabel label = view.Subviews[1] as UILabel` . You can get from index `0` to check whehter can get . – Junior Jiang Feb 14 '20 at 02:54
  • yesterday I tried with UILabel label = view.Subviews[1] as UILabel; it got crashed, but work with UILabel label = view.Subviews[0] as UILabel; but my partial label was visible, mean - "Sample /n Title" so only "Sample" is visible. – Blu Feb 14 '20 at 09:49
  • i will try it in some time maybe. cuz i have to work on clients android issue...THANKS once again :) – Blu Feb 14 '20 at 09:50
  • this works, however the tabbed buttons are not aligned, in 2020 - and still no usable solution for this. Xamarin is poor – Async- Jul 01 '20 at 12:52
  • 1
    @Async- Okey , this is not related to Xamarin. Apple not suggests that make multiline title in tabbar item . If need that effects , you can this `uiTabBarItem.ImageInsets = new UIEdgeInsets(0, 0, 5, 0)` to modify the space of needed tababr item between label and icon . Have a look at this discussuion : https://stackoverflow.com/questions/57260325/spacing-between-icon-and-label-in-tabbedpage-bar/57263848#57263848 :-) – Junior Jiang Jul 02 '20 at 01:15
  • what I mean is the "final" solution can not offer the icons to be aligned (check how icons all jump heights because the label's have different length - one word or two words) - besides that I see in my project that if first word is shorter of the two - "Page eleven" - the second word will be cut to only 4 letters (label width is calculated from first word, no idea why), and will be "Page elev" - check it yourself. Besides, this is the only solution to the problem I found, meaning community Xamarin is lacking numbers, you will be on your own with your problems. Developers should avoid Xamarin. – Async- Jul 02 '20 at 10:19
  • @Junior Jiang - MSFT I do use UIEdgeInsets, that only constraints the image within edges, doesn't help with alignment of the icons where labels have different lengths. – Async- Jul 02 '20 at 10:25
  • @Async- These are iOS limitations, not specific to Xamarin. Regardless of language, [some workaround code is required](https://stackoverflow.com/a/60320339/199364). Could adapt the code shown there to C#. Or add spaces and newline so that all tabs have "similar" text. E.g. `"Page \neleven"`, and change code in answer to split on newline instead of space. Force all to be two line: `"About\n "`, to avoid "uneven" height (jumping). Any workaround has nothing to do with Xamarin; Xamarin simply uses the built-in iOS control. – ToolmakerSteve Dec 14 '21 at 21:07
-1

I think the most simple way (i.e, avoiding a custom renderer) would be to use a TitleView

Here's the official Microsoft sample. https://learn.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/navigation-titleview/

Here's a blog post. https://www.andrewhoefling.com/Blog/Post/xamarin-forms-title-view-a-powerful-navigation-view

In that TitleView you can use a Label and set the LineBreakMode property.

rssllgrrtt
  • 11
  • 2
  • Thanks for your suggestion but I already knew that & I have already mentioned it clearly, I can do what you suggested but I need something else. Please read it again carefully. – Blu Feb 04 '20 at 16:41
  • 1
    If by "mentioned it clearly", you mean "I can create MultiLine ContentPage n its working fine on its own" then fair enough. Other than that, I don't see any mention of the word "TitleView". I've read it multiple times. Regardless, you should just be able to apply the TitleView to your TabbedPage instead of a ContentPage. If you provide a sample of your code I'm happy to look further. – rssllgrrtt Feb 04 '20 at 16:48
  • @rssllgrrtt Hi , have you solved it ? If need with three dots , I have a solution . However now no having a multi-line solution . – Junior Jiang Feb 06 '20 at 02:51
  • 1
    @JuniorJiang-MSFT I've not looked since. I wasn't overly sure if the original poster was talking about the title of the page (the one you see at the top) or the title on the tab bar. Given that they didn't provide any additional info, code, or screenshots, and then I got a downvote, I figured I might as well leave this one alone. Good luck :) – rssllgrrtt Feb 06 '20 at 15:47
  • @rssllgrrtt You're right . Blu not showing screenshot about queston , maybe your answer will be Blu's wants . – Junior Jiang Feb 13 '20 at 01:14
  • IMHO, the reason this answer got downvoted is that the original title of the question was poor. I've edited that title to clarify that it is "tab item text" that is wanted multiline, NOT "title of page". – ToolmakerSteve Dec 14 '21 at 20:57