IOS: UIDatePicker renders poorly with a black background - ipad

When I create a new UIDatePicker with its Mode set to a CountDownTimer, it renders poorly with a black background. Anyone have any insight?
Normal Picker looks like this:
CODE: Note the UIButton is a full screen button behind the picker to dismiss the view
intervalPicker = new UIDatePicker(new RectangleF(0, this.tvc.View.Bounds.Height - 135, this.tvc.View.Bounds.Width, 200));
intervalPicker.Mode = UIDatePickerMode.CountDownTimer;
intervalPicker.CountDownDuration = DeviceSession.CurrentBehavioralEvent.Duration*60;
intervalPicker.ValueChanged += new EventHandler(intervalPicker_EditingChanged);
UIButton b = UIButton.FromType(UIButtonType.Custom);
b.Opaque = false;
b.BackgroundColor = UIColor.Clear;
b.Frame = new RectangleF(0, 0, this.tvc.View.Bounds.Width, this.tvc.View.Bounds.Height);
b.TouchUpInside += (o, s) => {
intervalPicker.RemoveFromSuperview();
b.RemoveFromSuperview();
};
this.tvc.NavigationController.View.AddSubview(b);
this.tvc.NavigationController.View.AddSubview(intervalPicker);

The UIDatePicker in CountDownTimer mode displays this way when you set a frame height of less than 216. The other modes don't have this problem.
Your example is setting the height to 200.
Change the height to 216.

Related

How to render a UIButton in Xamarin.iOS

How do I render a UIButton in Xamarin.iOS? See the current Code for the full list.
This is the code I'm using to create and add the button to the Xamarin.Forms.Platform.iOS.CellTableViewCell cell. I cannot get the button to display anything.
With the use of a Foundation.NSMutableAttributedString, it shows a cut-off section of text in the top left corner, regardless of anything I try (alignments, insets, bounds, various constraints, etc). I'm currently trying things from Xamarin.Forms.Platform.iOS.Renderers.ButtonRenderer, but still can't get anything to display at all, no text, no button, or its outline.
If you could fork the repo and fix it or post the solution here, I would be very grateful.
protected override void SetUpContentView()
{
var insets = new UIEdgeInsets(SVConstants.Cell.PADDING.Top.ToNFloat(), SVConstants.Cell.PADDING.Left.ToNFloat(), SVConstants.Cell.PADDING.Bottom.ToNFloat(), SVConstants.Cell.PADDING.Right.ToNFloat());
_Button = new UIButton(UIButtonType.RoundedRect)
{
AutoresizingMask = UIViewAutoresizing.All,
HorizontalAlignment = UIControlContentHorizontalAlignment.Center,
VerticalAlignment = UIControlContentVerticalAlignment.Center,
ContentEdgeInsets = insets,
// TitleEdgeInsets = insets
};
DefaultFontSize = _Button.TitleLabel.ContentScaleFactor;
DefaultTextColor = _Button.TitleLabel.TextColor;
_Recognizer = new UILongPressGestureRecognizer(RunLong);
_Button.TouchUpInside += OnClick; // https://stackoverflow.com/a/51593238/9530917
_Button.AddGestureRecognizer(_Recognizer); // https://stackoverflow.com/a/6179591/9530917
ContentView.AddSubview(_Button);
_Button.CenterXAnchor.ConstraintEqualTo(ContentView.CenterXAnchor).Active = true;
_Button.CenterYAnchor.ConstraintEqualTo(ContentView.CenterYAnchor).Active = true;
_Button.WidthAnchor.ConstraintEqualTo(ContentView.WidthAnchor).Active = true;
_Button.HeightAnchor.ConstraintEqualTo(ContentView.HeightAnchor).Active = true;
UpdateConstraintsIfNeeded();
LayoutIfNeeded();
}
Found out that you can't subclass it. Any button added to the view must be native (UIButton) or custom rendered, such as Xamarin.Forms.Platform.iOS.ButtonRenderer; It doesn't show up otherwise.

Xamarin iOS display image and text in a UIButton

I am relatively new to iOS so go easy on me! In my app I need to have a button which contains an image a title. The image needs to go above the title. The image is defined dynamically from a base64 string.
My problem is I can’t work out how to display the title and the image in the button at the same time. I can display them individually but not together. I have tried following the approach in the below link but I have been unable to get it to work:
Display Button With Text & Image In Xamarin IOS
This is how the button needs to look:
In Xamarin iOS I am using the below code to set the image and lay out the controls in the button:
DeviceMenuItems m_menuItem = HHMenuContainer.Instance.GetMenuItems().DeviceMenuItems.SingleOrDefault(l => l.LineNo.ToString() == m_lineNo);
if (m_menuItem != null && m_menuItem.Base64Picture != null)
{
byte[] bytes = Convert.FromBase64String(m_menuItem.Base64Picture);
NSData data = NSData.FromArray(bytes);
UIImage uiimage = UIImage.LoadFromData(data);
//this line is not relevant to the problem
uiimage = ChangeImageBackground(uiimage);
if (uiimage != null)
{
//m_control is the UIButton
//commenting this out removes the image and shows the text
m_control.SetImage(uiimage, UIControlState.Normal);
float titleLabelHeight = (float)(m_control.TitleLabel.Frame.Size.Height + 10);
m_control.ImageEdgeInsets = new UIEdgeInsets(-(titleLabelHeight), 0, titleLabelHeight, 0 );
float imageHeight = (float)(m_control.ImageView.Frame.Size.Height * 0.5);
imageHeight -= titleLabelHeight;
m_control.TitleEdgeInsets = new UIEdgeInsets(imageHeight, 0, -(imageHeight), 0);
}
}
With the above code I get the following button (without the required text):
If I comment the ‘SetImage’ line out I get the following button:
Does anyone have any ideas why the above approach isn’t working?
From the shared link , it show left title and right image.If want up and down layout, you can try this:
button.TitleEdgeInsets = new UIEdgeInsets(0, -button.ImageView.Frame.Size.Width, -button.ImageView.Frame.Size.Height - 5,0);
button.ImageEdgeInsets = new UIEdgeInsets( -button.TitleLabel.Frame.Size.Height - 5, 0 , 0, -button.TitleLabel.Frame.Size.Width);
Note: If the button's frame is set and the width of the button is not enough to display the size of the image and text at the same time, the size of the titleLabel will get an error. So if you need to set the frame, it is recommended to set the width of the button to frame.size.width * 2, and then set the frame after the titleEdgeInsets and imageEdgeInsets are all set.

