Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 77050

XForms preventing native use (custom renderers) of bottom toolbar in iOS so can't use

$
0
0

This subject is an extension and increased scope of another thread by @SvenKunttz at :

https://forums.xamarin.com/discussion/26804/how-to-transform-secondary-toolbaritems-to-uibarbuttonitems-in-the-bottom-toolbar-on-ios

The reason for this thread is to both clarify and detail the issue but also because it now appears that if one wants to utilise the bottom tool bar as used extensively on iOS apps, Apple’s included, then it doesn’t appear possible to do that with Xamarin.Forms currently.

To show the issue first a test project based directly on the Master-Detail Application (iOS Unified API) with the “A” code shown below added which merely adds in standard iOS bottom tool bar on both the Master page (just example refresh and pause options) and on the Detail page (just example camera and play options)

This results in the app looking like the screen shots 1 & 2 in attached file with bottom toolbar as standard and native that iOS users are used to.

The next text project is based directly on the Blank App (Xamarin.Forms Shared) with the “B” code shown below added to create an app functioning similar to Master-Detail Application. With this code the resultant app appearing as screenshots 3 & 4 with the clicking on the “details” button on the first page taking to the details page.

Now to add the bottom toolbar to this app one would’ve hoped that using the Forms ToolbarItems with Secondary option would do it but unfortunately this creates a tab bar at the top of the screen under the main navigation bar which is NOT iOS like, not compliant with Apple’s UI guidelines and definitely NOT what iOS users are used to so .. no problem, we can go native and use custom renderer(s) to gain access to the native objects and do anything native there as Xamarin directs for anything not possible via the Xamarin APIs .. or so we (Sven, myself, etc) thought! ..

Created two custom renderers in “C” code shown below, one for the MasterPage and one for the DetailPage with exactly the same code as in “A” but when one runs this the app appears as screenshot 5 in attached file with the complete screen blanked out .. in fact it looks like it's covered.

If we comment out the SetToolbarHidden line in the MasterPageRenderer (last line in inserted code) then the app appears fine on first page but when the details button is clicked nothing appears to happen and then master page is still there.

If we comment out the SetToolbarHidden line in the DetailPageRenderer the app works fine.

And just to note - if the SetToolbarHidden line is commented out then in both cases (Master and Detail) the ViewDidLoad is followed by the ViewWillAppear but if it’s left in (which we need to see the toolbar) then the ViewWillAppear is never called implying some error occurring between ViewDidLoad and ViewWillAppear in the XForms code itself causing the error.

So in essence it appears that if we want to use the bottom toolbar in iOS that is common and standard in many apps we can’t do it and use Xamarin.Forms which for me at least is a disaster!

I can understand that Xamarin.Forms can’t do everything we all want but in this case it actually prevents us using the standard native features by custom renderers.

Might this be a fundamental issue with Xamarin.Forms and hence perhaps why the ToolbarItems functionality in .Forms is inconsitant with the normal native look and feel in the first place?

@JasonASmith - could you let us know if there is an issue that prevents this native functionality being used in custom renderers or if there’s something in the .Forms code that is a “bug” (?) that’s causing this? If, as I suspect it maybe, it’s related to how the ToolbarItems has been implemented, is there a way to “turn that off” with a flag or something when we do our own thing for instance.

Hope there’s a solution to this, ideally of course having ToolbarItems render correctly in a native iOS standard way by using the bottom bar but if not then quite happy to use custom renderers but .. only they can work!

Code - “A”

MasterViewController.cs

public override void ViewDidLoad ()
{
base.ViewDidLoad ();
   NavigationItem.LeftBarButtonItem = EditButtonItem;
   var addButton = new UIBarButtonItem (UIBarButtonSystemItem.Add, AddNewItem);
   NavigationItem.RightBarButtonItem = addButton;
   TableView.Source = dataSource = new DataSource (this);

   // code to insert and show bottom tool bar items
   this.SetToolbarItems( new UIBarButtonItem[] {
    new UIBarButtonItem(UIBarButtonSystemItem.Refresh, (s,e) => {
          Console.WriteLine("Refresh clicked");
      }),
      new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace) { Width = 50 },
      new UIBarButtonItem(UIBarButtonSystemItem.Pause, (s,e) => {
         Console.WriteLine ("Pause clicked");
      })
   }, false);
   this.NavigationController.SetToolbarHidden (false, false);
   // code to insert and show bottom tool bar items
}  

