我的iOS渲染器上有一个Draw
问题,我有一个自定义控件。这个控制(让我们称之为GradientFrame
)在ContentView
内部与IsVisible = false
。现在问题在于控件的初始化,我的渲染器上的Draw
方法没有被调用。
以下是我注意到的一些关键点,这是我的假设:
Draw
方法中放置一个断点,但它从未停止过。StackLayout
的IsVisible = true
时它按预期工作并调用Draw
方法,这在断点处停止。我的iOS渲染器:
class GradientFrameRenderer : FrameRenderer {
...
public override void Draw(CGRect rect) {
base.Draw(rect);
if (Element is GradientFrame control) {
CAGradientLayer gradientLayer = new CAGradientLayer() {
Frame = rect,
// i left the other stuffs out to minimize this post.
};
Layer.InsertSublayerBelow(gradientLayer, Layer.Sublayers.LastOrDefault());
Layer.MasksToBounds = true;
}
}
...
}
在我的.xaml页面中:
<ContentView IsVisible="false"
Opacity="0">
<Stacklayout Scale="0">
<custom:GradientFrame <!-- my style properties goes in here. again left out to minimize this post --> />
</StackLayout>
</ContentView>
你可能想知道,在我的.xaml上,ContentView
有Opacity="0"
而StackLayout
有Scale="0"
。这些用于后面的代码中的动画。
期望:
现实:
注意:顶部框架具有与Expectation图像中相同的样式属性,但底部框架没有任何样式属性,并且它原样。
我改变了渲染GradientFrame
的方法,改为使用this方法。所以我的渲染现在看起来像这样:
class GradientFrameRenderer : FrameRenderer {
public override CGRect Frame {
get => base.Frame;
set {
if(value.Width > 0 && value.Height > 0) {
foreach(var layer in Layer.Sublayers.Where(layer => layer is CAGradientLayer)) {
layer.Frame = new CGRect(0, 0, value.Width, value.Height);
}
}
base.Frame = value;
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) {
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == GradientFrame.StartColorProperty.PropertyName ||
e.PropertyName == GradientFrame.EndColorProperty.PropertyName ||
e.PropertyName == GradientFrame.DirectionProperty.PropertyName) {
UpdateLayer();
}
}
void UpdateLayer() {
if (Element is GradientFrame control) {
CAGradientLayer gradientLayer = new CAGradientLayer() {
// i left the other stuffs out to minimize this post.
};
Layer.InsertSublayerBelow(gradientLayer, Layer.Sublayers.LastOrDefault());
Layer.MasksToBounds = true;
}
}
}
所以现在不是使用Draw
方法来渲染控件,而是每次调用OnElementPropertyChanged
时(当属性发生变化时)都会执行渲染过程。然后我覆盖了我的渲染器的Frame
来更新我添加的图层的Frame
。