<span >看着公司项目中拥有这个自定义控件,想想后面肯定也要替换成swift的,所以,就开始动手干了起来.</span>
购物车计数器,目前设计了两种类型,一种就是线框圆角,一种就是按钮圆形.
目前支持加/减,以及设置每一步增加或减少的数值,支持闭包回调.当然同时也涉及了简单的VFL(Visual Format Language)的使用.
就目前来说,离笔者想要的功能也大致一样了,如果有新的功能,大家可以修改修改.
效果图是这样的,就没有制作动图了,将就吧:
那先上代码了:
//// NBCountVIEw.swift// NBCountVIEw//// Created by NapoleonBai on 15/9/20.// copyright © 2015年 NapoleonBai. All rights reserved.//import UIKitenum NBCountVIEwShowType{ /// 圆角按钮 case Filletbutton /// 圆形按钮 case Circlebutton}struct NBCountConfig { /// 设置私有属性显示样式 private var mCountVIEwType : NBCountVIEwShowType = .Filletbutton var countVIEwShowType : NBCountVIEwShowType{ get{ return mCountVIEwType } set(newShowType){ self.mCountVIEwType = newShowType } } /// 设置私有属性Tintcolor private var mTintcolor : UIcolor = UIcolor.greencolor() var tintcolor : UIcolor { get{ return mTintcolor } set(newTintcolor){ self.mTintcolor = newTintcolor } } init(){} /** 增加带参数的构造方法 - parameter countVIEwShowType: 显示样式 - parameter bordercolor: bordercolor - returns: 当前结构体实例 */ init(countVIEwShowType:NBCountVIEwShowType,tintcolor:UIcolor){ self.countVIEwShowType = countVIEwShowType self.tintcolor = tintcolor }}class NBCountVIEw : UIVIEw,UITextFIEldDelegate{ /// 设置默认的两个按钮以及输入框 private var lessBtn : UIbutton = UIbutton.init(type:.Custom) private var addBtn : UIbutton = UIbutton.init(type:.Custom) private var countTextFIEld : UITextFIEld = UITextFIEld.init() private var mVIEwConfig : NBCountConfig = NBCountConfig() /// 修改之前的值 private var updateAgainValue = 0 /// 当前显示值,缺省为0 private var mCurrentValue : Int = 0 /// 当前显示值,动态设置 var currentValue : Int{ get{ return mCurrentValue } set(newCurrentValue){ self.mCurrentValue = newCurrentValue self.updateAgainValue = self.mCurrentValue self.countTextFIEld.text = "\(self.mCurrentValue)" } } /// 每次增加或改变多少,缺省为1 var stepValue : Int = 1 /// 是否可以手动编辑数值 var isEditTextFIEld : Bool = false var vIEwConfig : NBCountConfig{ set(newConfig){ self.mVIEwConfig = newConfig //更新相关配置属性 updateConfig() } get{ return self.mVIEwConfig } } /// 当前数值改变回调(得到当前显示的数量) var notifyUpdateCurrentValue : ((currentValue : Int) ->VoID)! /// 当前数值改变时回调(得到的是每次更改的数量) var notifyUpdateStepValue : ((updateStepValue : Int) -> VoID)! /** 无参构造函数 */ convenIEnce init(){ //默认调用init frame self.init(frame: CGRectZero) } /** 重新构造方法,创建VIEw - parameter frame: 指定frame */ overrIDe init(frame: CGRect) { super.init(frame: frame) buildUI() } /** 从视图控制器中拖此控件,从这里加载 */ required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) buildUI() } /** 创建UI */ func buildUI(){ lessBtn = UIbutton.init(type: UIbuttonType.Custom) addBtn = UIbutton.init(type: .Custom) countTextFIEld = UITextFIEld.init() lessBtn.setTitle("-",forState: .normal) addBtn.setTitle("+",forState: .normal) countTextFIEld.text = "\(mCurrentValue)" updateAgainValue = mCurrentValue lessBtn.TitleLabel?.Font = UIFont.boldSystemFontOfSize(30) addBtn.TitleLabel?.Font = UIFont.boldSystemFontOfSize(30) countTextFIEld.textAlignment = .Center countTextFIEld.keyboardType = .NumberPad countTextFIEld.delegate = self countTextFIEld .addTarget(self,action:"textFIEldValueChange:",forControlEvents: .EditingChanged) self.addSubvIEw(lessBtn) self.addSubvIEw(addBtn) self.addSubvIEw(countTextFIEld) lessBtn.addTarget(self,action:"onClickLessBtn:",forControlEvents:.touchUpInsIDe) addBtn.addTarget(self,action:"onClickAddBtn:",forControlEvents:.touchUpInsIDe) //self.updateConfig() addautoLayoutContas() } func onClickLessBtn(lessBtn : UIbutton){ self.updatedisplayCurrentValue(-stepValue) } func onClickAddBtn(addBtn : UIbutton){ self.updatedisplayCurrentValue(stepValue) } func updatedisplayCurrentValue(updateStepCount : Int){ countTextFIEld.resignFirstResponder() //获取当前数值 let currentValueInt = (countTextFIEld.text! as Nsstring).integerValue //改变当前数值 mCurrentValue = currentValueInt + updateStepCount //重新设置当前数值 countTextFIEld.text = "\(mCurrentValue)" /** 回调,传入当前显示值 - parameter currentValue: 当前显示数值 */ notifyUpdateCurrentValue?(currentValue:mCurrentValue) /** 回调,传入当前更改的数量 - parameter updateStepValue: 当前更改的数量 */ notifyUpdateStepValue?(updateStepValue:updateStepCount) self.updateAgainValue = self.mCurrentValue } /** 设置相关属性 */ func updateConfig(){ //如果这是第一种类型,也就是圆角按钮,设置边框的那种 if mVIEwConfig.countVIEwShowType == NBCountVIEwShowType.Filletbutton { self.layer.bordercolor = mVIEwConfig.mTintcolor.CGcolor self.layer.borderWIDth = 1 self.layer.cornerRadius = 5 self.layer.masksToBounds = true self.lessBtn.layer.bordercolor = mVIEwConfig.mTintcolor.CGcolor self.addBtn.layer.bordercolor = mVIEwConfig.mTintcolor.CGcolor self.lessBtn.layer.borderWIDth = 1 self.addBtn.layer.borderWIDth = 1 self.lessBtn.setTitlecolor(mVIEwConfig.mTintcolor,forState:.normal) self.addBtn.setTitlecolor(mVIEwConfig.mTintcolor,forState:.normal) }else{ //这是第二种类型,设置圆形按钮 self.lessBtn.layer.masksToBounds = true self.addBtn.layer.masksToBounds = true self.lessBtn.layer.cornerRadius = self.frame.size.height / 2.0 self.addBtn.layer.cornerRadius = self.frame.size.height / 2.0 self.lessBtn.backgroundcolor = mVIEwConfig.mTintcolor self.addBtn.backgroundcolor = mVIEwConfig.mTintcolor self.lessBtn.setTitlecolor(UIcolor.whitecolor(),forState: .normal) self.addBtn.setTitlecolor(UIcolor.whitecolor(),forState: .normal) } } /** 添加约束 */ func addautoLayoutContas(){ lessBtn.translatesautoresizingMaskIntoConstraints = false addBtn.translatesautoresizingMaskIntoConstraints = false countTextFIEld.translatesautoresizingMaskIntoConstraints = false let vIEwDicts = dictForVIEws([lessBtn,countTextFIEld,addBtn]) //设置水平布局,间距5,两个按钮宽度相等 self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[lessBtn]-5-[countTextFIEld]-5-[addBtn(lessBtn)]|",options:.DirectionLeadingToTrailing,metrics: nil,vIEws: vIEwDicts)) //设置按钮高度 self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[lessBtn]|",options:NSLayoutFormatoptions.DirectionLeadingToTrailing,vIEws: vIEwDicts)) self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[countTextFIEld]|",vIEws: vIEwDicts)) self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[addBtn]|",vIEws: vIEwDicts)) //设置按钮宽高相等 self.addConstraint(NSLayoutConstraint.init(item:lessBtn,attribute: NSLayoutAttribute.WIDth,relatedBy: .Equal,toItem: lessBtn,attribute:NSLayoutAttribute.Height,multiplIEr: 1.0,constant: 0)) } /** 自定义生成键值对dicationary - parameter objecs: 数组对象 eg:[1,2,3] - returns: 键值对对象 eg:["1":1,"2":2,"3":3] */ func dictForVIEws(objecs:[AnyObject]) -> [String : AnyObject] { var count:UInt32 = 0 var dicts:[String : AnyObject] = [:] let ivars = class_copyIvarList(self.classForCoder,&count) for var i = 0; i < Int(count); ++i{ let obj = object_getIvar(self,ivars[i]) let name = String.fromCString(ivar_getname(ivars[i]))! dicts[name] = obj if dicts.count == objecs.count{ break } } free(ivars) return dicts } /** UItextFIEld delegate method - parameter textFIEld: 就是界面显示当前值的textfIEld - returns: 当前textfIEld是否能编辑,true为可编辑,false为不可编辑 */ func textFIEldShouldBeginEditing(textFIEld: UITextFIEld) -> Bool{ return isEditTextFIEld } /** countTextFIEld获取焦点是执行 - parameter textFIEld: <#textFIEld description#> */ func textFIEldDIDBeginEditing(textFIEld: UITextFIEld){ //如果开始输入时,为0,就去掉0 let changedValue = (textFIEld.text! as Nsstring).integerValue if changedValue == 0{ textFIEld.text = "" } } /** countTextFIEld 失去焦点时执行 - parameter textFIEld: <#textFIEld description#> */ func textFIEldDIDEndEditing(textFIEld: UITextFIEld){ //如果结束时没有任何输入,就置为0 if textFIEld.text!.isEmpty{ textFIEld.text = "0" } } func textFIEldValueChange(textFIEld : UITextFIEld){ let changedValue = (textFIEld.text! as Nsstring).integerValue let changedStep = changedValue - self.updateAgainValue self.mCurrentValue = changedValue self.updateAgainValue = self.mCurrentValue /** 回调,传入当前更改的数量 - parameter updateStepValue: 当前更改的数量 */ notifyUpdateStepValue?(updateStepValue:changedStep) } /** 移除焦点事件 */ overrIDe func resignFirstResponder() -> Bool { countTextFIEld.resignFirstResponder() return true }}
这上面就是完整的自定义的代码,下面,就介绍怎么使用吧,新建一个VC,然后分别创建不同的两种状态的计数器:
如下:
countVIEw.isEditTextFIEld = true self.vIEw.addSubvIEw(countVIEw) countVIEw.vIEwConfig = NBCountConfig(countVIEwShowType:.Filletbutton,tintcolor:UIcolor.redcolor()) countVIEw.currentValue = 20 countVIEw.notifyUpdateStepValue = {(updateStepValue : Int) in print("更改的数量为:\(updateStepValue)") } countVIEw.notifyUpdateCurrentValue = {(currentValue : Int) in print("当前显示数值为:\(currentValue)") }
这里设置了输入框是否可以编辑,以及当前显示值和监听每次更改的值以及当前值等
当然,这只是其中一种状态,还有另一种,如下:
let countVIEw1 : NBCountVIEw = NBCountVIEw.init(frame: CGRectMake(50,160,120,40)) self.vIEw.addSubvIEw(countVIEw1) countVIEw1.vIEwConfig = NBCountConfig(countVIEwShowType:.Circlebutton,tintcolor:UIcolor.greencolor()) countVIEw1.notifyUpdateStepValue = {(updateStepValue : Int) in print("更改的数量为:\(updateStepValue)") } countVIEw1.notifyUpdateCurrentValue = {(currentValue : Int) in print("当前显示数值为:\(currentValue)") }
这就是两种显示状态的计数器,当然了,如果想要停止编辑,只需要触摸屏幕方法中实现:
overrIDe func touchesBegan(touches: Set<UItouch>,withEvent event: UIEvent?) { countVIEw.resignFirstResponder() }当然了,也不仅仅是这样,根据自己需要调用resignFirstResponder就好了.
以上就是全部代码,如果你也喜欢,可以点个赞,如果你有好的需求,也可以在下面说说.
欢迎赐教,不甚感激!
源码下载:https://github.com/NapoleonBaiAndroid/NBCountView-swift
总结以上是内存溢出为你收集整理的swift 自定义购物车计数器全部内容,希望文章能够帮你解决swift 自定义购物车计数器所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)