DetailViewController.cs

public override void ViewDidLoad ()
{
base.ViewDidLoad ();
   ConfigureView ();

   // code to insert and show bottom tool bar items
   this.SetToolbarItems( new UIBarButtonItem[] {
    new UIBarButtonItem(UIBarButtonSystemItem.Camera, (s,e) => {
          Console.WriteLine("Camera clicked");
      }),
      new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace) {Width = 50},
      new UIBarButtonItem(UIBarButtonSystemItem.Play, (s,e) => {
          Console.WriteLine ("Play clicked");
      })
   }, false);
this.NavigationController.SetToolbarHidden (false, false);
// code to insert and show bottom tool bar items
}

Code - "B"

public class App : Application
{
public App()
   {
    MainPage = new NavPage();
   }
}
public class NavPage : NavigationPage
{
public NavPage ()
{
    Navigation.PushAsync(new MasterPage());
}

public class MasterPage : ContentPage
{
public MasterPage ()
   {
    Title = "Master";
      var button = new Button { Text = “Detail” };
      button.Clicked += (sender, args) =>
      {
       Navigation.PushAsync(new DetailPage());
      };
      Content = new StackLayout { 
       VerticalOptions = LayoutOptions.Center,
         Children = {
          new Label {
             XAlign = TextAlignment.Center,
               Text = "Master Page"
            },
            button
         }
      };
ToolbarItems.Add(
new ToolbarItem("Edit", "", EditAction, ToolbarItemOrder.Primary, 0));
   }
   void EditAction()
   {
   }

public class DetailPage : ContentPage
{
public DetailPage ()
   {
Title = “Detail”;
Content = new StackLayout { 
       VerticalOptions = LayoutOptions.Center,
       Children = {
          new Label {
             XAlign = TextAlignment.Center,
               Text = "Detail Page"
            }
         }
};
ToolbarItems.Add(
new ToolbarItem("Done", "", DoneAction, ToolbarItemOrder.Primary, 0));
   }
   void DoneAction()
   {
}
}

Code - "C"

public class MasterPageRenderer : PageRenderer
{
public override void ViewDidLoad ()
   {
    base.ViewDidLoad();

    // code to insert and show bottom tool bar items
    this.SetToolbarItems( new UIBarButtonItem[] {
    new UIBarButtonItem(UIBarButtonSystemItem.Refresh, (s,e) => {
           Console.WriteLine("Refresh clicked");
       }),
        new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace) {Width = 50},
       new UIBarButtonItem(UIBarButtonSystemItem.Pause, (s,e) => {
          Console.WriteLine ("Pause clicked");
       })
     }, false);
   this.NavigationController.SetToolbarHidden (false, false);
    // code to insert and show bottom tool bar items
}
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
}

public class DetailPageRenderer : PageRenderer
{
public override void ViewDidLoad ()
   {
    base.ViewDidLoad();

      // code to insert and show bottom tool bar items
      this.SetToolbarItems( new UIBarButtonItem[] {
       new UIBarButtonItem(UIBarButtonSystemItem.Camera, (s,e) => {
          Console.WriteLine("Camera clicked");
         }),
         new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace) {Width = 50},
         new UIBarButtonItem(UIBarButtonSystemItem.Play, (s,e) => {
            Console.WriteLine ("Play clicked");
         })
}, false);
   this.NavigationController.SetToolbarHidden (false, false);
      // code to insert and show bottom tool bar items
}
   public override void ViewWillAppear (bool animated)
   {
    base.ViewWillAppear (animated);
}
}  


Viewing all articles
Browse latest Browse all 77050

Trending Articles