using System; using System.ComponentModel; using RectangleF = CoreGraphics.CGRect; using SizeF = CoreGraphics.CGSize; #if __MOBILE__ using UIKit; using NativeLabel = UIKit.UILabel; namespace Xamarin.Forms.Platform.iOS #else using AppKit; using NativeLabel = AppKit.NSTextField; namespace Xamarin.Forms.Platform.MacOS #endif { public class LabelRenderer : ViewRenderer { SizeRequest _perfectSize; bool _perfectSizeValid; public override SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint) { if (!_perfectSizeValid) { _perfectSize = base.GetDesiredSize(double.PositiveInfinity, double.PositiveInfinity); _perfectSize.Minimum = new Size(Math.Min(10, _perfectSize.Request.Width), _perfectSize.Request.Height); _perfectSizeValid = true; } var widthFits = widthConstraint >= _perfectSize.Request.Width; var heightFits = heightConstraint >= _perfectSize.Request.Height; if (widthFits && heightFits) return _perfectSize; var result = base.GetDesiredSize(widthConstraint, heightConstraint); var tinyWidth = Math.Min(10, result.Request.Width); result.Minimum = new Size(tinyWidth, result.Request.Height); if (widthFits || Element.LineBreakMode == LineBreakMode.NoWrap) return result; bool containerIsNotInfinitelyWide = !double.IsInfinity(widthConstraint); if (containerIsNotInfinitelyWide) { bool textCouldHaveWrapped = Element.LineBreakMode == LineBreakMode.WordWrap || Element.LineBreakMode == LineBreakMode.CharacterWrap; bool textExceedsContainer = result.Request.Width > widthConstraint; if (textExceedsContainer || textCouldHaveWrapped) { var expandedWidth = Math.Max(tinyWidth, widthConstraint); result.Request = new Size(expandedWidth, result.Request.Height); } } return result; } #if __MOBILE__ public override void LayoutSubviews() { base.LayoutSubviews(); #else public override void Layout() { base.Layout(); #endif if (Control == null) return; SizeF fitSize; nfloat labelHeight; switch (Element.VerticalTextAlignment) { case TextAlignment.Start: fitSize = Control.SizeThatFits(Element.Bounds.Size.ToSizeF()); labelHeight = (nfloat)Math.Min(Bounds.Height, fitSize.Height); Control.Frame = new RectangleF(0, 0, (nfloat)Element.Width, labelHeight); break; case TextAlignment.Center: Control.Frame = new RectangleF(0, 0, (nfloat)Element.Width, (nfloat)Element.Height); break; case TextAlignment.End: nfloat yOffset = 0; fitSize = Control.SizeThatFits(Element.Bounds.Size.ToSizeF()); labelHeight = (nfloat)Math.Min(Bounds.Height, fitSize.Height); yOffset = (nfloat)(Element.Height - labelHeight); Control.Frame = new RectangleF(0, yOffset, (nfloat)Element.Width, labelHeight); break; } } protected override void OnElementChanged(ElementChangedEventArgs