TitleView for Pages

DH80DH80 USMember ✭✭
edited December 2016 in Xamarin.Forms Evolution

Summary

Add a new property to Page called TitleView which allows users to set a view that will be shown in the Navigation Bar (iOS) / Toolbar (Android) when the page is a child of a NavigationPage

API Changes

public View TitleView { get; set; }

Intended Use Case

Common use case would be to set a SearchBar in TitleView to follow common UI practices and to save on vertical real estate.
Another use case would be to make the TitleView actionable to allow apps to open a drop down or another view.

3
3 votes

In Progress · Last Updated

Assigned to @Velocity

«1

Posts

  • TheRealJasonSmithTheRealJasonSmith USXamarin Team Xamurai
    edited December 2016

    Would need to see how this would work on UWP. Do you envision the TitleView property being on a Page or on the NavigationPage? Generally speaking I am +1 on this idea.

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    This would deprecate TitleIcon which was implemented for that very same reason, and only works on iOS and Android.
    +1 on this as well

  • DH_HA1DH_HA1 USMember ✭✭✭

    I envision the TitleView property being on the page b/c I might want to have different TitleViews on different pages

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    TitleView (like TitleIcon is) pertains to NavigationPage as it only shows up when the page is in a NavigationPage. But as it's an attached BP, you actually set it on the `ContentPage, like this:

    NavigationPage.SetTitleView(myContentPage, myTitleView);
    

    or in XAML

    <ContentPage ...>
        <NavigationPage.TitleView>
            <Label .../>
        </NavigationPage.TitleView>
    </ContentPage>
    
  • DH_HA1DH_HA1 USMember ✭✭✭

    @StephaneDelcroix done .. so how hard would it be to implement this? I have a current requirement for this?

  • EZHartEZHart USXamarin Team Xamurai

    @TheRealJasonSmith said:
    Would need to see how this would work on UWP. Do you envision the TitleView property being on a Page or on the NavigationPage? Generally speaking I am +1 on this idea.

    For UWP, this would be as simple as adding the renderer for the TitleView to the same ContentPresenter we're already using for the Title TextBlock.

    Which brings up a question: is the TitleView intended to replace the current title label when it's set? Or is it intended to sit next to it?

  • DH_HA1DH_HA1 USMember ✭✭✭

    Replace it

  • TheRealJasonSmithTheRealJasonSmith USXamarin Team Xamurai

    I think it has to replace it as well, otherwise it will require differentiating based on UWP/non-UWP platform when designing.

  • TheRealJasonSmithTheRealJasonSmith USXamarin Team Xamurai

    Accepting proposal. As a side note I added more detail in the readme as to what exactly this means.

  • DH_HA1DH_HA1 USMember ✭✭✭

    thanks been wanting this one for a while

  • sastsast NLMember

    Very useful suggestion! Currently we are struggling with the available space, placing the searchbar in the title would be a nice feature! +1

  • DavidDancyDavidDancy AUMember ✭✭✭✭

    I would love to have this.

  • NMackayNMackay GBInsider, University ✭✭✭✭✭

    Would be an excellent addition. We never use the TitleIcon.

  • trung.dinhtrung.dinh VNMember ✭✭

    That's an interesting feature!

  • VelocityVelocity NZMember ✭✭✭

    @DH_HA1 @TheRealJasonSmith @StephaneDelcroix Happy to implement as need to do this for an upcoming project.
    Let me know and I'll start working on a PR.

  • DH_HA1DH_HA1 USMember ✭✭✭

    @Velocity please do! iOS is easy but Android will be a bit more challenging

  • StephaneDelcroixStephaneDelcroix USInsider, Beta ✭✭✭✭

    @Velocity please go ahead. as far as I know no one else is working on this yet.

  • VelocityVelocity NZMember ✭✭✭

    @StephaneDelcroix Thanks Stephane. OK great, will make a start on this next week.

  • trung.dinhtrung.dinh VNMember ✭✭

    @Velocity said:
    @StephaneDelcroix Thanks Stephane. OK great, will make a start on this next week.

    Thanks @Velocity for sharing!

  • DH_HA1DH_HA1 USMember ✭✭✭

    @Velocity making progress?

  • VelocityVelocity NZMember ✭✭✭

    @DH_HA1 Made a start on it at the beginning of the week. Coming along nicely.
    Am happy to make the branch available for any collaborative work if anyone is interested, as just working on this in my spare time at the moment.

  • DH_HA1DH_HA1 USMember ✭✭✭
    edited March 31

    @Velocity send a link when you get a chance. Forms Android apparently updates the toolbar a lot so I found the timing on that one more difficult

  • DH_HA1DH_HA1 USMember ✭✭✭

    @Velocity anything to share on this?

  • VelocityVelocity NZMember ✭✭✭

    @DH_HA1 said:
    @Velocity anything to share on this?

    Been a busy week, but will put up a branch this weekend. I'm also working on the Swipe Recognizer proposal at the moment too, so trying to divide my time between them both!

  • trung.dinhtrung.dinh VNMember ✭✭

    waiting for many awesome @Velocity! :D

  • trung.dinhtrung.dinh VNMember ✭✭

    @Velocity said:

    @DH_HA1 said:
    @Velocity anything to share on this?

    Been a busy week, but will put up a branch this weekend. I'm also working on the Swipe Recognizer proposal at the moment too, so trying to divide my time between them both!

    you can study this lib https://github.com/twintechs/TwinTechsFormsLib

  • VelocityVelocity NZMember ✭✭✭

    @DH_HA1 said:
    @Velocity anything to share on this?

    This is the branch I will be working from. iOS renderer coming first, Android and UWP to follow.

  • VelocityVelocity NZMember ✭✭✭

    Just an update on this - focusing my attention on finishing the swipe gesture recognizer first and then will move back to implementing this. If anyone wants to keep it moving in the meantime, let me know.

  • trung.dinhtrung.dinh VNMember ✭✭

    waiting!

  • trung.dinhtrung.dinh VNMember ✭✭

    making progress?

  • SeyyedSorooshSeyyedSoroosh USMember ✭✭

    ITNOA

    @Velocity It is cool feature, with this feature we hopefully can make search bar in toolbar.

  • ShimmyWeitzhandlerShimmyWeitzhandler USMember ✭✭✭

    ditto

  • VelocityVelocity NZMember ✭✭✭

    @trung.dinh @SeyyedSoroosh @ShimmyWeitzhandler

    Thanks for your interest. I'm not going to start working on this yet until my other PR has been accepted and merged for the Swipe Gesture recognizer. I can only really work on one request at a time due to limited availability.

  • ShimmyWeitzhandlerShimmyWeitzhandler USMember ✭✭✭

    @Velocity then for me it has a lower priority than let's say WPF's ItemsControl-like view. Integrated validation. Some other features the like to allow quick shipping of a product.

  • mdizzymdizzy USMember ✭✭

    This is interesting sounds like it would work something like WPF's HeaderedControl Let me jump in to see if I can help move along.

  • ShimmyWeitzhandlerShimmyWeitzhandler USMember ✭✭✭

    Currently horizontal ListView or ListView without selection or other things requiring the semantics of the ItemsControl is a pain in the @$$.

  • nitudnitud INMember ✭✭

    Can u give some example or code in xaml which i can use for search bar in toolbaritems

  • ChrisBoydChrisBoyd USMember ✭✭
    edited June 9

    Just an FYI for interested individuals, but I've already written a simple renderer for iOS that adds both ToolbarView and ToolbarHome XAML elements.

    ToolbarHome takes a single ToolbarItem child (allowing you to use either text or an icon) to put on the left side of the toolbar.

    ToolbarView should be able to take any view as its child and will replace the TitleView.

    Page implementation (adding XAML elements):

            public ToolbarPage()
            {
                this.On<Xamarin.Forms.PlatformConfiguration.iOS>().SetPrefersStatusBarHidden(StatusBarHiddenMode.False);
            }
    
            #region ToolbarView
            public static readonly BindableProperty ToolbarViewProperty = BindableProperty.Create(nameof(ToolbarView), typeof(object), typeof(ToolbarPage), null, propertyChanged: OnToolbarViewChanged);
    
            Element _toolbarViewElement;
    
            [EditorBrowsable(EditorBrowsableState.Never)]
            public Element ToolbarViewElement
            {
                get { return _toolbarViewElement; }
            }
    
            public object ToolbarView
            {
                get { return GetValue(ToolbarViewProperty); }
                set { SetValue(ToolbarViewProperty, value); }
            }
    
            private static void OnToolbarViewChanged(BindableObject bindable, object oldValue, object newValue)
            {
                var lv = (ToolbarPage)bindable;
                lv.OnToolbarViewChanged(newValue);
            }
    
            void OnToolbarViewChanged(object newValue)
            {
                var view = newValue as Element;
                _toolbarViewElement = view;
            }
            #endregion
    
            #region ToolbarHome
            public static readonly BindableProperty ToolbarHomeProperty = BindableProperty.Create(nameof(ToolbarHome), typeof(ToolbarItem), typeof(ToolbarPage), null, propertyChanged: OnToolbarHomeChanged);
    
            public ToolbarItem ToolbarHome
            {
                get { return GetValue(ToolbarHomeProperty) as ToolbarItem; }
                set { SetValue(ToolbarHomeProperty, value); }
            }
    
            private static void OnToolbarHomeChanged(BindableObject bindable, object oldValue, object newValue)
            {
                var lv = (ToolbarPage)bindable;
                lv.OnToolbarHomeChanged(newValue);
            }
    
            void OnToolbarHomeChanged(object newValue)
            {
                var view = newValue as ToolbarItem;
                if (view != null)
                {
                    SetInheritedBindingContext(view, BindingContext);
                }
            }
            #endregion
        }
    

    iOS renderer:

        public class ToolbarPageRenderer : PageRenderer
        {
            public override void ViewWillAppear(bool animated)
            {
                base.ViewWillAppear(animated);
    
                var toolbarPage = this.Element as ToolbarPage;
                var toolbarView = toolbarPage.ToolbarViewElement as VisualElement;
    
                var navigationItem = this.NavigationController?.TopViewController?.NavigationItem;
                if (navigationItem == null)
                { 
                    return;
                }
    
                if (toolbarView != null)
                {
                    if (Platform.GetRenderer(toolbarView) == null)
                        Platform.SetRenderer(toolbarView, Platform.CreateRenderer(toolbarView));
                    var vRenderer = Platform.GetRenderer(toolbarView);
    
                    var size = new CGRect(0, 0, 200, 30);
    
                    var nativeView = vRenderer.NativeView;
                    var segmentedControl = nativeView as UISegmentedControl;
                    nativeView.Frame = size;
    
                    nativeView.AutoresizingMask = UIViewAutoresizing.All;
                    nativeView.ContentMode = UIViewContentMode.ScaleToFill;
    
                    vRenderer.Element.Layout(size.ToRectangle());
    
                    navigationItem.TitleView = nativeView;
    
                    nativeView.SetNeedsLayout();
                }
    
                if (toolbarPage.ToolbarHome != null)
                {
                    navigationItem.LeftBarButtonItems = new UIBarButtonItem[] { toolbarPage.ToolbarHome.ToUIBarButtonItem() };
                }
            }
        }
    

    I haven't yet gotten around to working on any other platform renderers.

  • ChrisBoydChrisBoyd USMember ✭✭

    Use of my custom ToolbarPage in XAML:

    <custom:ToolbarPage ...>
        <custom:ToolbarPage.ToolbarHome>
            <ToolbarItem Text="{i18n:Translate ButtonDevices}" Command="{Binding NavigateCommand}" CommandParameter="ModalSelectPage/DeviceSelectPage">
                <ToolbarItem.Icon>
                    <OnPlatform x:TypeArguments="FileImageSource"
                        Android="ic_list_white_24dp.xml"
                        iOS="ic_list_white.png" />
                </ToolbarItem.Icon>
            </ToolbarItem>
        </custom:ToolbarPage.ToolbarHome>
        <custom:ToolbarPage.ToolbarView>
            <controls:SegmentedControl x:Name="SegControl">
                <controls:SegmentedControl.Children>
                    <controls:SegmentedControlOption Text="{i18n:Translate TitleFiles}" />
                    <controls:SegmentedControlOption Text="{i18n:Translate TitleOther}" />
                </controls:SegmentedControl.Children>
            </controls:SegmentedControl>
        </custom:ToolbarPage.ToolbarView>
        <ContentPage.Content>
    ...
        </ContentPage.Content>
    </custom:ToolbarPage>
    
  • SmeSme USMember ✭✭✭

    @ChrisBoyd

    This works great for most elements, but it doesn't work when I try to add a stacklayout or grid.

«1
Sign In or Register to comment.