C# 我们是否能够将Xamain.iOS自定义控件转换为Xamarin.Forms自定义控件?如果是,那怎么办?
我需要在导航栏右侧显示徽章通知图标 我在我的原生Xamari.iOS项目中使用了下面的代码,但现在我希望它在Xamarin.Forms中用作自定义控件 有人能帮我在Xamarin.Forms中为iOS和Android创建这种自定义控件类型的渲染器吗C# 我们是否能够将Xamain.iOS自定义控件转换为Xamarin.Forms自定义控件?如果是,那怎么办?,c#,xamarin,xamarin.ios,xamarin.android,xamarin.forms,C#,Xamarin,Xamarin.ios,Xamarin.android,Xamarin.forms,我需要在导航栏右侧显示徽章通知图标 我在我的原生Xamari.iOS项目中使用了下面的代码,但现在我希望它在Xamarin.Forms中用作自定义控件 有人能帮我在Xamarin.Forms中为iOS和Android创建这种自定义控件类型的渲染器吗 using System; using UIKit; using CoreGraphics; using CoreAnimation; using Foundation; namespace App1.i
using System;
using UIKit;
using CoreGraphics;
using CoreAnimation;
using Foundation;
namespace App1.iOS
{
public class BadgeBarButtonItem : UIBarButtonItem
{
#region Fields
UILabel _badge;
string _badgeValue;
UIColor _badgeBGColor;
UIColor _badgeTextColor;
UIColor _badgeBorderColor;
UIFont _badgeFont;
nfloat _badgePadding;
nfloat _badgeMinSize;
nfloat _badgeOriginX;
nfloat _badgeOriginY;
nfloat _badgeBorderWidth;
bool _shouldHideBadgeAtZero;
bool _shouldAnimateBadge;
#endregion
#region Public properties
// Each time you change one of the properties, the badge will refresh with your changes
/// <summary>
/// Gets or sets the badge value to be displayed.
/// </summary>
/// <value>The badge value.</value>
public string BadgeValue
{
get
{
return _badgeValue;
}
set
{
_badgeValue = value;
SetBadgeValue(value);
}
}
/// <summary>
/// Gets or sets the badge background color.
/// </summary>
/// <value>The color of the badge background.</value>
public UIColor BadgeBGColor
{
get
{
return _badgeBGColor;
}
set
{
if (value == null)
throw new ArgumentNullException(nameof(BadgeBGColor));
_badgeBGColor = value;
if (_badge != null)
{
this.RefreshBadge();
}
}
}
/// <summary>
/// Gets or sets the badge text color.
/// </summary>
/// <value>The color of the badge text.</value>
public UIColor BadgeTextColor
{
get
{
return _badgeTextColor;
}
set
{
if (value == null)
throw new ArgumentNullException(nameof(BadgeTextColor));
_badgeTextColor = value;
if (_badge != null)
{
this.RefreshBadge();
}
}
}
/// <summary>
/// Gets or sets the badge border color.
/// </summary>
/// <value>The color of the badge border.</value>
public UIColor BadgeBorderColor
{
get
{
return _badgeBorderColor;
}
set
{
if (value == null)
throw new ArgumentNullException(nameof(BadgeBorderColor));
_badgeBorderColor = value;
if (_badge != null)
{
this.RefreshBadge();
}
}
}
/// <summary>
/// Gets or sets the badge font.
/// </summary>
/// <value>The badge font.</value>
public UIFont BadgeFont
{
get
{
return _badgeFont;
}
set
{
if (value == null)
throw new ArgumentNullException(nameof(BadgeFont));
_badgeFont = value;
if (_badge != null)
{
this.RefreshBadge();
}
}
}
/// <summary>
/// Gets or sets the padding value for the badge.
/// </summary>
/// <value>The badge padding.</value>
public nfloat BadgePadding
{
get
{
return _badgePadding;
}
set
{
_badgePadding = value;
if (_badge != null)
{
this.UpdateBadgeFrame();
}
}
}
/// <summary>
/// Gets or sets the minimum size of the badge minimum.
/// </summary>
/// <value>The minimum size of the badge.</value>
public nfloat BadgeMinSize
{
get
{
return _badgeMinSize;
}
set
{
_badgeMinSize = value;
if (_badge != null)
{
this.UpdateBadgeFrame();
}
}
}
/// <summary>
/// Gets or sets the X value for offsetting the badge over the BarButtonItem.
/// </summary>
/// <value>The badge X origin.</value>
public nfloat BadgeOriginX
{
get
{
return _badgeOriginX;
}
set
{
_badgeOriginX = value;
if (_badge != null)
{
this.UpdateBadgeFrame();
}
}
}
/// <summary>
/// Gets or sets the Y value for offsetting the badge over the BarButtonItem.
/// </summary>
/// <value>The badge Y origin.</value>
public nfloat BadgeOriginY
{
get
{
return _badgeOriginY;
}
set
{
_badgeOriginY = value;
if (_badge != null)
{
this.UpdateBadgeFrame();
}
}
}
/// <summary>
/// Gets or sets the width of the badge border.
/// </summary>
/// <value>The badge border width.</value>
public nfloat BadgeBorderWidth
{
get
{
return _badgeBorderWidth;
}
set
{
_badgeBorderWidth = value;
if (_badge != null)
{
this.RefreshBadge();
}
}
}
/// <summary>
/// Gets or sets a value indicating whether this <see cref="Utility.BadgeBarButtonItem"/> should remove the badge when reaching zero.
/// </summary>
/// <value><c>true</c> if should hide badge at zero; otherwise, <c>false</c>.</value>
public bool ShouldHideBadgeAtZero
{
get
{
return _shouldHideBadgeAtZero;
}
set
{
_shouldHideBadgeAtZero = value;
if (_badge != null)
{
this.UpdateBadgeFrame();
}
}
}
/// <summary>
/// Gets or sets a value indicating whether this <see cref="Utility.BadgeBarButtonItem"/> should animate the badge when its value changes.
/// </summary>
/// <value><c>true</c> if should animate badge; otherwise, <c>false</c>.</value>
public bool ShouldAnimateBadge
{
get
{
return _shouldAnimateBadge;
}
set
{
_shouldAnimateBadge = value;
if (_badge != null)
{
this.UpdateBadgeFrame();
}
}
}
#endregion
/// <summary>
/// Initializes a new instance of the <see cref="Utility.BadgeBarButtonItem"/> class.
/// </summary>
/// <param name="customButton">Custom button.</param>
public BadgeBarButtonItem(UIButton customButton)
{
this.CustomView = customButton;
if (this.CustomView != null)
{
Initializer();
}
}
protected virtual void Initializer()
{
// Default design initialization
this.BadgeBGColor = UIColor.Red;
this.BadgeBorderColor = UIColor.White;
this.BadgeTextColor = UIColor.White;
this.BadgeFont = UIFont.SystemFontOfSize(12);
this.BadgePadding = 6;
this.BadgeMinSize = 8;
this.BadgeOriginX = 7;
this.BadgeOriginY = -9;
this.BadgeBorderWidth = 0;
this.ShouldHideBadgeAtZero = true;
this.ShouldAnimateBadge = true;
// Avoids badge to be clipped when animating its scale
this.CustomView.ClipsToBounds = false;
}
#region Utility methods
// Handles badge display when its properties have been changed (background, color and font)
void RefreshBadge()
{
// Change new attributes
_badge.TextColor = this.BadgeTextColor;
_badge.BackgroundColor = this.BadgeBGColor;
_badge.Font = this.BadgeFont;
SetBorder();
}
void UpdateBadgeFrame()
{
// When the value changes the badge could need to get bigger
// Calculate expected size to fit new value
// Use an intermediate label to get expected size thanks to sizeToFit
// We don't call sizeToFit on the true label to avoid bad display
UILabel frameLabel = DuplicateLabel(_badge);
frameLabel.SizeToFit();
CGSize expectedLabelSize = frameLabel.Frame.Size;
// Make sure that for small value, the badge will be big enough
nfloat minHeight = expectedLabelSize.Height;
// Using a const we make sure the badge respect the minimum size
minHeight = (minHeight < this.BadgeMinSize) ? this.BadgeMinSize : expectedLabelSize.Height;
nfloat minWidth = expectedLabelSize.Width;
nfloat padding = this.BadgePadding;
// Using const we make sure the badge doesn't get too smal
minWidth = (minWidth < minHeight) ? minHeight : expectedLabelSize.Width;
_badge.Frame = new CGRect(this.BadgeOriginX, this.BadgeOriginY, minWidth + padding, minHeight + padding);
_badge.Layer.CornerRadius = (minHeight + padding) / 2;
_badge.Layer.MasksToBounds = true;
}
// Handle the badge changing value
void UpdateBadgeValueAnimated(bool animated)
{
// Bounce animation on badge if value changed and if animation authorized
if (animated && this.ShouldAnimateBadge && _badge.Text != this.BadgeValue)
{
var animation = new CABasicAnimation();
animation.KeyPath = @"transform.scale";
animation.From = NSObject.FromObject(1.5);
animation.To = NSObject.FromObject(1);
animation.Duration = 0.2;
animation.TimingFunction = new CAMediaTimingFunction(0.4f, 1.3f, 1f, 1f);
_badge.Layer.AddAnimation(animation, @"bounceAnimation");
}
// Set the new value
_badge.Text = this.BadgeValue;
// Animate the size modification if needed
double duration = animated ? 0.2 : 0;
UIView.Animate(duration, UpdateBadgeFrame);
}
static UILabel DuplicateLabel(UILabel labelToCopy)
{
var duplicateLabel = new UILabel(labelToCopy.Frame);
duplicateLabel.Text = labelToCopy.Text;
duplicateLabel.Font = labelToCopy.Font;
return duplicateLabel;
}
void RemoveBadge()
{
if (_badge != null)
{
// Animate badge removal
UIView.AnimateNotify(0.15f, 0.0F,
UIViewAnimationOptions.CurveEaseIn,
() => {
_badge.Transform = CGAffineTransform.MakeScale(0.1f, 0.1f);
},
completed => {
_badge.RemoveFromSuperview();
_badge = null;
}
);
}
}
#endregion
#region Setter
void SetBadgeValue(string badgeValue)
{
// Set new value
_badgeValue = badgeValue;
// When changing the badge value check if we need to remove the badge
if (string.IsNullOrEmpty(badgeValue) || (badgeValue == @"0" && this.ShouldHideBadgeAtZero))
{
RemoveBadge();
}
else if (_badge == null)
{
// Create a new badge because it doesn't exist
_badge = new UILabel(new CGRect(this.BadgeOriginX, this.BadgeOriginY, 20, 20))
{
TextColor = this.BadgeTextColor,
BackgroundColor = this.BadgeBGColor,
Font = this.BadgeFont,
TextAlignment = UITextAlignment.Center,
};
// Fix for iOS 9: Correctly apply the CornerRadius later on
_badge.Layer.MasksToBounds = true;
SetBorder();
this.CustomView.AddSubview(_badge);
this.UpdateBadgeValueAnimated(false);
}
else
{
this.UpdateBadgeValueAnimated(true);
}
}
void SetBorder()
{
if (this.BadgeBorderWidth > 0)
{
_badge.Layer.BorderColor = BadgeBorderColor.CGColor;
}
_badge.Layer.BorderWidth = this.BadgeBorderWidth;
}
#endregion
}
}
使用系统;
使用UIKit;
使用核心图形;
使用CoreAnimation;
使用基础;
名称空间App1.iOS
{
公共类徽章巴布托教派:维吾尔巴布托教派
{
#区域字段
UILabel_徽章;
字符串值;
UIColor BadgebColor;
UIColor(UIColor);
UIColor(颜色);
UIFont(UIFont);;
nfloat_;
nfloat_Badgeminize;
nfloat_badgeOriginX;
nfloat_Badgeginy;
nfloat(宽度);
bool_应该在零位;
bool_应该有动画背景;
#端区
#区域公共财产
//每次更改其中一个属性时,徽章将随着您的更改而刷新
///
///获取或设置要显示的徽章值。
///
///徽章的价值。
公共字符串值
{
得到
{
返回值;
}
设置
{
_价值=价值;
SetBadgeValue(值);
}
}
///
///获取或设置徽章背景色。
///
///徽章背景的颜色。
公共UIColor徽章颜色
{
得到
{
返回颜色;
}
设置
{
如果(值==null)
抛出新ArgumentNullException(nameof(BadgeBGColor));
_颜色=值;
如果(_badge!=null)
{
这个.RefreshBadge();
}
}
}
///
///获取或设置徽章文本颜色。
///
///徽章文本的颜色。
公共UIColor徽章文本颜色
{
得到
{
返回颜色;
}
设置
{
如果(值==null)
抛出新ArgumentNullException(nameof(BadgeTextColor));
_badgeTextColor=值;
如果(_badge!=null)
{
这个.RefreshBadge();
}
}
}
///
///获取或设置徽章边框颜色。
///
///徽章边框的颜色。
公共颜色徽章边框颜色
{
得到
{
返回颜色;
}
设置
{
如果(值==null)
抛出新ArgumentNullException(nameof(BadgeBorderColor));
_颜色=值;
如果(_badge!=null)
{
这个.RefreshBadge();
}
}
}
///
///获取或设置徽章字体。
///
///徽章字体。
公用字体
{
得到
{
返回(字体);;
}
设置
{
如果(值==null)
抛出新ArgumentNullException(nameof(BadgeFont));
_字体=值;
如果(_badge!=null)
{
这个.RefreshBadge();
}
}
}
///
///获取或设置徽章的填充值。
///
///徽章的衬垫。
公共非流动资产
{
得到
{
返回(u);;
}
设置
{
_badgePadding=值;
如果(_badge!=null)
{
这个.UpdateBadgeFrame();
}
}
}
///
///获取或设置证卡的最小大小。
///
///徽章的最小尺寸。
公共nfloat Badgeminize
{
得到
{
返回(u)标记大小;;
}
设置
{
_badgeMinSize=值;
如果(_badge!=null)
{
这个.UpdateBadgeFrame();
}
}
}
///
///获取或设置用于在BarButtonItem上偏移徽章的X值。
///
///徽章是X的起源。
公共nfloat BadgeOriginX
{
得到
{
返回badgeOriginX;
}
设置
{
_badgeOriginX=数值;
如果(_badge!=null)
{
这个.UpdateBadgeFrame();
}
}
}
///
///