C# Xamarin Label Padding for iOS app - c#

I know this question has been asked a lot but I've tried the various solutions and can't seem to find one that works. I have a label on my storyboard titled Messages. On button click, different text appears in the label. I need to pad just this label.
I've looked at:
Adding space/padding to a UILabel,
UILabel text margin,
and Resizing a UILabel to accommodate insets.
Also not sure where in my ViewController.cs to put the code. I put it under public partial class ViewController : UIViewController but get errors.
Edit 2:
Okay, at first I did a UITextView but couldn't get vertical align to work so went back to label. This is what I have:
public partial class ViewController : UIViewController
{
public partial class PaddedUILabel : UILabel
{
private UIEdgeInsets EdgeInsets { get; set; }
public PaddedUILabel()
{
EdgeInsets = new UIEdgeInsets(0, 10, 0, 10);
}
public override void DrawText(CoreGraphics.CGRect rect)
{
base.DrawText(EdgeInsets.InsetRect(rect));
}
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
Message.Layer.BorderWidth = 1;
Message.BackgroundColor = UIColor.FromWhiteAlpha(1, 0.88f);
PaddedUILabel _paddedUILabel = Message as PaddedUILabel;
I'm still not getting any padding.

You can either use a UITextView and provide the insets directly (as mentioned in this link) which you can do either in ViewDidLoad or ViewWillAppear, or you can subclass your UILabel and override the DrawText method.
The DrawText method helps manipulate the rectangle in which the text within a label is drawn. I'd suggest you pay around with some values to get started with it.
Something like:
public partial class PaddedUILabel : UILabel
{
//Override draw text here
}
If you are using Xamarin iOS Native, give your label(for example: myLabel) the custom class from story board and retrieve the label as:
PaddedUILabel _paddedUILabel = this.myLabel as PaddedUILabel;
I'm sorry I would have given you the whole code but as of now, don't have access to a Mac environment. Let me know if you need anything else.
For vertical align in TextView follow link.
Cheers

i tried many solutions as discussed here but the actual out coming not what i wanted so i made it like that :
if (this.Padding != default(Thickness))
{
Device.BeginInvokeOnMainThread(() =>
{
if (Parent is Grid)
{
var parentAsGrid = Parent as Grid;
var index = parentAsGrid.Children.IndexOf(this);
parentAsGrid.Children.Remove(this);
Grid marginGrid = new Grid() { BackgroundColor = this.BackgroundColor, HorizontalOptions = this.HorizontalOptions, VerticalOptions = this.VerticalOptions };
var lbl = new Label() { Text = this.Text, TextColor = this.TextColor, BackgroundColor = this.BackgroundColor, HorizontalOptions = this.HorizontalOptions, VerticalOptions = this.VerticalOptions, FontSize = this.FontSize };
lbl.Margin = this.Padding;
if (!parentAsGrid.Children.Contains(this))
{
marginGrid.Children.Add(lbl);
parentAsGrid.Children.Insert(index, marginGrid);
}
}
if (Parent is StackLayout)
{
var parentAsGrid = Parent as StackLayout;
var index = parentAsGrid.Children.IndexOf(this);
parentAsGrid.Children.Remove(this);
Grid marginGrid = new Grid() { BackgroundColor = this.BackgroundColor, HorizontalOptions = this.HorizontalOptions, VerticalOptions = this.VerticalOptions };
var lbl = new Label() { Text = this.Text, TextColor = this.TextColor, BackgroundColor = this.BackgroundColor, HorizontalOptions = this.HorizontalOptions, VerticalOptions = this.VerticalOptions, FontSize = this.FontSize };
lbl.Margin = this.Padding;
if (!parentAsGrid.Children.Contains(this))
{
marginGrid.Children.Add(lbl);
parentAsGrid.Children.Insert(index, marginGrid);
}
}
});

Related

Horizontal alignment for ListView items

I have the page:
public partial class MenuPage : ContentPage
{
public MenuPage ()
{
StackLayout menu = new StackLayout { };
menu.Children.Add(new ListView
{
HorizontalOptions = LayoutOptions.Center,
ItemsSource = new string[]
{
"Settings",
"About"
}
});
Content = menu;
}
}
I'm trying to align by center the content of ListView items (with HorizontalOptions = LayoutOptions.Center), but the option has no effect (whatever values I set for HorizontalOptions - I will reach alignment just to the left side). How to center the contents of cells correctly?
As Jason said , you need to set the HorizontalOptions of each items in ListView . It is easier to define it in xaml .If you do want to implement it in code behind , you could check the following code .
You could define a custom cell
public CustomCell()
{
//instantiate each of our views
StackLayout horizontalLayout = new StackLayout() {
HorizontalOptions=LayoutOptions.CenterAndExpand,
VerticalOptions = LayoutOptions.CenterAndExpand
};
Label Content = new Label();
//set bindings
Content.SetBinding(Label.TextProperty, ".");
Content.HorizontalOptions = LayoutOptions.CenterAndExpand;
Content.TextColor = Color.Red;
horizontalLayout.Children.Add(Content);
View = horizontalLayout;
}
StackLayout menu = new StackLayout { };
var listview = new ListView
{
ItemsSource = new string[]
{
"Settings",
"About"
}
};
listview.ItemTemplate = new DataTemplate(typeof(CustomCell));
menu.Children.Add(listview);
Content = menu;

Custom button not rendering correctly

I've got a custom class for a button with a circular image as I'll be using it multiple times through my program. I thought it'd be pretty simple of creating class, inheriting from Button and slapping my setup into a constructor, but when I'm running the program the buttons are massive and plain (no image or text). Here's my class:
public class ImageButton : Button
{
public Button Button;
public ImageButton(string filename) : this(HorizontalAlignment.Center, VerticalAlignment.Center, filename)
{ }
public ImageButton(HorizontalAlignment hAlignment, VerticalAlignment vAlignment, string filename)
{
Button = new Button
{
Width = 35,
Height = 35,
Background = Brushes.Transparent,
HorizontalAlignment = hAlignment,
BorderBrush = Brushes.Transparent,
VerticalAlignment = vAlignment,
Content = new Image
{
Source = new BitmapImage(new Uri("pack://application:,,,/Resources/" + filename))
}
};
}
}
And here's my implementation of one of the instances
private void SetupHeaders(Grid resultGrid)
{
RowDefinition backbtn = new RowDefinition();
backbtn.Height = new GridLength(0.2, GridUnitType.Star);
resultGrid.RowDefinitions.Add(backbtn);
btn_Return = new ImageButton(HorizontalAlignment.Left, VerticalAlignment.Top, "returnicon.png");
Grid.SetRow(btn_Return, 0);
Grid.SetColumn(btn_Return, 0);
resultGrid.Children.Add(btn_Return);
}
with btn_Return being defined at the top of the class as simply
ImageButton btn_Return;
Here's an image of one of the buttons.
In you constructor you inititalize a Button with you properties and then assign it to a property. You never actually use the initialized button. You are always using ImageButton which is nothing more than an inherited button therefore you get the default behavior.
You have to change your constructor.
public ImageButton(HorizontalAlignment hAlignment, VerticalAlignment vAlignment, string filename)
{
Width = 35;
Height = 35;
Background = Brushes.Transparent;
HorizontalAlignment = hAlignment;
BorderBrush = Brushes.Transparent;
VerticalAlignment = vAlignment;
Content = new Image
{
Source = new BitmapImage(new Uri("pack://application:,,,/Resources/" + filename))
};
}

Collision detection Xamarin.Forms

I'm trying to detect a collision between two Xamarin. Forms Controls (BoxViews), but I can't find a way to do it. I have a button that what it does is to decrease the TranslationY of a BoxView until it collides with the other BoxView. I remember that with WinForms this could be done with IntersectsWith, but apparently here does not work, I currently have this:
public class Main : ContentPage
{
public BoxView pjOne = new BoxView { BackgroundColor = Color.Red, HeightRequest = 100, WidthRequest = 100, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.StartAndExpand };
public BoxView pjTwo = new BoxView { BackgroundColor = Color.Green, HeightRequest = 100, WidthRequest = 100, HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.CenterAndExpand };
public Button btnDown = new Button { HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.End, Text = "Down", TextColor = Color.White };
public Main()
{
btnDown.Clicked += (s, e) =>
{
if(!pjOne.Bounds.IntersectsWith(pjTwo.Bounds))
{
pjOne.TranslationY -= 100; //If it does not detect collision it decreases the TranslationY
}
else
{
pjOne.TranslationY += 100; //If it detects collision it increases the TranslationY
}
};
Content = new StackLayout
{
Children =
{
pjOne,
pjTwo,
btnDown
}
};
}
}
But this doesn't work, it never detects the collision between the two BoxView.
Bounds do not get updated when a Translation is applied.
From the docs:
Bounds is assigned during the Layout cycle by a call to Layout(Rectangle).
I would try
calling Layout with the new location you want to translate the BoxView to
create a rectangle for pjOne and pjTwo. Then you could use the Xamarin.Forms.Rectangle.IntercectsWith method.
Here is an untested example of how to do this:
var pjRectOne = new Rectangle(pjOne.X + pjOne.TranslationX, pjOne.Y + pjOne.TranslationY, pjOne.Width, pjOne.Height);
var pjRectTwo = new Rectangle(pjTwo.X + pjTwo.TranslationX, pjTwo.Y + pjTwo.TranslationY, pjTwo.Width, pjTwo.Height);
if (pjRectOne.IntercectsWith(pjRectTwo))
{
}
Note: if pjOne or pjTwo are children of a view, their X and Y positions will be relative to the parent. To get the absolute X and Y, loop through all their parents by doing something like this
var y = pjOne.Y;
var parent = pjOne.ParentView;
while (parent != null)
{
y += parent.Y;
parent = parent.ParentView;
}
Hope this helped you out :)

how to create custom popup window in Xamarin.Form

In Xamarin.Forms I need to create a popup window that shows login page in popup window.
here is my code using xlab popup control.
MainPage l = new MainPage();
Navigation.PushModalAsync(l);
PopupLayout popupLayout = new PopupLayout();
popupLayout.Content = l.Content;
ShowPopup(l);
MainPage extends ContentPage and currently its working fine for login screen, but my requirement is to show it as a popup. Can anyone please help on this? Or is there any other way to do this ?
Here is how you do it
private async void ShowPopup()
{
//Create `ContentPage` with padding and transparent background
ContentPage loginPage = new ContentPage
{
BackgroundColor = Color.FromHex("#D9000000"),
Padding = new Thickness(20, 20, 20, 20)
};
// Create Children
//Create desired layout to be a content of your popup page.
var contentLayout = new StackLayout
{
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
Orientation = StackOrientation.Vertical,
Children =
{
// Add children
}
};
//set popup page content:
loginPage.Content = contentLayout;
//Show Popup
await Navigation.PushModalAsync(loginPage, false);
}
#misho thanks for your help
here is my final working code. But it can't be called popup window. This can just fulfill my purpose.
private async void ShowPopup()
{
ContentPage detailsPage = new ContentPage
{
BackgroundColor = Color.Transparent,// Color.FromHex("#00F0F8FF"),
Padding = new Thickness(40, 40, 40, 40)
};
MainPage l = new MainPage();
detailsPage.Content = l.Content;
Button b = l.FindByName<Button>("btnClose");
b.Clicked += ((o2, e2) =>
{
this.Navigation.PopModalAsync();
});
await Navigation.PushModalAsync(detailsPage, false);
}
Hi #Misho here is actual screen shot op popup screen.

mvvmcross binding UILabel

I am trying to bind ULabel to a Command in a core but can't figure out why it is not working for me. I read that UILabel is bindable to a default Text property so I have the following simple tester to demonstrate:
in Touch code I have the following ViewDidLoad:
var tipLabel = new UILabel(new RectangleF(10, 20, 300, 40));
Add(tipLabel);
var loginBtn = new UIButton(UIButtonType.RoundedRect) { Frame = new RectangleF(10, 100, 100, 40) };
loginBtn.SetTitle("Set Text", UIControlState.Normal);
var tap = new UITapGestureRecognizer(() =>
{
tipLabel.Text = DateTime.Now.ToShortTimeString();
});
loginBtn.AddGestureRecognizer(tap);
Add(loginBtn);
var set = this.CreateBindingSet<FirstView, FirstViewModel>();
set.Bind(tipLabel).For(p=>p.Text).To(vm=>vm.TestCommand);
set.Apply();
and in a core:
private MvxCommand _testCommand;
public ICommand TestCommand
{
get { return this._testCommand ?? (this._testCommand = new MvxCommand(this.Test)); }
}
public void Test()
{
}
what am I missing?
Thank you
Mark
You are effectively binding the Text property to a command. This won't work. I would use a UIButton and adjust its properties so it looks like a label then bind to its click event to change the button label.

Categories

Resources