UINavigationBar Custom Right Bar Button in Xamarin.iOS - xamarin

I am adding a custom button with image on the right side of the UINavigationBar in Xamarin.iOS,
But unfortunately does not succeed yet. The problem is that it always shows a button with a blue background.
This is my code:
var customBtn = new UIBarButtonItem ();
customBtn.Image = UIImage.FromFile ("home.png");
customBtn.Clicked += (object sender, EventArgs e) =>
{
Console.WriteLine("This button is clicked");
};
NavigationItem.RightBarButtonItem = customBtn;

Think you need to use SetRightBarButtonItems like so:
var rightButton = new UIButton (UIButtonType.Custom);
rightButton.SetImage (UIImage.FromBundle ("home"), UIControlState.Normal);
rightButton.SetImage (UIImage.FromBundle ("home"), UIControlState.Disabled);
rightButton.Frame = new CGRect (0, 0, 17, 17); // set this to the size of the image
var rightBarButton = new UIBarButtonItem (rightButton);
navItem.SetRightBarButtonItems(new UIBarButtonItem[] {rightBarButton }, false);
rightButton.TouchUpInside += (sender, e) => {
Console.WriteLine("This button is clicked");
};

Related

How to add "Done" button to uiDatepicker in xamarin.ios for compact style

I was trying to add a button manually on the screen after a datepicker is tapped. But no matter what it always gets under the modal or blurred. Is it possible to add this button on top of that modal somehow and then when the button is tapped the modal will be dismissed.
Or only the button being top subview(over the modal) would be enough for me to work on.
This is my code:
private void DatePickerDateFrom_EditingDidBegin(object sender, EventArgs e)
{
UIButton button = new UIButton();
button.Frame = new CGRect(0, 0, 200, 100);
button.SetTitle("Done", UIControlState.Normal);
button.BackgroundColor = UIColor.Red;
Add(button);
button.Layer.ZPosition = 1000000;
}
This is the result now(the red blurry button which I want to be clear and tappable)

Display UIPopViewController center in iphone and iPad in iOS

I am working on Xamarin.iOS, I want to display UIPopViewController in iphone and iPad in center Screen. The below way I try the code :
public override void ViewDidLoad()
{
base.ViewDidLoad();
showButton.TouchUpInside += (sender, e) => {
// Create a UIImage view to show in the popover
UIImageView monkeyIcon = new UIImageView(new CGRect(20, 20, 200, 200));
monkeyIcon.Image = UIImage.FromFile("Abc.png");
monkeyIcon.UserInteractionEnabled = true;
// Create a view controller to act as the popover
UIViewController popover = new UIViewController();
popover.View = monkeyIcon;
popover.ModalPresentationStyle = UIModalPresentationStyle.Popover;
// Grab Image
var image = UIImage.FromFile("298-circlex.png");
// Add a close button
var closeButton = new UIButton(new CGRect(0, 20, 200, 200));
closeButton.UserInteractionEnabled = true;
closeButton.SetTitle("Close", UIControlState.Normal);
monkeyIcon.AddSubview(closeButton);
// Wireup the close button
closeButton.TouchUpInside += (button, e2) => {
popover.DismissViewController(true, null);
};
// Present the popover
PresentViewController(popover, true, null);
// Configure the popover for the iPad, the popover displays as a modal view on the
//iPhone
UIPopoverPresentationController presentationPopover = popover.PopoverPresentationController;
if (presentationPopover != null)
{
presentationPopover.SourceView = this.View;
presentationPopover.PermittedArrowDirections = 0;
presentationPopover.SourceRect = showButton.Frame;
presentationPopover.Delegate = this;
}
};
}
[Export("adaptivePresentationStyleForPresentationController:")]
public UIModalPresentationStyle GetAdaptivePresentationStyle(UIPresentationController forPresentationController)
{
return UIModalPresentationStyle.None;
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
// Release any cached data, images, etc that aren't in use.
}
I tried all the answer in SO and google but nothing is help to me.
Problem 1 :
- In Iphone the PopViewController is displaying in the full Screen, but I want to center and small PopView.
Problem 2 :
- In Ipad the PopViewController is displaying in the LeftSide I want to display it Center.
Any Help will be Appreciated.
If you don't want this PopoverPresentationController to be shown full screen, you should set a size to its owner Controller: popover.PreferredContentSize = new CGSize(200, 200);. Also you should set the PopoverPresentationController's configuration firstly before you present the popover.
In Ipad the PopViewController is displaying in the LeftSide I want to
display it Center.
SourceRect means the rectangle in the specified view in which to anchor the popover. You want to show this pop in the center, set this to your View.Frame. Here is my code for you referring to:
UIPopoverPresentationController presentationPopover = popover.PopoverPresentationController;
if (presentationPopover != null)
{
presentationPopover.SourceView = this.View;
presentationPopover.PermittedArrowDirections = 0;
presentationPopover.SourceRect = View.Frame;
//Configure this Delegate first before presenting.
presentationPopover.Delegate = this;
}
PresentViewController(popover, true, null);

Xamarin iOS CustomRenderer button background suddenly not working

