Removing navigation back arrow in Xamarin.Android - xamarin

I have a Xamarin.Forms app. I would like to remove/hide the back arrow in my navigation bars but keep the title. I was able to do it in iOS using the following code inside my NavigationPageRenderer:
UINavigationBar.Appearance.BackIndicatorImage = new UIImage();
UINavigationBar.Appearance.BackIndicatorTransitionMaskImage = new UIImage();
Is there any equivalent code for this in Android that I could use inside my renderer or in the MainActivity? I tried this.ActionBar.SetDisplayHomeAsUpEnabled(false); inside my MainActivity but the ActionBar always returns null. Below is my my MainActivity code:
public class MainActivity : FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
if (Window != null)
{
Window.SetStatusBarColor(Android.Graphics.Color.Transparent);
}
this.ActionBar.SetDisplayHomeAsUpEnabled(false);
}
}
What I want my navigation bar to look like something like the image below (this is in my iOS app).
The back arrow is just the back button title: NavigationPage.SetBackButtonTitle(this, "\u25C3");
In my ContentPage:
public partial class HomeTabPage : ContentPage
{
public HomeTabViewModel vm;
public HomeTabPage()
{
InitializeComponent();
BindingContext = vm = new HomeTabViewModel(this);
NavigationPage.SetHasBackButton(this, false);
NavigationPage.SetBackButtonTitle(this, "\u25C3");
}
}

Solution:
You can define a custom view as navigationBar of your content on specific platform (Android).Refer to the following code.
public partial class Page1 : ContentPage
{
public Page1 ()
{
InitializeComponent ();
if(Device.RuntimePlatform=="Android")
{
NavigationPage.SetHasBackButton(this, false);
NavigationPage.SetTitleView(this, SetBackView("Title", "back"));
}
}
private void BackButton_Clicked(object sender, EventArgs e)
{
Navigation.PopAsync();
}
StackLayout SetBackView (string title,string backButtonContent)
{
Button backButton = new Button()
{
Text = backButtonContent,
TextColor = Color.White,
FontAttributes=FontAttributes.None,
BackgroundColor = Color.Transparent,
Margin = new Thickness(-20,0,0,0),
};
backButton.Clicked += BackButton_Clicked;
StackLayout stackLayout = new StackLayout
{
Children = {
backButton,
new Label{
HorizontalTextAlignment=TextAlignment.Center,
VerticalTextAlignment=TextAlignment.Center,
Text=title,
TextColor=Color.White,
BackgroundColor=Color.Transparent,
},
},
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.StartAndExpand,
Orientation = StackOrientation.Horizontal,
};
return stackLayout;
}
}
And the effect is just like the following ,you can set the content of page title and backButton as you want.

Related

My CarouselViewControl block pinch and pan gesture in ItemSource