Tab bar not using full width on iOS11 iPad

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();
}

LeftBarButtonItem with UISearchBar is not visible on iOS 11

The title is pretty self explanatory, on iOS 10.3 using a UIBarButtonItem with a custom view (in this case UIStackView) assigned to a LeftBarButtonItem of a NavigationBar is not visible on iOS 11. I haven't figure out why it is not showed but when I type something with the keyboard my logic of the TextChanged event works! So the UISearchView is there but it is not visible:
Here is some code (It is coded with C# but it is using Objective C methods.):
var width = NavigationController.NavigationBar.Frame.Width;
var height = NavigationController.NavigationBar.Frame.Height;
_searchBarContainer = new UIStackView(new CGRect(0, 0, width * 0.75, height))
{
Alignment = UIStackViewAlignment.Center,
Axis = UILayoutConstraintAxis.Horizontal,
Spacing = 3
};
_uiSearchBar = new UISearchBar
{
BackgroundColor = UIColor.Clear,
BarTintColor = UIColor.Clear,
BackgroundImage = new UIImage(),
Placeholder = Strings.Search
};
_uiSearchBar.SizeToFit();
if (_iOS11)
{
_uiSearchBar.HeightAnchor.ConstraintEqualTo(44).Active = true;
}
_searchbarButtonItem = new UIBarButtonItem(_searchBarContainer);
NavigationItem.SetLeftBarButtonItem(_searchbarButtonItem, true);
ParentViewController.NavigationItem.LeftBarButtonItem = NavigationItem.LeftBarButtonItem;
Using the same code on iOS 10 this works.
Please try out setting up constraints to size properly your _searchBarContainer before setting it as the left bar button item. From iOS11 navigations bars use auto layout. Make sure you only add the constraints if iOS 11 is present, I was having problems in iOS 9 navigation bars otherwise.
Also checkout this thread in the Dev forum where it's explained how the bar items are wrapped inside stack views, maybe also helps with your particular issue.

How to show overlay screen over tabBar?

In main.lua I create tabBar with three buttons and three screens (screen1, screen2, screen3)
In screen1 I would like to show modal overlay
local options = {
effect = "fromBottom",
time = 400,
isModal = true,
}
storyboard.showOverlay( "get", options )
Everything works, but I would like to show the overlay over tabBar (like modal view in xCode).
How can I do it?
In one case I should "goto" screen3 from screen1
storyboard.gotoScene( "screen3")
It's works, but selected tabButton is still tabButton1 (with screen1)
How to select tabButton programmatically?
Here is the code of creating tabBar in main.lua:
-- Create buttons table for the tab bar
local tabButtons = {
{
width = 32, height = 32,
defaultFile = "assets/tabIcon.png", overFile = "assets/tabIcon-down.png",
label = translations["tab1"][language],
onPress = function() storyboard.gotoScene( "screen1" ); end,
selected = true
},
{
width = 32, height = 32,
defaultFile = "assets/tabIcon.png", overFile = "assets/tabIcon-down.png",
label = translations["tab2"][language],
onPress = function() storyboard.gotoScene( "screen2" ); end,
},
{
width = 32, height = 32,
defaultFile = "assets/tabIcon.png", overFile = "assets/tabIcon-down.png",
label = translations["tab3"][language],
onPress = function() storyboard.gotoScene( "screen3" ); end,
}
}
--Create a tab-bar and place it at the bottom of the screen
local tabBar = widget.newTabBar {
top = display.contentHeight - 50,
height = 50,
width = display.contentWidth,
--backgroundFile = "assets/tabbar.png",
tabSelectedFrameWidth = 1,
tabSelectedFrameHeight = 49,
buttons = tabButtons
}
storyboard.gotoScene( "screen1", "crossFade", 200 )
I don't think you can show any image over the tab bar since it's a native object. The only way I could see it possibly working is by inserting the image and tabBar into a 2 groups. Then making the one display.newGroup() over the other one. I don't even think that will work though, but give it a shot.
Actually in Corona's case, if you are using widget.newTabBar(), they are Corona display objects. I think the issue you are running into is that storyboard objects live below any objects that are not being managed by storyboard.
Because your tabBar is typically not managed by storyboard it will sit on top of any storyboard scene, including overlays. To make this work the way you want, you would probably need to create a scene (call it menu.lua or tabbar.lua) that creates the tabBar in it's createScene function and make sure to add the tabBar to the scene's view. Now that scene is being managed by storyboard and your overlay can now cover it.

Resources