UITableView Interfering with Status Bar in Xamarin.iOS - ios

I have created Slide Menu in Xamarin.iOS with below library https://github.com/thedillonb/MonoTouch.SlideoutNavigation
SplashViewController.cs
window = new UIWindow(UIScreen.MainScreen.Bounds);
Menu = new SlideoutNavigationController();
var storyboard = UIStoryboard.FromName("Main", null);
var webController = storyboard.InstantiateViewController("HomeViewController") as HomeViewController;
Menu.MainViewController = new MainNavigationController(webController, Menu);
Menu.MenuViewController = new MenuNavigationController(new DummyControllerLeft(), Menu) { NavigationBarHidden = true };
window.RootViewController = Menu;
window.MakeKeyAndVisible();
DummyControllerLeft.cs
public override void ViewDidLoad()
{
base.ViewDidLoad();
TableView.Frame = new RectangleF((float)TableView.Frame.Left, 30, (float)TableView.Frame.Width, (float)(View.Frame.Size.Height - 30));
headerView = new UIView();
headerView.Frame = new CoreGraphics.CGRect(0, 0, TableView.Frame.Width, 140);
profileImage = new UIImageView();
profileImage.Frame = new CoreGraphics.CGRect(10, 10, 70, 70);
profileImage.Layer.CornerRadius = 35;
profileImage.ClipsToBounds = true;
profileImage.Image = UIImage.FromBundle("gargi_logo.png");
userName = new UILabel();
userName.Frame = new CoreGraphics.CGRect(10, 90, TableView.Frame.Width - 20, 20);
userName.Font = GargiFontAndSize.B14();
userName.TextColor = UIColor.White;
headerView.AddSubview(userName);
userRole = new UILabel();
userRole.Frame = new CoreGraphics.CGRect(10, 110, TableView.Frame.Width - 20, 20);
userRole.Font = GargiFontAndSize.B14();
userRole.TextColor = UIColor.White;
headerView.AddSubview(userRole);
headerView.AddSubview(profileImage);
TableView.TableHeaderView = headerView;
TableView.ContentInset = new UIEdgeInsets(20, 0, 0, 0);
GetUserItemData();
SetSidePanel();
}
Its working fine.
Screen 1:
but when i scroll it is Interfering with Status Bar see below image.
Screen 2:
I have tried almost all solution or workaround but nothing is help to me. few of them are below.
Tried 1 :
TableView.ContentInset = new UIEdgeInsets(20, 0, 0, 0);
Tried 2 :
TableView.ScrollRectToVisible(new CGRect(0, 0, 1, 1), true);
Tried 3 :
EdgesForExtendedLayout = UIRectEdge.None;
ExtendedLayoutIncludesOpaqueBars = false;
AutomaticallyAdjustsScrollViewInsets = false;
I tried to solve this problem for last 6 hour but nothing is Help for me.
Any Help will be Appreciated.

If all of your menus 'rows' are in a single section, you could change your 'TableHeaderView' to a 'SectionHeader' that would remain in place whilst the section scrolls and should in theory solve your problem.
I think you will likely need to create a source delegate class for your tableview to do this though because the property isn't exposed for the tableview by itself, so you'd need to do something like this:
Assign it to your table view:
yoursource source = new yoursource();
TableView.Source = source;
Create the delegate class:
using CoreGraphics;
using Foundation;
using System;
using UIKit;
namespace somenamespace
{
class yoursource : UITableViewSource
{
public ThreadTableSource(UITableView table, List<ConversationThread> Threads)
{
}
public override UIView GetViewForHeader(UITableView tableView, nint section)
{
headerView = new UIView();
headerView.Frame = new CoreGraphics.CGRect(0, 0, tableView.Frame.Width, 140);
profileImage = new UIImageView();
profileImage.Frame = new CoreGraphics.CGRect(10, 10, 70, 70);
profileImage.Layer.CornerRadius = 35;
profileImage.ClipsToBounds = true;
profileImage.Image = UIImage.FromBundle("gargi_logo.png");
userName = new UILabel();
userName.Frame = new CoreGraphics.CGRect(10, 90, tableView.Frame.Width - 20, 20);
userName.Font = GargiFontAndSize.B14();
userName.TextColor = UIColor.White;
headerView.AddSubview(userName);
userRole = new UILabel();
userRole.Frame = new CoreGraphics.CGRect(10, 110, tableView.Frame.Width - 20, 20);
userRole.Font = GargiFontAndSize.B14();
userRole.TextColor = UIColor.White;
headerView.AddSubview(userRole);
headerView.AddSubview(profileImage);
return headerView;
}
}
}
Link to section header xamarin guide.

Related

Xamarin iOS adding Custom back button

I want to customise back-button so i can prompt user with confirmation box.
For that i have removed default navigation back button by setting its hidden property to 'True'
and i am adding new left bar button item.
But UI for the left bar button is not same as it is for default back button.
please find attached screenshot.
Please find below code for Left bar button added-
UIImage image = UIImage.FromBundle("BackButton"); UIButton customButton = new UIButton(UIButtonType.Custom);
customButton.SetImage(image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate),
UIControlState.Normal); customButton.Frame = new CGRect(0, 0,
100, 44); customButton.ImageEdgeInsets = new UIEdgeInsets(0,
-40, 0, -40); this.NavigationItem.SetHidesBackButton(true, false); var backButton = new
UIBarButtonItem(customButton);
this.NavigationItem.LeftBarButtonItem = backButton;
Thanks in advance !
You would better scale the image before you set the background image.
UIImage image = UIImage.FromBundle("BackButton").ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
UIImage newImg = ScalingImageToSize(image, new CGSize(30, 30)).ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
UIButton customButton = new UIButton(UIButtonType.Custom);
customButton.SetImage(newImg.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal), UIControlState.Normal);
customButton.Frame = new CGRect(0, 0, 50, 50);
customButton.ImageEdgeInsets = new UIEdgeInsets(0, -40, 0, -40);
NavigationController.NavigationBar.BackIndicatorImage = newImg;
NavigationController.NavigationBar.BackIndicatorTransitionMaskImage = newImg;
UIBarButtonItem buttonItem = new UIBarButtonItem(customButton);
NavigationItem.BackBarButtonItem = buttonItem;
public UIImage ScalingImageToSize(UIImage sourceImage, CGSize newSize)
{
if (UIScreen.MainScreen.Scale == 2.0) //#2x iPhone 6 7 8
{
UIGraphics.BeginImageContextWithOptions(newSize, false, 2.0f);
}
else if (UIScreen.MainScreen.Scale == 3.0) //#3x iPhone 6p 7p 8p...
{
UIGraphics.BeginImageContextWithOptions(newSize, false, 3.0f);
}
else
{
UIGraphics.BeginImageContext(newSize);
}
sourceImage.Draw(new CGRect(0, 0, newSize.Width, newSize.Height));
UIImage newImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return newImage;
}
Option 2
You can create a custom navigationBar as you want .
public class xxxViewController: UIViewController
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
NavigationController.NavigationBar.Hidden = true;
double height = IsiphoneX();
UIView backView = new UIView()
{
BackgroundColor = UIColor.White,
Frame = new CGRect(0,20,UIScreen.MainScreen.Bounds.Width, height),
};
// set
UIButton backBtn = new UIButton() {
Frame = new CGRect(20, height-44, 40, 44),
Font = UIFont.SystemFontOfSize(18),
} ;
UIImage image = UIImage.FromBundle("BackButton");
UIImage newImg = ScalingImageToSize(image, new CGSize(30, 30));
backBtn.SetBackgroundImage(newImg.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate), UIControlState.Normal);
backBtn.AddTarget(this,new Selector("GoBack"),UIControlEvent.TouchUpInside);
UILabel titleLabel = new UILabel() {
Frame=new CGRect(UIScreen.MainScreen.Bounds.Width/2-75, 0,150, height),
Font = UIFont.SystemFontOfSize(20),
Text = "xxx",
TextColor = UIColor.Black,
Lines = 0,
};
UILabel line = new UILabel() {
Frame = new CGRect(0, height, UIScreen.MainScreen.Bounds.Width, 0.5),
BackgroundColor = UIColor.Black,
};
backView.AddSubview(backBtn);
backView.AddSubview(titleLabel);
backView.AddSubview(line);
View.AddSubview(backView);
}
double IsiphoneX()
{
double height = 44;
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
{
if (UIApplication.SharedApplication.Delegate.GetWindow().SafeAreaInsets.Bottom > 0.0)
{
height = 64;
}
}
return height;
}
[Export("GoBack")]
void GoBack()
{
NavigationController.PopViewController(true);
}
public override void ViewWillDisappear(bool animated)
{
base.ViewWillDisappear(animated);
NavigationController.NavigationBar.Hidden = false;
}
}
You can set the property of title , backButton and navigationBar as you need (such as text , color ,BackgroundColor ,font e.g.)