I have the following CustomRenderer to apply a style to buttons in my iOS project of my cross-platform Xamarin.Forms app.
The button used to have rounded edges, white text, and a blue gradient background.
Everything has been working just fine up until I downloaded Xcode 8.1. Since moving to 8.1, the same code will not present the background gradient. Can anyone see how I could change my code to get the background gradient working again?
The border radius and text color are all working as usual - it's just the background gradient which is missing.
[assembly: ExportRenderer(typeof(CustomButton), typeof(CustomButtonRenderer))]
namespace MyApp.Forms.iOS.CustomRenderers
{
class CustomButtonRenderer : ButtonRenderer
{
public override void LayoutSubviews()
{
foreach (var layer in Control?.Layer.Sublayers.Where(layer => layer is CAGradientLayer))
{
layer.Frame = Control.Bounds;
}
base.LayoutSubviews();
}
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
var gradient = new CAGradientLayer();
gradient.CornerRadius = Control.Layer.CornerRadius = 10;
gradient.Colors = new CGColor[]
{
UIColor.FromRGB(153, 204, 255).CGColor,
UIColor.FromRGB(51, 102, 204).CGColor
};
var layer = Control?.Layer.Sublayers.LastOrDefault();
Control?.Layer.InsertSublayerBelow(gradient, layer);
Control.SetTitleColor(UIColor.White, UIControlState.Normal);
Control.Layer.BorderColor = UIColor.FromRGB(51, 102, 204).CGColor;
Control.Layer.BorderWidth = 1;
}
}
}
}
Ok so I have finally worked out what was going on. In the LayoutSubviews method where I was setting each layer.Frame to the value of Control.Bounds, I noticed that Control.Bounds was a rectangle full of zeros, so my gradient was therefore 0 pixels in size.
I have modified the method as follows and it now works as expected again:
public override void LayoutSubviews()
{
var newBounds = Element.Bounds.ToRectangleF();
foreach (var layer in Control?.Layer.Sublayers.Where(layer => layer is CAGradientLayer))
{
layer.Frame = new CGRect(0, 0, newBounds.Width, newBounds.Height);
}
base.LayoutSubviews();
}
I'm not sure if this is a hack, but it seems to do the job - for now...

WebView not getting rendered on Application launch in Xamarin.Forms

When I create WebView in xamarin, it is not visible when the application is launched. It gets visible when the view is readjusted.
How can I resolve the above issue.
Here is sample code that I am using
var browser = new WebView();
var htmlSource = new HtmlWebViewSource ();
public SamplePage()
{
InitializeComponent();
StackLayout stackLayout = new StackLayout
{
VerticalOptions = LayoutOptions.FillAndExpand,
Children =
{
sometextbox,
browser
}
}
}
//Code within some button's event
htmlSource.Html = #"<html><body>
<h1>Xamarin.Forms</h1>
<p>Welcome to WebView.</p>
</body></html>";
browser.Source = htmlSource;
It seems like the FillAndExpand should be on the webview, not on the StackLayout
The issue is that WebView has no idea how big it needs to be and so it is probably there but has no size. What I do is to assign a Width and Height in SizeChanged like so:
public SamplePage()
{
InitializeComponent();
StackLayout stackLayout = new StackLayout
{
VerticalOptions = LayoutOptions.FillAndExpand,
Children =
{
sometextbox,
browser
}
}
SizeChanged += (sender, args) => {
browser.WidthRequest = Width;
browser.HeightRequest = Height * 0.75;
}
}
If the browser still does not show up, keep the SizeChanged() code since it will update the WebView on rotation but also add the same code to OnAppearing():
protected override void OnAppearing() {
base.OnAppearing();
browser.WidthRequest = Width;
browser.HeightRequest = Height * 0.75;
}
If you needed to do that upon button click you could do that or you could even leave the above code in place and just change WebView.IsVisible.

Xamarin Forms TranslateTo relative to parent

I'm using TranslateTo to move an object vertically on the screen, but I only see how to use numbers for the x/y arguments. How can I do something like when adding an object on a view where you say, "Constraint.RelativeToParent(..."?
CAN I translate relative to something else?
Sounds like you want to use a RelativeLayout perhaps?
There is a discussion here, and a demo here that may get you started?
Yes - you can perform a Translate operation on a View that is relative to some other View.
The following example demonstrates that:-
StackLayout objStackLayout = new StackLayout()
{
Orientation = StackOrientation.Vertical,
};
RelativeLayout objRelativeLayout = new RelativeLayout();
objStackLayout.Children.Add(objRelativeLayout);
Label objLabel1 = new Label();
objLabel1.BackgroundColor = Color.Red;
objLabel1.Text = "This is a label";
objLabel1.SizeChanged += ((o2, e2) =>
{
objRelativeLayout.ForceLayout();
});
objRelativeLayout.Children.Add(objLabel1,
xConstraint: Constraint.RelativeToParent((parent) =>
{
return ((parent.Width - objLabel1.Width) / 2);
}));
Button objButton = new Button();
objButton.BackgroundColor = Color.Blue;
objButton.Text = "Hi";
objRelativeLayout.Children.Add(objButton,
xConstraint: Constraint.RelativeToView(objLabel1,
new Func<RelativeLayout, View, double>((pobjRelativeLayout, pobjView) =>
{
return pobjView.X + pobjView.Width;
})));
Button objButton1 = new Button();
objButton1.Text = "Translate the button that is relative to the text";
objButton1.Clicked += ((o2, e2) =>
{
objButton.TranslateTo(100,100,2000);
});
objStackLayout.Children.Add(objButton1);
Button objButton2 = new Button();
objButton2.Text = "Change label text";
objButton2.Clicked += ((o2, e2) =>
{
objLabel1.Text = "text";
});
objStackLayout.Children.Add(objButton2);
Clicking on the button with text "Translate the button that is relative to the text" will translate the blue button by 100 width and 100 height.
The rule is still enforced when you click the button with text "Change label text". Note that the translation previously applied is still at an offset of 100 width and 100 height from the end of the Label that we are doing our relative layout against.

Resources