I used CarouselViewControl (https://github.com/alexrainman/CarouselView) in Xamarin.Forms with My Custom-View. My custom-view
was extended Contentview and was added Pinch & Pan Gesture Recgnizer.
custom-view's content is Image control in forms.
I wanted to slide, pan-move and zoomable image gallery.
Gesture performance (pinch & zoom) was good.So , I added CarouselViewControl for sliding option. But , CarouselViewControl blocked my custom-view's Gesture
I don't know why blocked my Gesture-Recognizer.
I registered Recognizers in constructor
class Android_ZoomViewer : ContentView
{
....
public Android_ZoomViewer()
{
PinchGestureRecognizer pinchGesture = new PinchGestureRecognizer();
pinchGesture.PinchUpdated += PinchGesture_PinchUpdated;
GestureRecognizers.Add(pinchGesture);
var panGesture = new PanGestureRecognizer();
panGesture.PanUpdated += OnPanUpdated;
GestureRecognizers.Add(panGesture);
}
}
in CarouselPage.xaml.cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CarouselPage : ContentPage
{
public CarouselPage()
{
InitializeComponent();
var carousel = new CarouselViewControl();
ObservableCollection<Android_ZoomViewer> list= new ObservableCollection<Android_ZoomViewer>();
hymn.Add(new Android_ZoomViewer() { Content = new ImageView() });
hymn.Add(new Android_ZoomViewer() { Content = new ImageView() });
hymn.Add(new Android_ZoomViewer() { Content = new ImageView() });
((ImageView)hymn[0].Content).SetBinding(Image.SourceProperty,"img1");
((ImageView)hymn[1].Content).SetBinding(Image.SourceProperty, "img2");
((ImageView)hymn[2].Content).SetBinding(Image.SourceProperty, "img3");
carousel.ItemsSource = list;
in CarouselView, my Gesture Blocked ...

Xamarin Tabbed Page not showing Content

trying to learn more about Tabbed Pages with i've built a very simple App containing three content Pages with a code like this:
public class Page1 : ContentPage
{
public Page1()
{
Content = new StackLayout
{
Children = {
new Label { Text = "Hello Page1" }
}
};
}
protected override void OnAppearing()
{
base.OnAppearing();
System.Diagnostics.Debug.WriteLine("Page 1 On Appearing");
}
protected override void OnDisappearing()
{
base.OnDisappearing();
System.Diagnostics.Debug.WriteLine("Page 1 Disappearing");
}
}
The Main Page looks like this:
public class MainPage : TabbedPage
{
public MainPage()
{
var page1 = new Page1();
page1.Title = "Page1";
var page2 = new Page2();
page2.Title = "Page2";
var page3 = new Page3();
page3.Title = "Page3";
Children.Add(page1);
Children.Add(page2);
Children.Add(page3);
}
}
Now when i click on a new tab, the OnDisappearing() method of the old tab is called, as well as the OnAppearing() method of new tab, BUT the content of the new page is not shown. It remains the content of the old page.
To show the content of the new page i have to click again on the tab.
Does anybody has experienced this kind of behaviour?
Best regards,
Marco

Pop the UIViewController in xamarin ios

I want to open a UIViewController from a content page and this code helps me in doing this
UIWindow Window = new UIWindow(UIScreen.MainScreen.Bounds);
var cvc = new ScanningPage();
var navController = new UINavigationController(cvc);
Window.RootViewController = navController;
Window.MakeKeyAndVisible();
but I also want a Back button on that Controller Page which navigate me back to that content Page.
this.NavigationController.PopViewController(true);
or
this.DismissViewController(true,null);
not working in this case.
I would recommend not creating a new Window and a UINavigationController...
Xamarin.Forms is contained in a single VC in the first Window, so you can obtain that view controller via:
UIApplication.SharedApplication.Windows[0].RootViewController;
So as an example Dependency service that presents and dismisses a VC (either from Forms or the view controller), you can do something like this.
Dependency interface:
public interface IDynamicVC
{
void Show();
void Dismiss();
}
iOS Dependency implementation
public class DynamicVC : IDynamicVC
{
UIViewController vc;
public void Show()
{
if (vc != null) throw new Exception("DynamicVC already showing");
vc = new UIViewController();
var button = new UIButton(new CGRect(100, 100, 200, 200));
button.SetTitle("Back", UIControlState.Normal);
button.BackgroundColor = UIColor.Red;
button.TouchUpInside += (object sender, EventArgs e) =>
{
Dismiss();
};
vc.Add(button);
var rootVC = UIApplication.SharedApplication.Windows[0].RootViewController;
rootVC.PresentViewController(vc, true, () => { });
}
public void Dismiss()
{
vc?.DismissViewController(true, () =>
{
vc.Dispose();
vc = null;
});
}
}

Xamarin.Forms customizing action bar on iOS

I'm using Xamarin.Forms and on iOS I need to customize the top action bar.
In this case I need to remove the dark line between the top action bar and the content view below (see screen shot).
How can I do it ?
Thank you in advance!!
I did it here and it working:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
//Tab bar
UITabBar.Appearance.SelectedImageTintColor = UIColor.FromRGB(247, 139, 43);
//Switch
UISwitch.Appearance.OnTintColor = UIColor.FromRGB(247, 139, 43);
//----------------------------------------------------------------------------
UINavigationBar.Appearance.BarTintColor = UIColor.Clear;
UINavigationBar.Appearance.ShadowImage = new UIImage();
UINavigationBar.Appearance.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);
//----------------------------------------------------------------------------
global::Xamarin.Forms.Forms.Init();
ImageCircleRenderer.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
You can achieve this by either creating a custom Renderer:
[assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(CustomNavigationRenderer))]
namespaceiOS.Renderers
{
public class CustomNavigationRenderer : NavigationRenderer
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
this.NavigationBar.ShadowImage = new UIImage();
this.NavigationBar.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);
}
}
}
Or in your iOS project, in AppDelegate method "FinishedLaunching" you could use the UIAppearance API to style your application across the board.
UINavigationBar.Appearance.ShadowImage = new UIImage();
UINavigationBar.Appearance.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);

