您的位置:首页 > 移动开发 > IOS开发

Xamarin.iOS 自定义按钮选择器

2016-11-15 14:37 197 查看
最近项目中做了一个标题栏中的按钮选择器,原生的UISegmentedControl 无法达到项目效果,效果如下图:



如果只针对项目写一个不难,可是如果以后遇到了还需要针对项目再去写一个,于是我打算把他写的活一些,最终决定用Builder模式来完成它,以前做android原生的时候就用Builder模式构建了一些组合view,但是我尝试着用java的方式去Builder的时候发现行不通,这次是Xamarin的项目,语言是C#,于是我又去学习了一下C#的Builder模式(浅显的理解很简单)。

哦,差点忘了介绍,项目的框架是MvvmCross,不理解的同学去他的官网看看,很良心的!

最终计划了一下这个工作分为三步走(典型的面向过程,哈哈)。

第一步:将这些可以看见的属性,或者随时可以变的属性抽象出来。

using System;
using UIKit;

namespace RuilaiGrow.iOS
{
/// <summary>
/// 多按钮圆角view构建抽象类
/// by ge
/// </summary>
abstract class BuilderTopSelectedTitle
{
public abstract void setTitles(string[] titles);
public abstract void setTextSize(nfloat size);
public abstract void setCornerRadius(nfloat radius);
public abstract void setHeight(nfloat height);
public abstract void setWidth(nfloat width);
public abstract void setNormalTextColor(UIColor color);
public abstract void setSelectedTextColor(UIColor color);
public abstract void setViewBackground(UIColor background);
public abstract void setItemNormal(UIColor corlor);
public abstract void setItemSelected(UIColor selected);
public abstract UIView create();
}
}


项目比较紧张,可能这些属性还是不够,或者说想的不到位,以后慢慢添加和优化。



第二步:创建实现类,构建需要的控件。

经过一番研究,最外层(也就是最终创建返回给界面的)是一个UIView,中间的按钮用UIButton来代替,原因是:经过查阅资料,和尝试,发现UIButton是将UILable于UIImageView封装的结果,采用懒加载的方式,用谁初始化谁,感觉很棒不用我自己造轮子了(以前一直做android原生,对iOS不是很了解,大家见笑)。下面是实现类的代码,注视挺全的了,直接复制粘贴了(懒懒懒)。

using System;
using System.Drawing;
using RuilaiGrow.iOS.Common;
using UIKit;