Xamarin iOS UINavigationBar weird overlay

I am working in Xamarin 4.5 with iOS 13. I am using Simulator to run the code. Here's how it looks.
I have added the following code to apply red color but its not hiding this white/grey overlay.
UIApplication.SharedApplication.StatusBarStyle = UIStatusBarStyle.LightContent;
UINavigationBar.Appearance.BarTintColor = UIColor.Red;
UINavigationBar.Appearance.TintColor = UIColor.Red;
UINavigationBar.Appearance.TitleTextAttributes = new UIStringAttributes
{
ForegroundColor = UIColor.Red
};
UINavigationBar.Appearance.BackgroundColor = UIColor.FromRGBA(255, 0, 0, 255);
Last line added the Red color.
It will be an expected effect because UINavigationBar has a default CALayer after iOS 11.0. As a workaround , we could create a custom NavigationBar by using custom renderer
in your iOS project
using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using xxx;
using xxx.iOS;
using CoreGraphics;
using ObjCRuntime;
[assembly:ExportRenderer(typeof(ContentPage),typeof(MyPageRenderer))]
namespace xxx.iOS
{
public class MyPageRenderer:PageRenderer
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
NavigationController.NavigationBar.Hidden = true;
double height = IsiphoneX();
UIView backView = new UIView()
{
BackgroundColor = UIColor.Red,
Frame = new CGRect(0, 20, UIScreen.MainScreen.Bounds.Width, height),
};
// set
UIButton backBtn = new UIButton()
{
Frame = new CGRect(20, height - 44, 40, 44),
Font = UIFont.SystemFontOfSize(18),
};
backBtn.SetTitle("<",UIControlState.Normal);
backBtn.SetTitleColor(UIColor.White,UIControlState.Normal);
backBtn.AddTarget(this, new Selector("GoBack"), UIControlEvent.TouchUpInside);
UILabel titleLabel = new UILabel()
{
Frame = new CGRect(UIScreen.MainScreen.Bounds.Width / 2 - 75, 0, 150, height),
Font = UIFont.SystemFontOfSize(20),
Text = "xxx",
TextColor = UIColor.White,
Lines = 0,
};
UILabel line = new UILabel()
{
Frame = new CGRect(0, height, UIScreen.MainScreen.Bounds.Width, 0.5),
BackgroundColor = UIColor.Black,
};
if (NavigationController.ViewControllers.Length > 1)
{
backView.AddSubview(backBtn);
}
backView.AddSubview(titleLabel);
backView.AddSubview(line);
View.AddSubview(backView);
}
double IsiphoneX()
{
double height = 44;
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
{
if (UIApplication.SharedApplication.Delegate.GetWindow().SafeAreaInsets.Bottom > 0.0)
{
height = 64;
}
}
return height;
}
[Export("GoBack")]
void GoBack()
{
NavigationController.PopViewController(true);
}
public override void ViewWillDisappear(bool animated)
{
base.ViewWillDisappear(animated);
NavigationController.NavigationBar.Hidden = false;
}
}
}
You can set the property of title , backButton and navigationBar as you need (such as text , color ,BackgroundColor ,font e.g.)

Button Click inside TableView Header is ignore in iOS

