Xamarin.iOS 自定义按钮选择器
2016-11-15 14:37
197 查看
最近项目中做了一个标题栏中的按钮选择器,原生的UISegmentedControl 无法达到项目效果,效果如下图:
如果只针对项目写一个不难,可是如果以后遇到了还需要针对项目再去写一个,于是我打算把他写的活一些,最终决定用Builder模式来完成它,以前做android原生的时候就用Builder模式构建了一些组合view,但是我尝试着用java的方式去Builder的时候发现行不通,这次是Xamarin的项目,语言是C#,于是我又去学习了一下C#的Builder模式(浅显的理解很简单)。
哦,差点忘了介绍,项目的框架是MvvmCross,不理解的同学去他的官网看看,很良心的!
最终计划了一下这个工作分为三步走(典型的面向过程,哈哈)。
第一步:将这些可以看见的属性,或者随时可以变的属性抽象出来。
项目比较紧张,可能这些属性还是不够,或者说想的不到位,以后慢慢添加和优化。
第二步:创建实现类,构建需要的控件。
经过一番研究,最外层(也就是最终创建返回给界面的)是一个UIView,中间的按钮用UIButton来代替,原因是:经过查阅资料,和尝试,发现UIButton是将UILable于UIImageView封装的结果,采用懒加载的方式,用谁初始化谁,感觉很棒不用我自己造轮子了(以前一直做android原生,对iOS不是很了解,大家见笑)。下面是实现类的代码,注视挺全的了,直接复制粘贴了(懒懒懒)。
上面就是实现类的全部内容,最后那个接口是这个view点击某个按钮时的回调,同事说我这是拿java的思想来写c#,搞得我去查了一下,打算把这个换成事件委托机制。
下面看一下第三步:使用
在Controller中直接定义一个UIView接收创建的view就可以:
最后将view添加到导航栏就可以了:
在ViewDidLoad()方法中:
按钮的个数是根据构造函数传入的数组决定的。
搞定!!
如果只针对项目写一个不难,可是如果以后遇到了还需要针对项目再去写一个,于是我打算把他写的活一些,最终决定用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);
按钮的个数是根据构造函数传入的数组决定的。
搞定!!
相关文章推荐
- 自定义的iOS的滚轮选择器,附带农历选择器实现
- iOS创建不带nib文件的工程之四--在自定义view上添加按钮
- IOS UINavigationBar 自定义返回按钮
- [ios] 自定义UIAlertView样式,实现可替换背景和按钮 【转】
- iOS cocos2d实现自定义button(按钮特效)控件效果源码
- 在Android中自定义IOS风格的按钮
- iOS自定义的UISwitch按钮
- iOS 5 编程-实现自定义的选择器视图(UIPickerView)
- iOS 背景图片。按钮高亮自定义背景
- IOS 自定义导航栏标题和返回按钮标题
- iOS中创建自定义的圆角按钮
- 自定义的iOS的滚轮选择器,附带农历选择器实现
- 自定义的iOS的滚轮选择器,附带农历选择器实现代码
- 自定义ios UIAlertView, 重排按钮位置
- Ios使用按钮自定义segmentcontrol
- 自定义的iOS的滚轮选择器,附带农历选择器实现
- 【IOS】自定义UIAlertView样式,实现可替换背景和按钮
- IOS中自定义navigationItem的按钮
- ios 自定义按钮
- iOS 背景图片。按钮高亮自定义背景