I'm using Xamarin Auth via dependency services which presents a new view where the user authenticates However, when the modal page appears and is fully visible, it jumps up and down revealing this black bar
It quickly disapears and the page loads like so: where the top of the page is hidden. Thanks in advance
I've tried the following:
UIWindow window = UIApplication.SharedApplication.KeyWindow;
UIViewController viewController = window.RootViewController;
UIViewController AuthVC = auth.GetUI();
AuthVC.EdgesForExtendedLayout = UIRectEdge.None;
AuthVC.ExtendedLayoutIncludesOpaqueBars = false;
AuthVC.AutomaticallyAdjustsScrollViewInsets = false;
viewController.EdgesForExtendedLayout = UIRectEdge.None;
viewController.ExtendedLayoutIncludesOpaqueBars = false;
viewController.AutomaticallyAdjustsScrollViewInsets = false;
viewController.PresentViewController(AuthVC, true, null);
The UIViewController from Auth.GetUI() comes from this package: https://github.com/xamarin/Xamarin.Auth
Here is my temp fix, It still flashes but it looks correct after if has loaded. Does anyone know what would cause the black bar flashing?
viewController.PresentViewController(AuthVC, true, new Action(() =>
{
var MainUIView = AuthVC.View.Subviews[0];
var MainNavBar = AuthVC.View.Subviews[1];
var NavBarHeight = MainNavBar.Frame.Y + MainNavBar.Frame.Height;
MainUIView.Frame = new CoreGraphics.CGRect(0, NavBarHeight, MainUIView.Frame.Width, MainUIView.Frame.Height - NavBarHeight);
}));
Try this one
viewController.NavigationController.PresentViewController(AuthVC, true, new Action(() =>
{
var MainUIView = AuthVC.View.Subviews[0];
var MainNavBar = AuthVC.View.Subviews[1];
var NavBarHeight = MainNavBar.Frame.Y + MainNavBar.Frame.Height;
MainUIView.Frame = new CoreGraphics.CGRect(0, NavBarHeight, MainUIView.Frame.Width, MainUIView.Frame.Height - NavBarHeight);
}));
Related
I have an application that from the main app "hamburger" menu, if an option is selected I want to show a PickerView for the user to select a number from.
Because it's needs to be accessible throughout the app from this menu I built the UIPickerView in the AppDelegate.cs (as that's where the UINavigationController code is and from that the menu).
Everything shows up correctly: User selected menu button -> menu displays -> User selects "Show Picker" button -> Picker displays with all items. But once the picker displays, you can't scroll the options, nor does the "Done" button I've added register clicks. In fact text fields from the ViewController behind this popup can be clicked on through the popup.
I'm not sure why this UIPickerView is non interactive, does anyone have some thoughts?
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
// create a new window instance based on the screen size
window = new UIWindow(UIScreen.MainScreen.Bounds);
// instantiate the navigation controller
nav = new UINavigationController(new SplashController());
vwNav = new UIView(nav.NavigationBar.Bounds);
var pickerView = new UIPickerView(new CGRect(275f, (UIScreen.MainScreen.Bounds.Size.Height / 2) - (375f / 2), 275f, 375f));
pickerView.ShowSelectionIndicator = true;
var myPickerViewModel = new PickerViewModel(itemList);
pickerView.Model = myPickerViewModel;
myPickerViewModel.PickerChanged += (sender, e) => {
var temp = myPickerViewModel.SelectedItem;
};
// Set up toolbar
var toolbar = new UIToolbar();
toolbar.SizeToFit();
toolbar.Hidden = false;
UILabel titleLabel = new UILabel();
titleLabel.Text = "Select an Item";
titleLabel.Frame = new RectangleF(75, 13, 200, 20);
UIButton doneButton = new UIButton(UIButtonType.Custom);
doneButton.Frame = new RectangleF(40, 335, (float)200, 30);
doneButton.SetTitle("Done", UIControlState.Normal);
doneButton.TouchDown += (sender, e) =>
{
pickerView.Hidden = true;
};
toolbar.AddSubview(titleLabel);
toolbar.AddSubview(doneButton);
pickerView.AddSubview(toolbar);
pickerView.Hidden = true;
btnMenu = new UIButton(UIButtonType.Custom);
btnMenu.Frame = new CGRect(vwNav.Frame.Right - 45, 0, 45, nav.NavigationBar.Bounds.Height);
btnMenu.SetImage(imgMenu, UIControlState.Normal);
btnMenu.SetImage(imgMenu, UIControlState.Selected);
btnMenu.TouchUpInside += (object sender, EventArgs e) =>
{
UIAlertView alert = new UIAlertView();
alert.Title = "Settings";
alert.AddButton("Open PickerView");
alert.AddButton("Exit");
alert.Dismissed += delegate (object alertSender, UIButtonEventArgs args)
{
if (args.ButtonIndex == 0)
{
pickerView.Hidden = false;
}
else
return;
}
}
vwNav.AddSubviews(btnMenu, pickerView);
nav.NavigationBar.Layer.BorderWidth = 2f;
nav.NavigationBar.Layer.BorderColor = (UIColor.FromPatternImage(imgNavBar)).CGColor;
nav.NavigationBar.AddSubviews(vwNav);
// If you have defined a root view controller, set it here:
this.window.RootViewController = nav;
this.window.MakeKeyAndVisible();
return true;
}
I removed some of the unrelated code (a few nav.PushViewController() for different screens and other menu options) to keep it as clear as I could.
From your code, the frame of vwNav is nav.NavigationBar.Bounds, and the frame of pickerView is new CGRect(275f, (UIScreen.MainScreen.Bounds.Size.Height / 2) - (375f / 2), 275f, 375f), if you add pickView to vwNav, the pickerView is out of bounds of vwNav.
Remember that views don't receive touch events where they're outside the bounds of their superview.
That's the cause of your issue.
Solution:
I don't think you should built the UIPickerView in the AppDelegate.cs, create it in your ViewController instead.
You can also add buttons to Navigationbar in ViewController :
UIBarButtonItem btn = new UIBarButtonItem();
btn.Image = UIImage.FromFile("Image");
btn.Clicked += (sender, e) => { System.Diagnostics.Debug.WriteLine("show picker"); };
NavigationItem.RightBarButtonItem = btn;
And remember to add picker to the View of Viewcontroller.
Refer: uinavigationitem and add-uibarbuttonitem-to-navigation-bar-in-xamarin-ios
Feel free to ask me any question:).
Context: I want to achieve something similar with How can I mimic the bottom sheet from the Maps app? based on https://github.com/grendio/XBottomSheet/tree/master/XBottomSheet.Samples/XBottomSheet.Touch
Problem: If I use the BottomSheet with Google Maps for iOS View it does not let me to drag up or down the BottomSheet, even if it adds (it's visible on the screen).
Code: As already mentioned I have a Google Maps View and my BottomSheet View:
public override void ViewDidLoad()
{
base.ViewDidLoad();
SetMap();
SetBottomSheet();
}
private void SetMap()
{
var frame = new CGRect(0, View.Frame.GetMaxY(), View.Frame.Width, View.Frame.Height);
mapView = new MapView(View.Frame);
mapView.MyLocationEnabled = true;
mapView.BuildingsEnabled = false;
mapView.SetMinMaxZoom(15f, 18f);
View = mapView;
}
private void SetBottomSheet()
{
var bottom = UIScreen.MainScreen.Bounds.Height - UIApplication.SharedApplication.StatusBarFrame.Height;
bottomSheetViewController = new BottomSheetViewController(100, 300, bottom, true, BottomSheetState.Middle);
AddChildViewController(bottomSheetViewController);
View.AddSubview(bottomSheetViewController.View);
bottomSheetViewController.DidMoveToParentViewController(this);
bottomSheetViewController.View.Frame = new CGRect(0, View.Frame.GetMaxY(), View.Frame.Width, View.Frame.Height);
}
How can I wire these two views (mapView and bottomSheetViewController.View) in order to not lose the drag up/down feature from the BottomSheet control?
Even if the question is for Xamarin, an answer from swift or objective-c will do just fine as I will do the 'translation' afterwards.
I had a similar project, my solution at that time was to set the ConsumeGesturesInView property to false.
So your SetMap() method should look like this:
private void SetMap()
{
var frame = new CGRect(0, View.Frame.GetMaxY(), View.Frame.Width, View.Frame.Height);
mapView = new MapView(View.Frame);
mapView.MyLocationEnabled = true;
mapView.Settings.ConsumeGesturesInView = false;
mapView.BuildingsEnabled = false;
mapView.SetMinMaxZoom(15f, 18f);
View = mapView;
}
I'm using a UITabbarViewController in a relatively simple way. My issue only appears on iPad devices of iOS11 version. It's not visible on iOS10 or iPhone.
If you look at the screenshot, you can see that the background color of the tab is not aligned. Actually, it is aligned, it's the tabbar itself that is not taking the full width. So the background color is overlapping towards the central button because it's not using the space on the far left and far right.
I'm assuming that the tabbar is broken (and not my background colors, which are drawn manually) because the edges of the outsides tabs are not clickable, and yet the item positioning is set to be filling the width of the screen :
TabBar.ItemPositioning = UITabBarItemPositioning.Fill;
The items sizes are wrong if you consider the tabbar fullscreen, but they are if you consider the "reduced" version. So i'm pretty sure it's all good there, as long as the tabbar decides to take the full width of the screen, the buttons and background color will then have the correct measurements.
I've tried using View.LayoutIfNeeded() and SetNeedsLayout() to force a redraw, but to no avail.
I'm not sure why it's even behaving like so, and since it's the default behaviour of the OS and I haven't done anything particular, I'm not certain of what can even be tried.
Here's some relevant code :
MainTabbarController tabController = (MainTabbarController)Window.RootViewController;
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
ConfigureTabbar();
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
UIViewController[] tabs = //Create the VCs in the most basic way
SetViewControllers(tabs, false);
}
protected virtual void ConfigureTabbar()
{
TabBar.Translucent = false;
TabBar.ItemPositioning = UITabBarItemPositioning.Fill;
TabBar.ItemSpacing = 0;
//View.LayoutIfNeeded();
float tabbarItemWidth = (float)Math.Ceiling(View.Bounds.Width / TabBar.Items.Length) + 1; //+ 1 to avoid the right pixel that was not filled on the right tab. Strange behaviour...
TabBar.ItemWidth = tabbarItemWidth;
//var version = NSProcessInfo.ProcessInfo.OperatingSystemVersion;
NSOperatingSystemVersion ios11 = new NSOperatingSystemVersion(11, 0, 0);
if (NSProcessInfo.ProcessInfo.IsOperatingSystemAtLeastVersion(ios11))
{
if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad)
{
TabBar.SelectionIndicatorImage = _viewModel.Styles.Colors.ActiveTabColor.ToNative().ToImage(new CGRect(0, -View.SafeAreaInsets.Bottom, tabbarItemWidth, TabBar.Frame.Height));
}
else
{
TabBar.SelectionIndicatorImage = _viewModel.Styles.Colors.ActiveTabColor.ToNative().ToImage(new CGRect(0, -View.SafeAreaInsets.Bottom, tabbarItemWidth, TabBar.Frame.Height));
}
}
else
{
TabBar.SelectionIndicatorImage = _viewModel.Styles.Colors.ActiveTabColor.ToNative().ToImage(new CGSize(tabbarItemWidth, TabBar.Frame.Height));
}
UITextAttributes attrs = new UITextAttributes();
attrs.Font = _viewModel.Styles.Fonts.ExtraSmall.ToNative();
attrs.TextColor = _viewModel.Styles.Colors.ActionText.ToNative();
UITabBarItem.Appearance.SetTitleTextAttributes(attrs, UIControlState.Normal);
for (int i = 0; i < TabBar.Items.Length; i++)
{
UITabBarItem item = TabBar.Items[i];
item.Title = _viewModel.Titles[i];
item.TitlePositionAdjustment = new UIOffset(0, -4);
item.ImageInsets = new UIEdgeInsets(-2, 0, 2, 0);
}
//View.LayoutIfNeeded();
}
I want to implement a flyout navigation in Xamarin.iOS. For this purpose I am using the FlyoutNavigationController, which works good so far.
But now I have to display some additional content underneath the navigation list inside of the flyout-menu (basically an image, some labels and buttons). For this purpose, I wanted to use the FooterView property of the "section" control that holds the menu items.
When I set
section.Footer = "Test";
it will work (I can see the text), but when I use the 'FooterView' property, nothing shows up:
public class ViewController : UIViewController
{
FlyoutNavigationController navigation;
private const string PageNamePage1 = "The first page";
private const string PageNamePage2 = "The second page";
readonly string[] pages =
{
PageNamePage1,
PageNamePage2
};
public override void ViewDidLoad()
{
base.ViewDidLoad();
navigation = new FlyoutNavigationController
{
View =
{
Frame = UIScreen.MainScreen.Bounds
}
};
View.AddSubview(navigation.View);
var elements = pages.Select(page => new StringElement(page) as Element);
navigation.NavigationRoot = new RootElement("Induserv App");
var section = new Section();
section.AddAll(elements);
var uiTextView = new UITextView {Text = "--> This won't show!"};
section.FooterView = new UIView
{
uiTextView
};
navigation.NavigationRoot.Add(section);
navigation.ViewControllers = new UIViewController[]
{
new UINavigationController(new Page1Controller(navigation, PageNamePage1)),
new UINavigationController(new Page2Controller(navigation, PageNamePage2)),
};
}
}
Does anyone have an idea what it needs to display this footer here? Is there another way to put some controls in this panel?
Set a frame for both the footer view and uiTextView, like so:
var uiTextView = new UITextView(new RectangleF(0, 0, 10, 10)) {Text = "--> This won't show!"};
section.FooterView = new UIView(new RectangleF(0, 0, 10, 10))
{
uiTextView
};
in my App i have a Longpress Gesture on my TableCell. On Lonpress a Popover opens. The Popover inerhits a NavigationController.
Here is the code:
var navigationController = new UINavigationController();
//Page 1
var contPage1 = new UIViewController();
this._movePicker = new UIDatePicker();
var btnPage1 = new UIButton();
btnPage1.Frame = new RectangleF(0,260, 300,40);
contPage1.View.AddSubview(this._movePicker);
contPage1.View.AddSubview(btnPage1);
//Page 2
var contPage2 = new UIViewController();
var btnPage2 = new UIButton();
var textField = new UITextField();
textField.Frame = new RectangleF(0,35,300,150);
btnPage2.Frame = new RectangleF(0,260,300,40);
contPage2.View.AddSubview(btnPage2);
contPage2.View.AddSubview(textField);
// startPopover
this.PopoverController = new UIPopoverController(navigationController);
this.PopoverController.PopoverContentSize = new SizeF(300,340);
//Navigate on the first site
navigationController.PushViewController(contPage1, true);
btnPage1.TouchUpInside(s,e) => navigationController.PushViewController(contPage2, true);
this.PopoverController.PresentFromRect(locationinView, btn, UIPopoverDirection.Any, true);
Okay. This works fine. A popover appears. on the FirstView i click on the button and it navigates me to the second page. After that the keyboard appears and i can write something in the textField. If i close the keyboard the popover changes his size. It now takes the entire height of the iPadĀ“s display.
But why does it resize. I set the size of the Popover to 300, 400