I am making TableView with the custom Header. in the custom header I have 1 ImageView, 2 UILabel and 1 UIButton. When i set TouchUpInSide event on the UIButton it will not fire.
I see many post on the SO and google but nothing is getting help me.
Here What i have tried :
1). Swift - Custom TableView Not Executing Click on UIButton
2). UIButton in UITableView tableHeaderView not responding to touches
3). UIButton in a UITableView header ignores most touches
Here is my code for Custom header.
Code :
public override void ViewDidLoad()
{
base.ViewDidLoad();
TableView.Frame = new RectangleF((float)TableView.Frame.Left, 130, (float)TableView.Frame.Width, (float)(View.Frame.Size.Height - 130));
headerView = new UIView();
headerView.Frame = new CoreGraphics.CGRect(0, 0, TableView.Frame.Width, 140);
UIImageView backgroundImage = new UIImageView();
backgroundImage.Image = UIImage.FromFile("drawerbg");
backgroundImage.Frame = new CoreGraphics.CGRect(0, 0, TableView.Frame.Width, 140);
headerView.AddSubview(backgroundImage);
profileImage = new UIImageView();
profileImage.Frame = new CoreGraphics.CGRect(10, 10, 70, 70);
profileImage.Layer.CornerRadius = 35;
profileImage.ClipsToBounds = true;
profileImage.Image = UIImage.FromBundle("default_user");
backgroundImage.AddSubview(profileImage);
userName = new UILabel();
userName.Frame = new CoreGraphics.CGRect(10, 90, TableView.Frame.Width - 20, 20);
userName.Font = GargiFontAndSize.B14();
userName.TextColor = UIColor.White;
backgroundImage.AddSubview(userName);
userOrganization = new UILabel();
userOrganization.Frame = new CoreGraphics.CGRect(10, 110, TableView.Frame.Width - 50, 20);
userOrganization.Font = GargiFontAndSize.B14();
userOrganization.TextColor = UIColor.White;
userOrganization.Text = "Organizaton";
backgroundImage.AddSubview(userOrganization);
organizationArrowButton = new UIButton();
organizationArrowButton.Frame = new CoreGraphics.CGRect(260, 110, 20, 20);
organizationArrowButton.SetImage(UIImage.FromBundle("sort_down"), UIControlState.Normal);
organizationArrowButton.UserInteractionEnabled = true;
organizationArrowButton.ClipsToBounds = false;
backgroundImage.AddSubview(organizationArrowButton);
organizationArrowButton.BringSubviewToFront(headerView);
TableView.SectionHeaderHeight = 0;
TableView.SectionFooterHeight = 0;
var gradient = new CAGradientLayer();
gradient.Frame = headerView.Frame;
gradient.Colors = new CoreGraphics.CGColor[] { GargiColor.PrimaryColor().CGColor, GargiColor.SecondaryColor().CGColor };
headerView.Layer.InsertSublayer(gradient, 0);
TableView.TableHeaderView = headerView;
}
One more thing My viewController is extend DialogViewController.
Any Help will be Appreciated..
UIImageView's userInteraction is disabled by default, and you are adding button to image view, set userInteractionEnabled to true for UIImageView.

Customize Custom Cell further

I have the following class that generate custom cell. It works very well. However, I have a condition where I need to get more space for my InfoLabel than it is defined below. I could not able to handle it?
public WeinerGeneralCellItem (NSString cellId, Short Weiner) : base (UITableViewCellStyle.Default, cellId)
{
this.Weiner = Weiner;
weinerInfoLabel = new UILabel () {
TextColor = UIColor.FromRGB (0, 0, 0),
BackgroundColor = UIColor.Clear,
TextAlignment = UITextAlignment.Left,
};
weinerInfo = new UITextField () {
TextColor = UIColor.FromRGB (0, 0, 0),
TextAlignment = UITextAlignment.Right,
BackgroundColor = UIColor.Clear,
};
ContentView.Add (weinerInfoLabel);
ContentView.Add (weinerInfo);
}
public override void LayoutSubviews ()
{
base.LayoutSubviews ();
weinerInfoLabel.Frame = new CGRect(20, ContentView.Bounds.Height/4, 200, 25);
weinerInfo.Frame = new CGRect(220, ContentView.Bounds.Height/4, 300, 25);
}
}
By default infolabel width is 200, info is 300, but for the last cell, I want infoLabel width is 350, info is 150. I have tried the following but it did not work.
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
if (indexPath.Row == 5) {
cell.weinerInfoLabel.Frame = new CGRect(20, 20, 350, 25);
cell.weinerInfo.Frame = new CGRect(350, 20, 150, 25);
cell.weinerInfoLabel.Text = "The value calculated from the server";
cell.weinerInfo.Tag = 5;
cell.weinerInfo.Text = "155.00";
}
}
Here is the solution that I have ended up, it is working. I am just checking tag id before setting up the frame for that corresponding cell.
public override void LayoutSubviews ()
{
base.LayoutSubviews ();
if (weinerInfo.Tag == 5)
{
weinerInfoLabel.Frame = new CGRect (20, ContentView.Bounds.Height / 4, 350, 25);
weinerInfo.Frame = new CGRect (350, ContentView.Bounds.Height / 4, 170, 25);
}
else
{
weinerInfoLabel.Frame = new CGRect(20, ContentView.Bounds.Height/4, 200, 25);
weinerInfo.Frame = new CGRect (220, ContentView.Bounds.Height / 4, 300, 25);
}
}

