How to change the height of a Tab Bar in Xamarin.Forms (iOS)? Is it possible with TabbedRenderer?
Yeah this is possible to modify from a CustomRenderer.
You will need to subclass the TabbedPage in the Forms project and use this class to export the render.
Then in the CustomRenderer override the ViewWillLayoutSubviews method. Something like:
public class MyTabbedPageRenderer : TabbedRenderer
{
// Modify this variable with the height you desire.
private readonly float tabBarHeight = 55f;
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
TabBar.Frame = new CGRect(TabBar.Frame.X, TabBar.Frame.Y + (TabBar.Frame.Height - tabBarHeight), TabBar.Frame.Width, tabBarHeight);
}
}
Hope this helps.-
Related
My aim is to change increase the size of the back arrow button that comes with the NavigationPage class. I have found out that we are able to change its color, but not it's size. Is it possible to do that in xamarin forms or can i atleast use a custom icon there that will suit my UI requirements.
<Style TargetType="NavigationPage">
<Setter Property="BarTextColor" Value="Red" />
<Setter Property="BarBackgroundColor" Value="Black" />
</Style>
Here i am able to set color for the "BarTextColor" but not it's size. Any help is appreciated.
NavigationPage back button is icon, so you can replace this icon using another bigger icon.
For Android platform, if your MainActivity type is FormsAppCompatActivity, you could custom a PageRenderer and change the Toolbar's NavigationIcon.
[assembly: ExportRenderer(typeof(ContentPage), typeof(NavigationPageRendererDroid))]
namespace FormsSample.Droid
{
public class NavigationPageRendererDroid : PageRenderer
{
public NavigationPageRendererDroid(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Page> e)
{
base.OnElementChanged(e);
var context = (Activity)this.Context;
var toolbar = context.FindViewById<AndroidX.AppCompat.Widget.Toolbar>(Droid.Resource.Id.toolbar);
toolbar.NavigationIcon = AndroidX.Core.Content.ContextCompat.GetDrawable(context, Resource.Drawable.c1);
}
}
}
Please note: ToolBar in Android platform> Resource folder> Layout type is androidx.appcompat.widget.Toolbar
If your ToolBar is other type, you can take a look:
How to change navigation page back button in xamarin forms
Update:
I also reproduce the same problem as you, from I provide the thread , you can follow the last solution, custom a NavigationPageRenderer, override the OnPushAsync method to set the Toolbar's icon.
Firstly, create a class named CustomNavigationPage in the .NET Standard project, and this class inherits from NavigationPage to make our custom renderer applied to that class.
public class CustomNavigationPage : NavigationPage
{
public CustomNavigationPage(Page startupPage) : base(startupPage)
{
}
}
Secondly, in Android project, create class named NavigationPageRenderer, override the OnPushAsync method.
[assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(NavigationPageRenderer))]
namespace FormsSample.Droid
{
public class NavigationPageRenderer : Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer
{
public Activity context;
public NavigationPageRenderer(Context context) : base(context)
{
}
protected override Task<bool> OnPushAsync(Page view, bool animated)
{
var retVal = base.OnPushAsync(view, animated);
var context = (Activity)this.Context;
var toolbar = context.FindViewById<AndroidX.AppCompat.Widget.Toolbar>(Droid.Resource.Id.toolbar);
if (toolbar != null)
{
if (toolbar.NavigationIcon != null)
{
toolbar.NavigationIcon = AndroidX.Core.Content.ContextCompat.GetDrawable(context, Resource.Drawable.c1);
toolbar.Title = "back";
}
}
return retVal;
}
}
}
Finally, in App.xaml.csfile, set the MainPage to NavigtaionPage,
MainPage = new CustomNavigationPage(new simplecontrol.Page41());
Is there any way to avoid the new presentation sheet style introduced on ios 13?
I am trying to do that in my CustomNavigationRenderer, without lucky
public class CustomNavigationRenderer : NavigationRenderer
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
base.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
...
}
Yes. If you look here you can see UIModalPresentationAutomatic defaults to UIModalPresentationPageSheet. Just change your modalPresentationStyle to UIModalPresentationFullScreen.
First create your new viewcontroller. This needs to have the modalPresentationStyle property set.
var modalViewController = new UIViewController();
modalViewController.modalPresentationStyle = UIModalPresentationStyle.FullScreen;
Then, present this viewController on top of the NavigationPage. NavigationRenderer has a property called ViewController:
this.ViewController.presentViewController(modalViewController, true, nil);
This is my code
ToolbarItems.Add(new ToolbarItem("User", "userAvatar.png", async () => {
await Navigation.PopToRootAsync();
}));
It's not working. It's place a masked single color image instead a png in colors.
I'm trying to archive something like this...
Any clue ?
I was going mad about this issue once, too (my situation was a bit more subtle, I had a plain and a colored verion of the icon and was wondering why the heck the colored icon would not be loaded) and unfortunately it's not that easy to overcome.
The icons being monochrome is the default behavior for iOS apps and Xamarin.Forms implements this behavior. According to this post you'll need a custom renderer to show colored icons in the navigation bar.
Edit
According to this post, you'll have to set the UIImageRenderingMode for the respective images in your custom renderer
image = image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
using the renderer implementation from this answer, it should be something in the line of
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(TabbedPage), typeof(MyProject.iOS.Renderers.IosMainMenuRenderer))]
namespace MyProject.iOS.Renderers {
public class IosMainMenuRenderer : TabbedRenderer {
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
var items = TabBar.Items;
for (var i = 0; i < items.Length; i++) {
items[i].Image = items[i].ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
items[i].SelectedImage = items[i].SelectedImage.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
}
}
}
}
but I have not tested this!
For a color logo on the right on all my navigation pages I used this custom renderer:
[assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(CustomNavigationRenderer))]
namespace App.iOS
{
public class CustomNavigationRenderer : NavigationRenderer
{
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
var logo = NavigationBar.TopItem.RightBarButtonItem.Image;
if (logo == null) return;
if (logo.RenderingMode == UIImageRenderingMode.AlwaysOriginal)
{
return;
}
NavigationBar.TopItem.RightBarButtonItem.Image = logo.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
}
}
}
The easiest way is to not use a toolbar, instead, set the type of this page as a Modal when navigating to it(Using Navigation.PushModal()). And add a horizontal LinearLayout that will act as the toolbar.
I am using xamarin to develop a Mac app, and somewhere in my program I want to set the tag of a NSView. However, the tag property is readonly for NSView, so I'm searching for a way to create a subclass where tag is writable. Is there any suggestion about how I should write the subclass? thanks
public class MyNSView : NSView
{
public nint _tag;
public new nint Tag
{
get
{
return _tag;
}
set
{
_tag = value;
}
}
Be aware that this is not longer the NSView Tag.
Using your custom NSView Tag
var view = new MyNSView ();
view.Tag = 100;
I found a workaround to get viewWithTag working:
#IBInspectable
override var tag: Int {
get { return super.tag }
set { super.tag = newValue }
}
In IB the NSView's Tag is still greyed out, but there is also a subclass's Tag available for setting a value.
Still, to my best effort, I can't find a logical reason for Tag to be greyed out in IB.
I am creating an iOS application (not Xamarin Forms) in Xamarin Studio and I have a question regarding styling. In this particular case I am setting the default appearance of a UIButton using the iOS Appearance API and calling this method from the FinishedLaunching method in the AppDelegate class.
private void SetUserInterfaceStyles()
{
//UIButton
UIButton.Appearance.TintColor = UIColor.FromRGB(73, 217, 41);
UIButton.Appearance.BackgroundColor = UIColor.FromRGB(73, 217, 41);
UIButton.Appearance.SetTitleColor(UIColor.White, UIControlState.Normal);
}
Now this works fine but there particular cases where the styling of the button differs from the default size and when setting any of the colours in the storyboard using Xamarin iOS designer the settings are not applied and the defaults from the SetUserInterfaceStyles method are used. Setting the colour in the ViewDidLoad of the ViewController does override the default but I would prefer a designer solution.
Is there a way to have multiple styles defined for a button or a working method to override the default styling in the form designer?
Looks like the recommended method of accomplishing this is not to use the Appearance API but to sub class the UI Button class and then to assign that class to the Storyboard button.
Something like this...
public StandardButton(IntPtr handle) : base (handle)
{
this.TouchDown += (sender, e) => { SetButtonStyleOnClick(); };
this.TouchUpInside += (sender, e) => { SetButtonStyleOnClickRelease(); };
this.SetBackgroundImage(new UIImage().FromColour(ApplicationStyles.ButtonBackgroundColourEnabled), UIControlState.Normal);
this.SetBackgroundImage(new UIImage().FromColour(ApplicationStyles.ButtonBackgroundColourDisabled), UIControlState.Disabled);
this.Layer.CornerRadius = ApplicationStyles.StandardButtonCornerRadius;
this.ClipsToBounds = true;
this.TintColor = ApplicationStyles.ButtonBackgroundColourEnabled;
this.SetTitleColor(ApplicationStyles.ButtonTitleColourEnabled, UIControlState.Normal);
this.SetTitleColor(ApplicationStyles.ButtonTitleColourDisabled, UIControlState.Disabled);
}
private void SetButtonStyleOnClick()
{
var shrink = CGAffineTransform.MakeScale(0.95f, 0.95f);
this.Transform = shrink;
this.BackgroundColor = ApplicationStyles.ButtonBackgroundColourClicked;
UIView.BeginAnimations("shrink", this.Handle);
UIView.SetAnimationDuration(0.25);
UIView.SetAnimationDelegate(this);
UIView.CommitAnimations();
}
private void SetButtonStyleOnClickRelease()
{
CGAffineTransform pop = CGAffineTransform.MakeScale(1.0f, 1.0f);
this.Transform = pop;
this.BackgroundColor = ApplicationStyles.ButtonBackgroundColourEnabled;
UIView.BeginAnimations("pop", this.Handle);
UIView.SetAnimationDuration(0.25);
UIView.SetAnimationDelegate(this);
UIView.CommitAnimations();
}