/// <summary> /// Gets the size of the desired. /// </summary> /// <returns>The desired size.</returns> /// <param name="widthConstraint">Width constraint.</param> /// <param name="heightConstraint">Height constraint.</param> public override SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint) { if (widthConstraint < 0 || heightConstraint < 0 || _currentDrawState == null || _currentDrawState.IsBlank || Control == null || Element == null) { return(new SizeRequest(Size.Zero)); } //_currentMeasureState?.Dispose(); _currentMeasureState = new TextControlState(_currentDrawState) { AvailWidth = widthConstraint, AvailHeight = heightConstraint }; if (_currentMeasureState == _lastMeasureState && _lastMeasureResult.HasValue) { return(_lastMeasureResult.Value); } _lastMeasureResult = InternalLayout(MeasureControl, _currentMeasureState); //_lastMeasureState?.Dispose(); _lastMeasureState = new TextControlState(_currentMeasureState); return(_lastMeasureResult.Value); }
protected override void OnElementChanged(ElementChangedEventArgs <Label> e) { if (e.OldElement != null) { e.OldElement.RendererIndexAtPoint -= IndexAtPoint; e.OldElement.RendererSizeForWidthAndFontSize -= LabelF9PSize; e.OldElement.Draw -= DrawLabel; } if (e.NewElement != null) { _currentDrawState = new TextControlState(); if (Control == null) { var view = new UILabel(CGRect.Empty) { BackgroundColor = UIColor.Clear }; _defaultTextColor = view.TextColor; SetNativeControl(view); } UpdateTextColor(); UpdateFont(); UpdateHorizontalAlignment(); UpdateLineBreakMode(); UpdateStrings(); e.NewElement.RendererIndexAtPoint += IndexAtPoint; e.NewElement.RendererSizeForWidthAndFontSize += LabelF9PSize; e.NewElement.Draw += DrawLabel; } base.OnElementChanged(e); }
public static void PropertiesFromControlState(this UILabel label, TextControlState state) { if (state.AttributedString != null) { label.AttributedText = state.AttributedString; } else { label.Text = state.Text; } label.Font = state.Font; label.TextAlignment = state.HorizontalTextAlignment; label.LineBreakMode = state.LineBreakMode; }
SizeRequest DrawLabel(double width, double height) { if (width >= 0 && height >= 0 && !_currentDrawState.IsBlank && Control is UILabel control && Element != null) { _currentDrawState.AvailWidth = width; _currentDrawState.AvailHeight = height; if (_currentDrawState == _lastDrawState && _lastDrawResult.HasValue) { return(_lastDrawResult.Value); } _lastDrawResult = InternalLayout(control, _currentDrawState); _lastDrawState = new TextControlState(_currentDrawState); return(_lastDrawResult.Value); } return(new SizeRequest(Xamarin.Forms.Size.Zero)); }
SizeRequest InternalLayout(UILabel control, TextControlState state) { if (Element is Forms9Patch.Label element) { var tmpFontSize = BoundTextSize(element.FontSize); if (tmpFontSize < 0) { System.Diagnostics.Debug.WriteLine(GetType() + "." + P42.Utils.ReflectionExtensions.CallerMemberName() + ": [" + null + "]"); } control.PropertiesFromControlState(state); control.Lines = 0; if (element.Lines == 0) { if (state.AvailHeight < int.MaxValue / 3) { tmpFontSize = ZeroLinesFit(control, state.AvailWidth, state.AvailHeight, tmpFontSize); } } else { if (element.AutoFit == AutoFit.Lines) { if (state.AvailHeight < int.MaxValue / 3) { var font = control.Font = UIFont.FromDescriptor(_currentDrawState.FontDescriptor, tmpFontSize); var lineHeightRatio = font.LineHeight / font.PointSize; var tmpLineSize = (nfloat)(state.AvailHeight - 0.05f) / element.Lines; tmpFontSize = tmpLineSize / lineHeightRatio; } } else if (element.AutoFit == AutoFit.Width) { tmpFontSize = WidthFit(control, state.AvailWidth, tmpFontSize); } } tmpFontSize = BoundFontSize(tmpFontSize); if (tmpFontSize < 0) { System.Diagnostics.Debug.WriteLine(GetType() + "." + P42.Utils.ReflectionExtensions.CallerMemberName() + ": [" + null + "]"); } if (Math.Abs(tmpFontSize - element.FittedFontSize) > 0.1) { if (element != null && control != null) // multipicker test was getting here with Element and control both null { if (System.Math.Abs(tmpFontSize - element.FontSize) < 0.1 || (element.FontSize < 0 && System.Math.Abs(tmpFontSize - UIFont.LabelFontSize) < 0.1)) { element.FittedFontSize = -1; } else { element.FittedFontSize = tmpFontSize; } } } var syncFontSize = (nfloat)((ILabel)element).SynchronizedFontSize; if (syncFontSize >= 0 && System.Math.Abs(tmpFontSize - syncFontSize) > 0.1) { tmpFontSize = syncFontSize; } state.FontPointSize = tmpFontSize; control.Font = state.Font; control.Lines = 0; control.AdjustsFontSizeToFitWidth = false; control.ClearsContextBeforeDrawing = true; control.ContentMode = UIViewContentMode.Redraw; CGSize cgSize = LabelSize(control, state.AvailWidth, tmpFontSize); control.Lines = state.Lines; double reqWidth = cgSize.Width; double reqHeight = cgSize.Height + 0.05; var textHeight = cgSize.Height; var textLines = Lines(textHeight, control.Font); if (double.IsPositiveInfinity(state.AvailHeight)) { if (element.Lines > 0) { if (element.AutoFit == AutoFit.Lines) { reqHeight = element.Lines * control.Font.LineHeight; } else if (element.AutoFit == AutoFit.None && element.Lines <= textLines) { reqHeight = element.Lines * control.Font.LineHeight; } } control.Center = new CGPoint(control.Center.X, reqHeight / 2); } else { var constraintLines = Lines(state.AvailHeight, control.Font); var constraintLinesHeight = Math.Floor(constraintLines) * control.Font.LineHeight; if (element.Lines > 0 && element.Lines <= Math.Min(textLines, constraintLines)) { reqHeight = element.Lines * control.Font.LineHeight; } else if (textLines <= constraintLines) { reqHeight = textHeight; } else if (constraintLines >= 1) { reqHeight = constraintLinesHeight; } else { reqHeight = state.AvailHeight; } if (element.VerticalTextAlignment == TextAlignment.Start) { control.Center = new CGPoint(control.Center.X, reqHeight / 2); } else if (element.VerticalTextAlignment == TextAlignment.End) { control.Center = new CGPoint(control.Center.X, state.AvailHeight - reqHeight / 2); } } SizeRequest result; //if (UIDevice.CurrentDevice.CheckSystemVersion(11, 3)) result = new SizeRequest(new Size(Math.Ceiling(reqWidth), Math.Ceiling(reqHeight)), new Size(10, Math.Ceiling(state.Font.LineHeight))); //else // result = new SizeRequest(new Size(Math.Ceiling(reqWidth * 1.25), Math.Ceiling(reqHeight * 1.25)), new Size(10, Math.Ceiling(state.Font.LineHeight))); return(result); } return(new SizeRequest(Size.Zero)); }