namespace RuilaiGrow.iOS
{
/// <summary>
/// 知识库主页标题切换控制器
/// </summary>
class KnowledgeTitleControl : BuilderTopSelectedTitle
{
public KnowledgeTitleControl()
{

}

//最外层总view
UIView _thisView = null;
public UIView ThisView
{
get
{
if (_thisView == null)
{
//根据本view的宽与高来计算其实位置(目的最终添加到View的导航栏的时候可以居中显示)
nfloat startX = (UIScreen.MainScreen.Bounds.Width - _itemWid * _titles.Length) / 2;
nfloat startY = (EasyLayout.BarHeight - _viewHei) / 2;
_thisView = new UIView(new RectangleF((float)startX, (float)startY, (float(_itemWid * _titles.Length), (float)_viewHei));
_thisView.BackgroundColor = _viewBackground;
}
return _thisView;
}
}

//标题数组
private string[] _titles;

//item数组
private UIButton[] _itemBtns;

//控件的高
private nfloat _viewHei = 45;

//item的宽
private nfloat _itemWid = 70;

//item正常时的颜色
private UIColor _itemNormalBac = UIColor.Blue;

//item选中时的颜色
private UIColor _itemSeletedBac = UIColor.White;

//文字正常的颜色
private UIColor _textNormalColor = UIColor.Black;

//文字选中时的颜色
private UIColor _textSeletedColor = UIColor.Red;

//设置本view的颜色
private UIColor _viewBackground = UIColor.Blue;

//文字的大小
private nfloat _textSize = 15;

//边框与按钮的圆角
private nfloat _radius = 18;

//按钮上次点击事件 默认0
private int lastIndex = 0;

/// <summary>
/// 最终创建view
/// </summary>
public override UIView create()
{
ThisView.Layer.BorderWidth = 1;
ThisView.Layer.BorderColor = MvxTouchColor.ShallowGrayOne.CGColor;
ThisView.Layer.CornerRadius = _radius;

_itemBtns = new UIButton[_titles.Length];

//循环创建文字按钮并加入到总view中
int lenght = _titles.Length;
for (int i = 0; i < lenght; i++) {
_itemBtns[i] = new UIButton();
_itemBtns[i].Tag = i;
_itemBtns[i].SetTitle(_titles[i], UIControlState.Normal);
_itemBtns[i].SetTitleColor(_textNormalColor, UIControlState.Normal);
_itemBtns[i].Layer.CornerRadius = _radius;
_itemBtns[i].TitleLabel.Font = UIFont.SystemFontOfSize(_textSize);
//设置第一个按钮选中状态
if (i == 0)
{
_itemBtns[i].BackgroundColor = _itemSeletedBac;
_itemBtns[i].SetTitleColor(_textSeletedColor, UIControlState.Normal);
}
}

ThisView.AddSubviews(_itemBtns);

//循环设置view内部item之间约束
for (int i = 0; i < lenght; i++) {
if (i == 0)
{
ThisView.ConstrainLayout(() =>
_itemBtns[i].Frame.GetCenterY() == ThisView.Frame.GetCenterY()
&& _itemBtns[i].Frame.Width == _itemWid
&& _itemBtns[i].Frame.Height == ThisView.Frame.Height
&& _itemBtns[i].Frame.Left == ThisView.Frame.Left

&& ThisView.Frame.Bottom == _itemBtns[i].Frame.Bottom
);
}
else {
ThisView.ConstrainLayout(() =>
_itemBtns[i].Frame.GetCenterY() == ThisView.Frame.GetCenterY()
&& _itemBtns[i].Frame.Left == _itemBtns[i - 1].Frame.Right
&& _itemBtns[i].Frame.Width == _itemWid
&& _itemBtns[i].Frame.Height == ThisView.Frame.Height
);
}
}

//按钮点击事件
for (int i = 0; i < _titles.Length; i++) {
_itemBtns[i].TouchUpInside += this.TouchBtn;
}

return ThisView;
}

//按钮点击处理
private void TouchBtn(object sender, EventArgs e)
{
UIButton v = (UIKit.UIButton)sender;

//如果和上次点的一样 return
if (v.Tag == lastIndex)
return;

//清空上次点击view的状态
_itemBtns[lastIndex].BackgroundColor = _itemNormalBac;
_itemBtns[lastIndex].SetTitleColor(_textNormalColor, UIControlState.Normal);

//设置本次点击的view的状态
_itemBtns[v.Tag].BackgroundColor = _itemSeletedBac;
_itemBtns[v.Tag].SetTitleColor(_textSeletedColor, UIControlState.Normal);

//记录本次点击的位置
lastIndex = (int)v.Tag;

//回调点击位置
if (_click != null) {
_click.TitleBackIndex((int)v.Tag);
}
}

/// <summary>
/// 设置按钮正常时的状态颜色
/// </summary>
/// <param name="corlor">Corlor.</param>
public override void setItemNormal(UIColor corlor)
{
this._itemNormalBac = corlor;
}

/// <summary>
/// 设置item选中时的背景
/// </summary>
/// <param name="selected">Selected.</param>
public override void setItemSelected(UIColor selected)
{
this._itemSeletedBac = selected;
}

/// <summary>
/// 设置正常时的文字的颜色
/// </summary>
/// <param name="color">Color.</param>
public override void setNormalTextColor(UIColor color)
{
this._textNormalColor = color;
}

/// <summary>
/// 设置选中时文字的颜色
/// </summary>
/// <param name="color">Color.</param>
public override void setSelectedTextColor(UIColor color)
{
this._textSeletedColor = color;
}

/// <summary>
/// 设置item的文字
/// </summary>
/// <param name="titles">Titles.</param>
public override void setTitles(string[] titles)
{
this._titles = titles;
}

/// <summary>
/// 设置view的背景图片
/// </summary>
/// <param name="background">Background.</param>
public override void setViewBackground(UIColor background)
{
this._viewBackground = background;
}

/// <summary>
/// 设置item的宽
/// </summary>
/// <param name="width">Width.</param>
public override void setWidth(nfloat width)
{
this._itemWid = width;
}

/// <summary>
/// 设置本view的高
/// </summary>
/// <param name="height">Height.</param>
public override void setHeight(nfloat height)
{
this._viewHei = height;
}

/// <summary>
/// 设置边框的圆角与按钮的圆角
/// </summary>
/// <param name="radius">Radius.</param>
public override void setCornerRadius(nfloat radius)
{
this._radius = radius;
}

/// <summary>
/// 设置文字的大小
/// </summary>
/// <param name="size">Size.</param>
public override void setTextSize(nfloat size)
{
this._textSize = size;
}

/// <summary>
/// 点击view回调接口
/// </summary>
public interface ClickTitleControlItem {
void TitleBackIndex(int index);
}

private ClickTitleControlItem _click;

public void setClickTitleControlItem(ClickTitleControlItem click)
{
this._click = click;
}

}
}


上面就是实现类的全部内容,最后那个接口是这个view点击某个按钮时的回调,同事说我这是拿java的思想来写c#,搞得我去查了一下,打算把这个换成事件委托机制。

下面看一下第三步:使用

在Controller中直接定义一个UIView接收创建的view就可以:

       

//头部导航栏的view
UIView _topViewControl = null;
public UIView TopViewControl {
get{
if (_topViewControl == null) {
string[] s = new string[] {
"0-1岁", "1-3岁", "3-6岁"
};
KnowledgeTitleControl ctr = new KnowledgeTitleControl();
ctr.setWidth(85);
ctr.setHeight(EasyLayout.BarHeight - 10f);
ctr.setTitles(s);
ctr.setTextSize(15);
ctr.setCornerRadius(18);
ctr.setItemNormal(MvxTouchColor.DeepRed);
ctr.setViewBackground(MvxTouchColor.DeepRed);
ctr.setItemSelected(MvxTouchColor.White);
ctr.setNormalTextColor(MvxTouchColor.ShallowGrayOne);
ctr.setSelectedTextColor(MvxTouchColor.DeepRed);
ctr.setClickTitleControlItem(this);
_topViewControl = ctr.create();
}
return _topViewControl;
}
}


最后将view添加到导航栏就可以了:

在ViewDidLoad()方法中:

//将头部控制器的uiview加入顶部导航栏
NavigationController.NavigationBar.AddSubview(TopViewControl);


按钮的个数是根据构造函数传入的数组决定的。

搞定!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  xamarin c# iOS Xamarin.iOS