* [Controls] Add repo for issue #6368 and #6328 * [iOS] Protect against no Element from CustomRenderers bad usage * [Controls] Drop private on sample code
This commit is contained in:
Родитель
216a6333f1
Коммит
7712162fb7
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
using UIKit;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.ControlGallery.iOS;
|
||||
using Xamarin.Forms.Platform.iOS;
|
||||
using static Xamarin.Forms.Controls.Issues.Issue6368;
|
||||
|
||||
[assembly: ExportRenderer(typeof(CustomView), typeof(CustomRenderer))]
|
||||
namespace Xamarin.Forms.ControlGallery.iOS
|
||||
{
|
||||
public class CustomRenderer : ViewRenderer<CustomView, UIView>
|
||||
{
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<CustomView> e)
|
||||
{
|
||||
base.OnElementChanged(e);
|
||||
|
||||
//
|
||||
// --- Important --- //
|
||||
//
|
||||
// This is a WRONG Pattern!
|
||||
//Pattern taken from: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/view
|
||||
if (this.Control == null)
|
||||
{
|
||||
// Instantiate the native control and assign it to the Control property with
|
||||
// the SetNativeControl method
|
||||
UIView myView = new UIView();
|
||||
this.SetNativeControl(myView);
|
||||
}
|
||||
|
||||
if (e.OldElement != null)
|
||||
{
|
||||
// Unsubscribe from event handlers and cleanup any resources
|
||||
}
|
||||
|
||||
if (e.NewElement != null)
|
||||
{
|
||||
// Configure the control and subscribe to event handlers
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using UIKit;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.ControlGallery.iOS.CustomRenderers;
|
||||
using Xamarin.Forms.Platform.iOS;
|
||||
using static Xamarin.Forms.Controls.Issues.Issue6368;
|
||||
|
||||
[assembly: ExportRenderer(typeof(RoundedLabel), typeof(RoundedLabelRenderer))]
|
||||
namespace Xamarin.Forms.ControlGallery.iOS.CustomRenderers
|
||||
{
|
||||
public class RoundedLabelRenderer : LabelRenderer
|
||||
{
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
|
||||
{
|
||||
if (Control == null)
|
||||
{
|
||||
SetNativeControl(new TagUiLabel());
|
||||
}
|
||||
base.OnElementChanged(e);
|
||||
if (e.NewElement != null)
|
||||
{
|
||||
this.Layer.CornerRadius = 10;
|
||||
this.Layer.BorderColor = ColorExtensions.ToCGColor(ColorExtensions.ToColor(UIColor.FromRGB(3, 169, 244)));
|
||||
this.Layer.BackgroundColor = ColorExtensions.ToCGColor(Color.GhostWhite);
|
||||
this.Layer.BorderWidth = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TagUiLabel : UILabel
|
||||
{
|
||||
UIEdgeInsets _edgeInsets = new UIEdgeInsets(10, 5, 10, 5);
|
||||
UIEdgeInsets _inverseEdgeInsets = new UIEdgeInsets(-10, -5, -10, -5);
|
||||
|
||||
public override CoreGraphics.CGRect TextRectForBounds(CoreGraphics.CGRect bounds, nint numberOfLines)
|
||||
{
|
||||
var textRect = base.TextRectForBounds(_edgeInsets.InsetRect(bounds), numberOfLines);
|
||||
return _inverseEdgeInsets.InsetRect(textRect);
|
||||
}
|
||||
public override void DrawText(CoreGraphics.CGRect rect)
|
||||
{
|
||||
base.DrawText(_edgeInsets.InsetRect(rect));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -117,6 +117,8 @@
|
|||
<Compile Include="CustomRenderers.cs" />
|
||||
<Compile Include="CustomRendererBugzila38731.cs" />
|
||||
<Compile Include="CustomApplication.cs" />
|
||||
<Compile Include="CustomRenderers\CustomRenderer.cs" />
|
||||
<Compile Include="CustomRenderers\RoundedLabelRenderer.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Xamarin.Forms.Controls\Xamarin.Forms.Controls.csproj">
|
||||
|
@ -386,6 +388,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Resources\Fonts\" />
|
||||
<Folder Include="CustomRenderers\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,67 @@
|
|||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
#if UITEST
|
||||
using Xamarin.Forms.Core.UITests;
|
||||
using Xamarin.UITest;
|
||||
using NUnit.Framework;
|
||||
#endif
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
|
||||
#if UITEST
|
||||
[Category(UITestCategories.CustomRenderers)]
|
||||
#endif
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Github, 6368, "[CustomRenderer]Crash when navigating back from page with custom renderer control", PlatformAffected.iOS)]
|
||||
public class Issue6368 : TestNavigationPage
|
||||
{
|
||||
public class CustomView : View
|
||||
{
|
||||
}
|
||||
|
||||
public class RoundedLabel : Label
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
var rootPage = new ContentPage();
|
||||
var button = new Button()
|
||||
{
|
||||
AutomationId = "btnGo",
|
||||
Text = "Click me to go to the next page",
|
||||
Command = new Command(() => PushAsync(new ContentPage()
|
||||
{
|
||||
Content = GetContent()
|
||||
}))
|
||||
};
|
||||
var content = GetContent();
|
||||
content.Children.Add(button);
|
||||
rootPage.Content = content;
|
||||
PushAsync(rootPage);
|
||||
}
|
||||
|
||||
static StackLayout GetContent()
|
||||
{
|
||||
var content2 = new StackLayout();
|
||||
content2.Children.Add(new RoundedLabel { Text = "Go to next Page" });
|
||||
content2.Children.Add(new RoundedLabel { Text = "then navigate back" });
|
||||
content2.Children.Add(new RoundedLabel { Text = "If test doesn't crash it passed" });
|
||||
content2.Children.Add(new CustomView());
|
||||
return content2;
|
||||
}
|
||||
|
||||
#if UITEST && __IOS__
|
||||
[Test]
|
||||
public void Issue6368Test()
|
||||
{
|
||||
RunningApp.WaitForElement (q => q.Marked ("btnGo"));
|
||||
RunningApp.Tap(q => q.Marked("btnGo"));
|
||||
RunningApp.WaitForElement(q => q.Marked("Go to next Page"));
|
||||
RunningApp.NavigateBack();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -897,6 +897,7 @@
|
|||
<DependentUpon>Issue4356.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue5888.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue6368.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">
|
||||
|
|
|
@ -47,5 +47,7 @@
|
|||
public const string Performance = "Performance";
|
||||
public const string Visual = "Visual";
|
||||
public const string AppLinks = "AppLinks";
|
||||
public const string Shell = "Shell";
|
||||
public const string CustomRenderers = "CustomRenderers";
|
||||
}
|
||||
}
|
|
@ -40,7 +40,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
event EventHandler _controlChanging;
|
||||
event EventHandler _controlChanged;
|
||||
|
||||
|
||||
bool IsElementOrControlEmpty => Element == null || Control == null;
|
||||
|
||||
protected virtual TNativeView CreateNativeControl()
|
||||
{
|
||||
|
@ -188,7 +188,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
protected override void SetBackgroundColor(Color color)
|
||||
{
|
||||
if (Control == null)
|
||||
if (IsElementOrControlEmpty)
|
||||
return;
|
||||
#if __MOBILE__
|
||||
if (color == Color.Default)
|
||||
|
@ -217,8 +217,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
#endif
|
||||
Control = uiview;
|
||||
|
||||
if (Element.BackgroundColor != Color.Default)
|
||||
SetBackgroundColor(Element.BackgroundColor);
|
||||
UpdateBackgroundColor();
|
||||
|
||||
UpdateIsEnabled();
|
||||
|
||||
|
@ -236,9 +235,18 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
}
|
||||
#endif
|
||||
|
||||
void UpdateBackgroundColor()
|
||||
{
|
||||
if (IsElementOrControlEmpty)
|
||||
return;
|
||||
|
||||
if (Element.BackgroundColor != Color.Default)
|
||||
SetBackgroundColor(Element.BackgroundColor);
|
||||
}
|
||||
|
||||
void UpdateIsEnabled()
|
||||
{
|
||||
if (Element == null || Control == null)
|
||||
if (IsElementOrControlEmpty)
|
||||
return;
|
||||
|
||||
var uiControl = Control as NativeControl;
|
||||
|
@ -249,6 +257,9 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
if (IsElementOrControlEmpty)
|
||||
return;
|
||||
|
||||
Control.UpdateFlowDirection(Element);
|
||||
}
|
||||
|
||||
|
@ -260,4 +271,4 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
focusRequestArgs.Result = focusRequestArgs.Focus ? Control.BecomeFirstResponder() : Control.ResignFirstResponder();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче