与路由设计模式配套的视图处理方式

随着路由设计模式的使用,所有按钮及tableview的点击事件都由服务器端决定,固定UI已经无法满足需求,固定的UI限制了当前路由设计的灵活性,所以为了使UI可以像点击事件一样灵活,我们定义了差不多30种常见的UI展示样式,开发中最常用的就是tableview,所以我们让每一种展示样式都作为一个新的cell,通过当前数据的show_type来决定使用哪一种cell来展示当前数据。

UI部分仿制路由设计模式,点击事件的处理方式都由路由中心决定,在UI处理中我们同样需要一个视图中心来根据不同的show_type来产生不通的视图,就好像一个工厂一样,我给你一个标识符,你返回一个我需要的视图,这里我新建了一个ViewProducter来处理视图,ViewProducter中实现了tableview的数据源方法及代理方法。

存储不同show_type所使用的model

 /*
     1. banner    轮播图    img_ratio
     2    icons    小图下方带文字    colunms
     3    images    一行多个图片均分    colunms,img_ratio
     4    scroll    一行多个图片滚动    img_ratio,固定宽度
     5    labels    一行多个文字带圆角边框    colunms,color
     6    manage    一行通栏文字样式    -
     7    search    搜索样式    orders,filters
     8    list_material    资料列表    -
     9    list_topic    论坛列表    用ontop决定是否是置顶
     10    list_meal    套餐列表    -
     11    list_course    课程列表    -
     12    list_news    资讯列表    -
     13    list_teacher    导师列表
     14    ad_round    左边圆图广告
     15    ad_square    左边方图广告
     */
    private let listClassMap = [
        "icons":"HSMutPicModel", //1
        "images":"HSMutPicModel",//2
        "scroll":"HSMutPicModel",//3
        "labels":"HSMutPicModel",//4
        "banner":"HSMutPicModel",//5
        "list_material":"HSMaterilCellModel",//6
        "list_meal":"HSClasslCellModel",//7
        "list_course":"HSClasslCellModel",//8
        "list_news":"HSListNewsCellModel",//9
        "list_topic":"HSListTopicCellModel",//10
        "list_ontop":"HSListTopicCellModel",//1
        "manage":"HSManageTipsModel",//12
        "ad_round":"HSAdvertiseModelNew",//13
        "ad_square":"HSAdvertiseModelNew",//14
        "list_teacher":"HSTeacherListCellModel",//15
        "search":"HSSearchStyleCellModel",//16
        "video":"HSVideoSectionModel",
        "list_pack":"HSClasslCellModel",
        "list_order":"HSOrderModel",
        "list_video":"HSClasslCellModel",
        "list_goods":"HSClasslCellModel",
        "ad_corner":"HSAdvertiseModelNew",
        "attach":"HSAttachModel",
        "texts":"HSTextsModel",
        "blocks":"HSBlockModel",
        "marquee":"HSMarqueeModel",
        "across":"HSAcrossModel",
        "collect":"HSCollectModel",
        "list_discover":"HSDiscoverModel",
        "square":"HSSquareModel",
        "word":"FilterConModel"
    ];

实现tableview返回cell的方法,根据不同的show_type返回不同的cell


    class func processCell(mutiModel:HSAllKindsCellModel,tableView:UITableView) -> UITableViewCell {
        let show_type = mutiModel.show_type
        switch show_type {
        case "icons":
            let cell:HSIconsCell = HSIconsCell.createCell(tableView: tableView)
            cell.selectionStyle = .none
            cell.cellModel = mutiModel
            return cell
        case "images":
            let cell:HSImagesCell = HSImagesCell.createCell(tableView: tableView)
            cell.cellModel = mutiModel
            cell.selectionStyle = .none
            return cell
        case "scroll":
            let cell:HSScrollCell = HSScrollCell.createCell(tableView: tableView)
            cell.cellModel = mutiModel
            cell.selectionStyle = .none
            return cell
        case "labels":
            let cell:HSLablesCell = HSLablesCell.createCell(tableView: tableView);
            cell.cellModel =  mutiModel
            cell.selectionStyle = .none
            return cell
        case "banner":
            let cell:HSBannerCell = HSBannerCell.createCell(tableView: tableView);
            cell.cellModel =  mutiModel
            cell.selectionStyle = .none
            return cell
        case "list_material":
            let cell:HSMaterialTableViewCell = HSMaterialTableViewCell.createCell(tableView)
            //cell.topic_url = (mutiModel.cellModel as!HSMaterilCellModel).topic_url
            cell.model = mutiModel.cellModel as?HSMaterilCellModel
            cell.selectionStyle = .none
            return cell;
        case "list_news":
            let newmodel = mutiModel.cellModel as? HSListNewsCellModel
            if newmodel!.ontop == true {
                let cell:HSTopicTopCell = HSTopicTopCell.createCell(tableView: tableView)
                let topmodel = HSListTopicCellModel()
                topmodel.title = (newmodel?.title)!
                cell.cellModel = topmodel
                cell.selectionStyle = .none
                return cell
            }
            else
            {
                let cell:HSNewsListCell = HSNewsListCell.createCell(tableView: tableView)
                cell.cellModel = mutiModel.cellModel as? HSListNewsCellModel
                cell.selectionStyle = .none
                return cell
            }
            
        case "list_topic":
            let topicModel:HSListTopicCellModel = (mutiModel.cellModel as? HSListTopicCellModel)!
            if topicModel.ontop==true {
                let cell:HSTopicTopCell = HSTopicTopCell.createCell(tableView: tableView)
                cell.cellModel = topicModel
                cell.selectionStyle = .none
                return cell
            }
            else
            {
                let cell:HSTopicsContentCell = HSTopicsContentCell.createCell(tableView)
                cell.model = topicModel
                cell.selectionStyle = .none
                return cell
            }
        case "manage":
            let cell:HSManageCell = HSManageCell.createCell(tableView: tableView)
            cell.cellModel =  mutiModel.cellModel as? HSManageTipsModel
            cell.selectionStyle = .none
            return cell;
        case "ad_square":
            let cell:HSAdvertiseCell = HSAdvertiseCell.dashabicell(with: tableView)
            cell.celllModel = (mutiModel.cellModel as? HSAdvertiseModelNew)?.data_list![0]
            cell.selectionStyle = .none
            return cell;
        case "ad_round":
            let cell:HSAdvertiseCircleImageCell = HSAdvertiseCircleImageCell.dashabicell(with: tableView)
            cell.cellModel = (mutiModel.cellModel as? HSAdvertiseModelNew)?.data_list![0]
            cell.selectionStyle = .none
            return cell;
        case "list_teacher":
            let cell:HSTeacherListCell = HSTeacherListCell.createCell(tableView: tableView)
            cell.cellModel =  mutiModel.cellModel as? HSTeacherListCellModel
            cell.selectionStyle = .none
            return cell;
        case "search":
            let cell:HVSearchCell = HVSearchCell.createCell(tableView: tableView)
            cell.cellModel = mutiModel.cellModel as? HSSearchStyleCellModel
            cell.selectionStyle = .none
            return cell
        case "list_course","list_meal","list_pack","list_video","list_goods":
            let cell:HSClassCell = HSClassCell.createCell(tableView: tableView);
            cell.isRelate = false;
            let cellModel = mutiModel.cellModel as? HSClasslCellModel
            cell.showType = show_type
            if show_type == "list_goods" {
                cell.GoodsModel = cellModel
            }
            else
            {
                cell.CourseModel = cellModel
            }
            mutiModel.cellHeight = cell.cellHeight
            cell.selectionStyle = .none
            return cell
        case "video":
            let cell:HSVideoListCell = HSVideoListCell.createCell(tableView: tableView);
            let cellModel = mutiModel.cellModel as? HSVideoSectionModel
            cell.cellModel = cellModel;
            cell.selectionStyle = .none
            return cell
        case "list_order":
            let cell:HSOrderCell = (tableView.dequeueReusableCell(withIdentifier: "HSOrderCell") as? HSOrderCell)!
            let cellModel = mutiModel.cellModel as? HSOrderModel
            cell.cellModel = cellModel
            cell.selectionStyle = .none;
            return cell
        case "ad_corner":
            let cell:HSAdCornerCell = (tableView.dequeueReusableCell(withIdentifier: "HSAdCornerCell") as? HSAdCornerCell)!
            let cellModel = (mutiModel.cellModel as? HSAdvertiseModelNew)?.data_list?.first
            cell.cellModel = cellModel;
            cell.selectionStyle = .none
            return cell
        case "attach":
            let cell:HSAttentTableViewCell = (tableView.dequeueReusableCell(withIdentifier: "HSAttentTableViewCell") as? HSAttentTableViewCell)!
            let cellModel = mutiModel.cellModel as? HSAttachModel
            if !hs_isEmptyString(cellModel?.image) {
                cell.imageimageView.sd_setImage(with: URL.init(string: cellModel!.image!), placeholderImage: DefultImage)
            }
            cell.titletitleLabel.text = cellModel?.title
            cell.nameLabel.text = cellModel?.name
            cell.messageLabel.text = cellModel?.message
            cell.selectionStyle = .none
            return cell
        case "texts":
            let cell:HSTextsCell = HSTextsCell.createCell(tableView: tableView)
            let cellModel = mutiModel.cellModel as? HSTextsModel
            cell.cellModel = cellModel;
            cell.selectionStyle = .none
            return cell
        case "blocks":
            let cell:HSBlockCell = HSBlockCell.createCell(tableView: tableView)
            let cellModel = mutiModel.cellModel as? HSBlockModel
            if cellModel != nil {
                cell.cellModel = cellModel
            }
            cell.selectionStyle = .none
            return cell
        case "marquee":
            let cell:HSMarqueeCell = HSMarqueeCell.createCell(tableView: tableView)
            cell.cellModel = mutiModel.cellModel as? HSMarqueeModel
            return cell
        case "across":
            let cell:HSArcossCell = HSArcossCell.createCell(tableView: tableView)
            cell.cellModel = mutiModel.cellModel as? HSAcrossModel
            cell.selectionStyle = .none
            return cell
        case "collect":
            let cell:HSCollectCell = HSCollectCell.createCell(tableView: tableView)
            let cellModel = mutiModel.cellModel as? HSCollectModel
            cell.cellModel = cellModel;
            cell.selectionStyle = .none
            return cell
            
        case "list_discover":
            let cell:HSDiscoverCell = HSDiscoverCell.createCell(tableView: tableView)
            let cellModel = mutiModel.cellModel as? HSDiscoverModel
            cell.cellModel = cellModel;
            cell.selectionStyle = .none
            return cell
        case "square":
            let cell:HSSquareCell = HSSquareCell.createCell(tableView: tableView)
            let cellModel = mutiModel.cellModel as? HSSquareModel
            cell.cellModel = cellModel;
            cell.selectionStyle = .none
            return cell
        case "word":
            let cell:HSWordCell = (tableView.dequeueReusableCell(withIdentifier: "HSWordCell") as? HSWordCell)!
            let cellModel = mutiModel.cellModel as? FilterConModel
            cell.model = cellModel;
            cell.selectionStyle = .none
            return cell
            
        default:
            return UITableViewCell.init(style:.default , reuseIdentifier: "none")
        }
    }

实现返回cell高度的方法

    class func processCellHeight(mutiModel:HSAllKindsCellModel) -> CGFloat{
        
        let show_type = mutiModel.show_type
        if show_type == "banner"||show_type == "labels"||show_type == "scroll"||show_type == "images"||show_type == "icons" {
            return mutiModel.cellHeight;
        }
        else if(show_type == "list_topic")
        {
            let topicModel:HSListTopicCellModel = (mutiModel.cellModel as? HSListTopicCellModel)!
            if topicModel.ontop==true {
                return 40
            }
            else{
                return 80
            }
        }
        else if(show_type == "list_teacher")
        {
            return 90
        }
        else if(show_type == "manage")
        {
            return 50
        }
        else if(show_type == "search")
        {
            return 44
        }
        else if(show_type == "list_meal"||show_type == "list_course"||show_type == "list_pack")
        {
            return mutiModel.cellHeight;
        }
        else if(show_type == "list_goods")
        {
            return mutiModel.cellHeight;
        }
        if show_type == "video" {
            let allkinds = mutiModel.cellModel as? HSVideoSectionModel
            return (HSwidth/allkinds!.hs_getSafeImgRatio())
        }
        if show_type == "scroll" {
            return 40;
        }
        if show_type == "list_material" {
            return ((mutiModel.cellModel as?HSMaterilCellModel)?.cellHeight)!;
        }
        else if show_type == "list_order"{
            return 100
        }
        else if show_type == "list_material" {
            return 70.5
        }
        else if show_type == "attach" {
            return 135
        }
        else if show_type == "texts" {
            let model = mutiModel.cellModel as!HSTextsModel
            return 36*ceil(CGFloat(CGFloat(model.data_list!.count)/model.hs_getSafeColumns()))
        }
        else if show_type == "blocks" {
            if mutiModel.cellModel == nil {
                return 0.001;
            }
            let cellModel = mutiModel.cellModel as!HSBlockModel
            let padding:CGFloat = 10.0
            
            let itemW = (HSwidth-(CGFloat((cellModel.hs_getSafeColumns()))+1.0)*padding)/CGFloat((cellModel.hs_getSafeColumns()))
            let itemH = itemW/(cellModel.hs_getSafeImgRatio())+21+15+5+5
            let line = ceil(CGFloat(CGFloat(cellModel.data_list!.count)/CGFloat(cellModel.hs_getSafeColumns())))
            return itemH*CGFloat(line) + 10.0*(CGFloat(line+1))
        }
        else if show_type == "marquee" {
            return 60
        }
        else if show_type == "across" {
            return 40
        }
        else if show_type == "collect" {
            let model = mutiModel.cellModel as!HSCollectModel
            return 36*ceil(CGFloat(CGFloat(model.data_list!.count)/model.hs_getSafeColumns()))
        }
        else if show_type == "list_discover" {
            return 80
        }
        else if show_type == "word" {
            return ((mutiModel.cellModel as?FilterConModel)?.cellHeight)!+50;
        }
        else if show_type == "square" {
            if mutiModel.cellModel == nil {
                return 0.001;
            }
            let cellModel = mutiModel.cellModel as!HSSquareModel
            let padding:CGFloat = 10.0
            
            let itemW = (HSwidth-(CGFloat((cellModel.hs_getSafeColumns()))+1.0)*padding)/CGFloat((cellModel.hs_getSafeColumns()))
            let itemH = itemW/(cellModel.hs_getSafeImgRatio())+21+15+5+5+10
            let line = ceil(CGFloat(CGFloat(cellModel.data_list!.count)/CGFloat(cellModel.hs_getSafeColumns())))
            return itemH*CGFloat(line) + 10.0*(CGFloat(line+1))
        }
        return 80;
    }

返回cell的Headerview的方法

    class func processViewForHeader(mutiModel:HSAllKindsCellModel,tableView:UITableView) -> UIView{
        if !hs_isEmptyString(mutiModel.cellHeaderModel?.header)
        {
            let backView = UIView()
            if !hs_isEmptyString(mutiModel.cellHeaderModel?.header) {
                backView.frame = CGRect(x: 0, y: 0, width: HSwidth, height:CGFloat((mutiModel.cellHeaderModel?.space_type)!)*3)
            } else {
                backView.frame = CGRect(x: 0, y: 0, width: HSwidth, height:3)
            }
            
            let spaceV = UIView()
            spaceV.backgroundColor = UIColor.clear
            
            let has_more:Bool = !hs_isEmptyString(mutiModel.cellHeaderModel!.more_url)
            let headerView:HSComSectionHeaderView = HSComSectionHeaderView.createTableSectionHeader(hasMore: has_more, tableView: tableView)
            mutiModel.cellHeaderModel!.subtitle = "更多"
            headerView.sectionModel = mutiModel.cellHeaderModel
            backView.addSubview(spaceV)
            backView.addSubview(headerView)
            spaceV.snp.makeConstraints({ (make) in
                make.left.top.right.equalTo(backView)
                make.height.equalTo(((mutiModel.cellHeaderModel?.space_type)!)*3)
            })
            headerView.snp.makeConstraints({ (make) in
                make.left.right.bottom.equalTo(backView)
                make.top.equalTo(spaceV.snp.bottom)
            })
            return backView;
        }
        if mutiModel.space_type != 0 {
            let backview = UIView.init(frame: CGRect(x: 0, y: 0, width: HSwidth, height: CGFloat(mutiModel.space_type)*3.0));
            backview.backgroundColor = UIColor.init(hexString: "eeeeee")
            if (mutiModel.show_type == "list_topic") {
                backview.backgroundColor = UIColor.clear;
            }
            return backview
        }
        
        let backview = UIView.init(frame: CGRect(x: 0, y: 0, width: HSwidth, height: 0.5));
        backview.backgroundColor = UIColor.init(hexString: "eeeeee")
        if (mutiModel.show_type == "list_topic") {
            backview.backgroundColor = UIColor.clear;
        }
        return backview
    }
   
    class func processHeightForHeaderInSection(mutiModel:HSAllKindsCellModel) -> CGFloat{
        if !hs_isEmptyString(mutiModel.cellHeaderModel?.header) {
            return 40 + CGFloat((mutiModel.cellHeaderModel?.space_type)!)*3
        }
        if mutiModel.space_type != 0 {
            return CGFloat(mutiModel.space_type)*3.0
        }
        return 0.5;
    }

实现cell的点击方法,这里cell的点击方法都传入到路由中心中统一处理

  class func processCellSelect(mutiModel:HSAllKindsCellModel) -> Void{
        Router.process(with: mutiModel);
    }
各种cell1.jpg
各种cell2.jpg

说明:这里新建viewProducter是后期需求逐渐变更的产物,开始所有的tableview代理方法都是写在一个VC当中的,但是随着版本的迭代,有一些固定页面也要支持通用的show-type,所以后来才把代理方法提取放在一个类中,这样就解决了,固定页面的tableview中使用通用解析的cell,只需要通过判断当前data是否含有show-type,如果有就交给viewproducter,没有就返回固定cell。

总结:1.通过这样的UI处理方式,UI展示样式由服务器端配置决定
2.UI展示顺序由服务器端决定(例如轮播图可放在任意位置,只取决于在array中的index)
3.固定页面也可以扩展业务,随时随地修改比较方便,我们不用总是天天改UI(这个还是比较爽的)
4.解决了对路由点击事件灵活性的限制(例如有一个图表页面,可以是今年的销售统计,也可以是用户注册统计,但是图标是不一样的,能更好的配合点击事件)

相关:iOS 浅析路由设计模式

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259