Xamarin forms block user back key press

In my Xamarin forms application I want to show a confirmation message when user clicks the back button from Main-page. Is there any way to achieve this?
I overrided the OnBackButtonPressed method in my MainPage. But still the app is closing while back key press. Here is my code
protected override bool OnBackButtonPressed ()
{
//return base.OnBackButtonPressed ();
return false;
}
You can override OnBackButtonPressed for any Xamarin.Form Page. But it only will work for the physical button in Android and Windows Phone devices.
protected override bool OnBackButtonPressed () {
DisplayAlert("title","message","ok");
return true;
}
For the virtual one, you will need to create CustomRenderers and to intercept the click handler. In iOS it can be tricky because the user can go back doing other actions (e.g. the swipe gesture). Once you intercept it you just need to create your Confirmation Message (which I assume that you know how to do it).
For iOS you can do something like this:
[assembly: ExportRenderer (typeof (YourPage), typeof (YourPageRenderer))]
namespace YourNamespace {
public class YourPageRenderer : PageRenderer {
public override void ViewWillAppear (bool animated) {
base.ViewWillAppear (animated);
Action goBack = () => page.DisplayAlert("title","message","ok");
var backButton = new NavBackButton (goBack);
navigationItem.LeftBarButtonItem = new UIBarButtonItem (backButton);
}
}
public class NavBackButton : UIView {
public NavBackButton (Action onButtonPressed) {
SetButton (onButtonPressed);
}
UILabel text;
UIImageView arrow;
void SetButton(Action onButtonPressed){
arrow = new UIImageView(new CGRect(-25,0, 50, 50)) {
Image = new UIImage("Images/back").ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
};
arrow.TintColor = Colors.DarkGreen.ToUIColor ();
text = new UILabel(new CGRect(arrow.Frame.Width + arrow.Frame.X -15, arrow.Frame.Height /2 - 10, 40, 20)) { Text = "Back" };
text.TextColor = Colors.DarkGreen.ToUIColor ();
Frame = new CGRect(0,0,text.Frame.Size.Width + arrow.Frame.Width, arrow.Frame.Height);
AddSubviews (new UIView[] { arrow, text });
var tapGesture = new UITapGestureRecognizer (onButtonPressed);
AddGestureRecognizer (tapGesture);
}
public override void TouchesBegan (Foundation.NSSet touches, UIEvent evt) {
base.TouchesBegan (touches, evt);
text.TextColor = UIColor.YourColor;
arrow.TintColor = UIColor.YourColor;
}
public override void TouchesEnded (Foundation.NSSet touches, UIEvent evt){
base.TouchesEnded (touches, evt);
arrow.TintColor = UIColor.YourColor;
text.TextColor = UIColor.YourColor;
}
}
}
PS You will need to provide an arrow image ("Images/back")

Resources