How to change SeparatorColor of Selected Item in a UITableView

I've got the following UITableView
_navigationList = new UITableView
{
Source = UINavigationTableViewSource,
BackgroundColor = UIColor.FromRGB(43, 43, 43), // #2b2b2b - same as Android
SeparatorColor = UIColor.FromRGB(27,27,27), // #1b1b1b - same as Android
SeparatorInset = UIEdgeInsets.Zero,
ScrollEnabled = true
};
The UINavigationTableViewSource is using a custom UITableViewCell
public sealed class UINavigationTableViewCell : UITableViewCell
{
public new readonly UILabel TextLabel;
public UINavigationTableViewCell(string cellId)
: base(UITableViewCellStyle.Default, cellId)
{
TextLabel = new UILabel(new RectangleF(10, 0, Bounds.Width, 40)) {TextColor = UIColor.White}; // properly position the label.
SeparatorInset = UIEdgeInsets.Zero; // make the boarder go all the way across the list item
ContentView.BackgroundColor = UIColor.FromRGB(43, 43, 43); // #2b2b2b - same as Android
var activeOrb = new UIImageView(new RectangleF(0,0,10,Bounds.Height))
{
Image = UIImage.FromBundle("Images/active_orb.png"),
ContentMode = UIViewContentMode.ScaleAspectFit
};
SelectedBackgroundView = new UIView { BackgroundColor = UIColor.FromRGB(43, 43, 43) };
SelectedBackgroundView.Add(activeOrb);
ContentView.Add(TextLabel);
}
}
Everything is looking the way we want except for the ugly white line on a selected row.
How do I change the SeparatorColor when a row is selected?
I had never programmed in xamarin, but i worked on ios(5-7) sdk.
I would suggest you to dont use any seperators.Instead add the seperator line as view(height-1pixel;width-cellWidth) to your cell.
edit by ChaseFlorell - working example
_navigationList = new UITableView
{
Source = UINavigationTableViewSource,
BackgroundColor = UIColor.FromRGB(43, 43, 43), // #2b2b2b - same as Android
SeparatorStyle = UITableViewCellSeparatorStyle.None,
ScrollEnabled = true
};
Add(_navigationList);
public sealed class UINavigationTableViewCell : UITableViewCell
{
public new readonly UILabel TextLabel;
public UINavigationTableViewCell(string cellId) : base(UITableViewCellStyle.Default, cellId)
{
// The default state
TextLabel = new UILabel(new RectangleF(10, 0, Bounds.Width, 40)) { TextColor = UIColor.White }; // properly position the label.
ContentView.BackgroundColor = UIColor.FromRGB(43, 43, 43); // #2b2b2b - same as Android
ContentView.Add(Separator(Bounds));
ContentView.Add(TextLabel);
// todo: move colors to a config file.
// The selected state
var activeOrb = new UIImageView(new RectangleF(0, 0, 10, Bounds.Height))
{
Image = UIImage.FromBundle("Images/active_orb.png"),
ContentMode = UIViewContentMode.ScaleAspectFit
};
SelectedBackgroundView = new UIView { BackgroundColor = UIColor.FromRGB(43, 43, 43) };
SelectedBackgroundView.Add(Separator(Bounds));
SelectedBackgroundView.Add(activeOrb);
}
private static UIView Separator(RectangleF bounds)
{
return new UIView(new RectangleF(0, 0, bounds.Width, 1))
{
BackgroundColor = UIColor.FromRGB(27, 27, 27)
};
}
}

Resources