I created a collectionview acting like a barchart diagram. For the bar display in the center of the screen, I am showing the current value for that center item. Everything works fine so far, but to be able to scroll the first or last item in the chart, to the center of the screen, i have to add padding to the beginning and end of the collection.
This chart is a migration of an old xamarin.forms app, where the padding was handle by a customerender and worked fine.
The issue i am currently seeing, is that when the collectionview´s ItemsLayout is
ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal)
the handler that i made, doesn't set the padding.
But if the
ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical)
it works fine.
I tried different approach with handlers
Microsoft.Maui.Controls.Handlers.Items.CollectionViewHandler.Mapper[nameof(IView)] = (h, v) =>
{
if (v is CollectionViewChart)
{
#if ANDROID
(h.PlatformView as Android.Views.View).SetPadding(375,0,375,0);
var recycleView = h.PlatformView;
recycleView.SetClipToPadding(false);
recycleView.SetPadding(375, 0, 375, 0);
#endif
}
#if IOS
h.PlatformView.SemanticContentAttribute = UISemanticContentAttribute.ForceRightToLeft;
((UICollectionView)h.PlatformView.Subviews[0]).CollectionViewLayout.CollectionView.ContentInset = new UIEdgeInsets(0, 375, 0, (float)375);
((UICollectionView)h.PlatformView.Subviews[0]).CollectionViewLayout.CollectionView.ContentOffset = new CoreGraphics.CGPoint(0, 0);
#endif
};
or like handlers that looks more like the old customrenders that i have from the xamarin.forms project, like this.
public partial class CollectionViewChartHandler : CollectionViewHandler
{
protected override void ConnectHandler(RecyclerView platformView)
{
platformView.RootView.SetPadding(375, 375, 375, 375);
platformView.SetClipToPadding(false);
platformView.SetPadding(375, 375, 375, 375);
base.ConnectHandler(platformView);
}
}
and for iOS
public partial class CollectionViewChartHandler : CollectionViewHandler
{
protected override void ConnectHandler(UIView platformView)
{
base.ConnectHandler(platformView);
platformView.SemanticContentAttribute = UISemanticContentAttribute.ForceRightToLeft;
(((UICollectionView)platformView.Subviews[0]).CollectionViewLayout.CollectionView).ContentInset = new UIEdgeInsets(0, 375, 0, (float)375);
((UICollectionView)platformView.Subviews[0]).CollectionViewLayout.CollectionView.ContentOffset = new CoreGraphics.CGPoint(0, 0);
}
}
But none seems to work, when the itemslayout of the collectionView is set to Horizontal, but works fine if the itemslayout is set to Vertical
Any idea why?
Related
How do I get the width of an Entry view in Xamarin.Forms? I'm trying to make an entry in iOS look like the default entry in Android (the one with the line underneath).
Custom Renderer:
void SetBorderWidth(Controls.Entry control)
{
Control.BorderStyle = UITextBorderStyle.None;
var myBox = new UIView(new CGRect(0, 40, <INSERT WIDTH HERE>, 1));
myBox.BackgroundColor = control.BorderColor.ToUIColor();
Control.AddSubview(myBox);
}
Whenever I try to insert either control.Width, control.WidthRequest, control.MinimumWidthRequest nothing happens. But if I put a number the line underneath suddenly shows.
Additionally when I print out the width and widthrequest they have a value of -1.
In your iOS Entry renderer, override the Draw method and use the CGRect provided as the current Frame size of the UITextField, since this method can be called multiple times (screen rotations, resizes, etc... Save your UIView after its initial creation and just update its Frame.
Something like (I do not have my personal code with me, but this should be "close"):
UIView myBox;
public override void Draw(CGRect rect)
{
base.Draw(rect);
switch (myBox)
{
case null:
myBox = new UIView(new CGRect(0, 40, rect.Width, 1));
Control.AddSubview(myBox);
break;
default:
myBox.Frame = new CGRect(0, 40, rect.Width, 1);
break;
}
}
I'm trying to dynamically draw lines by using the package SkiaSharp.
I've defined the control in my xaml like this:
<skia:SKCanvasView x:Name="CanvasView" PaintSurface="OnCanvasViewPaintSurface" />
This is my code behind class:
private SkiaSharp.SKCanvas canvas;
private SkiaSharp.SKSurface surface;
void OnCanvasViewPaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs args)
{
SkiaSharp.SKImageInfo info = args.Info;
surface = args.Surface;
canvas = surface.Canvas;
canvas.Clear();
SkiaSharp.SKPaint thinLinePaint = new SkiaSharp.SKPaint
{
Style = SkiaSharp.SKPaintStyle.Stroke,
Color = SkiaSharp.SKColors.Blue,
StrokeWidth = 6
};
canvas.DrawLine(0, 0, 50, 50, thinLinePaint);
}
The part above works fine, and a blue line will be drawn when loading the view at startup. But what I want to do is to dynamically draw new lines and remove the old ones.
public void DrawNewLine()
{
canvas.Clear();
SkiaSharp.SKPaint thickLinePaint = new SkiaSharp.SKPaint
{
Style = SkiaSharp.SKPaintStyle.Stroke,
Color = SkiaSharp.SKColors.Red,
StrokeWidth = 16
};
canvas.DrawLine(0, 0, 50, 50, thickLinePaint);
}
I am using the canvas field that was declared before, but it's not working. Application will crash at runtime when using the canvas object.
What am I doing wrong?
You need to use SKCanvasView.InvalidateSurface() method to recall OnCanvasViewPaintSurface() internally.
I'm trying to style the UINavigationBar in Xamarin with MonoTouch. In the constructor of the UIViewController I tried the following:
//this.NavigationController.NavigationBar.TintColor = UIColor.Magenta;
UINavigationBar.Appearance.TintColor = UIColor.Yellow;
But if I try to run this in the simulator there is nothing changed. Where should I place this code? How do I use a RGB color (with UIColor.FromRGB (0, 127, 14)?) Is my code correct?
My Solution:
//AppDelegate.cs
public partial class AppDelegate : UIApplicationDelegate
{
// class-level declarations
UIWindow window;
public static UIStoryboard Storyboard = UIStoryboard.FromName ("MainStoryboard", null);
public static UIViewController initialViewController;
// ...
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
window = new UIWindow (UIScreen.MainScreen.Bounds);
initialViewController = Storyboard.InstantiateInitialViewController () as UIViewController;
UINavigationBar.Appearance.SetTitleTextAttributes (
new UITextAttributes () { TextColor = UIColor.FromRGB (0, 127, 14) });
window.RootViewController = initialViewController;
window.MakeKeyAndVisible ();
return true;
}
}
Assuming that you're developing for iOS7 you need to set BarTintColor.
UINavigationBar.Appearance.BarTintColor = UIColor.Red;
UINavigationBar.Appearance.BarTintColor = UIColor.FromRGB(0, 127, 14);
see: How to change UINavigationBar background color from the AppDelegate
Put this code in AppDelegate.cs
Try this ..
NSDictionary *textTitleOptions = [NSDictionary dictionaryWithObjectsAndKeys:[UIColor darkGrayColor], UITextAttributeTextColor, [UIColor whiteColor], UITextAttributeTextShadowColor, nil];
[[UINavigationBar appearance] setTitleTextAttributes:textTitleOptions];
Or you can refer more from
IOS 7 Navigation Bar text and arrow color
You should specific the UIViewController, like:
viewController.navigationBar.tintColor = [UIColor yellowColor];
or in UIViewController:
self.navigationBar.tintColor = [UIColor yellowColor];
I have implemented signaturepad for my ios application. (Its not a native application. I am developing using MVVMCROSS platform. I wish to set the orientation of this signature pad in landscape view always. I am unable to find any parameters for the signaturepad frame.
var signature = new SignaturePadView(View.Frame);
View.AddSubview(signature);
signature.Frame = new RectangleF(0, 135, 320, 130);
//signature.Frame = new RectangleF(0, 135, this.View.Frame.Width, 140);
signature.BackgroundColor = UIColor.Gray;
I am not able to make sure that it always opens in landscape view and adjusts to the width of the screen. Would be glad if you anyone could help
Try adding following code to your ViewController of SignaturePadView
public override bool ShouldAutorotate()
{
return true;
}
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
{
return UIInterfaceOrientationMask.AllButUpsideDown;
}
It overrides orientation methods
I am trying to create a custom UIButton which extends from UIButtonType.RoundedRect.
My added functionality is working, but there is an issue with the initial rounded border state of my button. The border of my extended button is not drawn until after it has been tapped.
Update (January 24th 2013): Added the result of red background test, as requested by Richard Marskell, which concludes only the label of the button is drawn. BackgroundColor = UIColor.Red;
Below is my source code for creating my custom button.
public class TestView : UIView
{
public TestView(IntPtr p) : base(p) { }
public TestView(RectangleF bounds)
{
Frame = bounds;
BackgroundColor = UIColor.White;
UIButton button1 = new UIButton(UIButtonType.RoundedRect);
button1.Frame = new RectangleF(20,20,100,50);
button1.SetTitle("Button 1", UIControlState.Normal);
AddSubview(button1); // Drawn Correctly
MyButton button2 = new MyButton();
button2.Frame = new RectangleF(20,90,100,50);
button2.SetTitle("Button 2", UIControlState.Normal);
AddSubview(button2); // Only drawn correctly after Tap
// EDIT: Added to test Miguel's theory
UIButton button3 = UIButton.FromType(UIButtonType.RoundedRect);
button3.Frame = new RectangleF(20,160,100,50);
button3.SetTitle("Button 3", UIControlState.Normal);
AddSubview(button3); // Drawn Correctly
}
}
public class MyButton : UIButton
{
public MyButton() : base(UIButtonType.RoundedRect) { }
}
I'm just not sure how to force the border to be drawn correctly on loading of the view.
I don't need a button of type UIButtonType.Custom, as I don't want to style the button myself.
When I debug I the type of MyButton is correctly set to UIButtonType.RoundedRect.
The UIButton base properties of MyButton (button2) match the properties of the UIButton instance (button1).
How can I resolve this issue?
Update (January 31st 2013): Herman Schoenfeld provided a suitable solution for this bug.
This works
public class MyButton : UIButton
{
public MyButton() : base(UIButtonType.RoundedRect) { }
public override RectangleF Frame {
get {
return base.Frame;
}
set {
var temp = TranslatesAutoresizingMaskIntoConstraints;
TranslatesAutoresizingMaskIntoConstraints = false;
var constraints = new [] {
NSLayoutConstraint.Create(this, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1.0f, value.Width),
NSLayoutConstraint.Create(this, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1.0f, value.Height)
};
AddConstraints(constraints);
SizeToFit();
RemoveConstraints(constraints);
base.Frame = value;
TranslatesAutoresizingMaskIntoConstraints = temp;
}
}
}
This is only a workaround, it appears to be a bug. The SizeToFit() fixes the issue, the other code maintains the frame.