美文网首页Swift学习
swift 项目实战演练

swift 项目实战演练

作者: 朱允见 | 来源:发表于2018-03-13 14:59 被阅读0次

    发现

    • 偶然间发现一个很好的手把手教学项目,swift直播教学技术,在这里奉献出来,都是很实用的项目实战技术,拿来练手学习非常棒
      网易云课堂

    共同进步,爱生活,爱钻研,爱分享!

    项目实战核心技术分享

    注意: *本文不是简单的代码练习,而是在原项目实战的基础上添加流行的框架尤其是swift中让人头疼的网络解析 模型转换 *

    • 项目中使用的第三方框架

    pod 'Alamofire'
    pod 'SwiftyJSON'
    pod 'Kingfisher'

    • 项目技术点
    1. UIcollectionView 的高级用法,
    2. 类似今日头条的横向菜单
    3. 无限轮播图复用实现
    4. xib 快速布局
    5. Alamofire 组建封装
    6. 三方库的使用
    7. MVVM 思想运用
    8. 算法小技巧

    项目效果

    QQ20180313-140323.gif

    开启代码之旅

    横向菜单原理

    1. 标题部分PageTitleView 自定义UIview
    代码请到github 中下载  https://github.com/zyjian/DouYuZB/
    
    • 这样写是不是很清爽,给类不断的扩展方法让我们的代码结构化方便管理


      50BB7174-A400-4B02-9A1C-B1B16B4BB4B3.png
    1. 下面的content 也是一个自定义的UIView 的子类 PageContentView,上面放了一个UIcollectionView,这是横线滚动
    2. 让PageTitleView 与 PageContentView建立对一个逻辑关系
      这里有点需要注意的就是,慢慢滑动的时候 标题的颜色从orange 渐变到 gray
    // MARK: - 对外暴露方法
    extension PageTitleView {
        func setCurrentIndex(sourceIndex: Int, targetIndex: Int, process: CGFloat) {
            //1.取出sourceLabel targetLabel
            let sourceLabel: UILabel = titleLabels[sourceIndex]
            let targetLabel: UILabel = titleLabels[targetIndex]
            
            
            //2.改变下标值
            currentIndex = targetIndex
            
            //3.移动滑块逻辑
            let moveTotalX = targetLabel.frame.origin.x - sourceLabel.frame.origin.x
            let moveX = moveTotalX * process
            scrollLine.frame.origin.x = sourceLabel.frame.origin.x + moveX
            
            //4.颜色渐变33
            //4.1取出颜色变化范围
            let colorDelta = (kSelectedColor.0 - kNormalColor.0 , kSelectedColor.1 - kNormalColor.1 , kSelectedColor.2 - kNormalColor.2)
            //4.2变化sourceLabel
            sourceLabel.textColor = UIColor.init(r: kSelectedColor.0 - colorDelta.0*process, g: kSelectedColor.1 - colorDelta.1*process, b: kSelectedColor.2 - colorDelta.2 * process, a: 1)
            //4.3变化sourceLabel
            targetLabel.textColor = UIColor.init(r: kNormalColor.0 + colorDelta.0*process, g:kNormalColor.1 + colorDelta.1*process , b: kNormalColor.2 + colorDelta.2*process, a: 1)
            
        }
    } 
    

    PageContentView 监听collectionView滑动 这里有个小算法这样更简单

        func scrollViewDidScroll(_ scrollView: UIScrollView) {
            if isForbidScrollDelegate { return }
            
            let nowOffsetX : CGFloat = scrollView.contentOffset.x
            
            
            var soureceIndex : Int
            var targetIndex :Int
            var process : CGFloat
            //左滑
            if nowOffsetX > beganOffsetX {
                
                //1.确定process
                process = (nowOffsetX/scrollView.frame.width - CGFloat((floor(nowOffsetX/scrollView.frame.width))))
    
                
                //2. 确定 soureceIndex,
                soureceIndex = Int(nowOffsetX/scrollView.frame.width)
                
                //3.确定  targetIndex
                targetIndex = soureceIndex + 1
                if targetIndex >= childVcs.count {
                    targetIndex = childVcs.count - 1
                }
                
                //4.完全划过去
                if nowOffsetX - beganOffsetX == scrollView.frame.width {
                    process = 1
                    targetIndex = soureceIndex
                }
               
                
            }else{
                //右滑
                
                //1.确定process
                process = 1 - (nowOffsetX/scrollView.frame.width - CGFloat((floor(nowOffsetX/scrollView.frame.width))))
    
                //2.确定  targetIndex
                targetIndex = Int(nowOffsetX/scrollView.frame.width)
                
                //3. 确定 soureceIndex,
                soureceIndex = targetIndex + 1
                
                //4.完全划过去
                if soureceIndex >= childVcs.count {
                    process = 1
                    soureceIndex = targetIndex
                }
                
                
                
            }
            Log("soureceIndex:\(soureceIndex) ,targetIndex:\(targetIndex) process:\(process)")
            delegate?.pageContentView(source: soureceIndex, target: targetIndex, process: process)
        }
    
    

    网络请求工具类封装

    import UIKit
    import Alamofire
    
    enum MethodType {
        case get
        case post
    }
    
    extension Dictionary {
        func dic2urlString() -> String {
            let muStr:NSMutableString = NSMutableString()
            
            for (k,v) in self {
                let temp : String = "\(k)=\(v)&"
                muStr.append(temp)        }
            
            return String(muStr.substring(to: muStr.length-1))
        }
    }
    
    class NetworkTools {
        class func requestData(type :MethodType, URLString: String , parameters: [String : Any]? = nil ,finishedCallback:@escaping ( _ result : AnyObject) -> ()) {
            
            //1.获取类型
            let method = type == .get ? HTTPMethod.get : HTTPMethod.post
            
            // 请求头
            var headers: [String : String]? {
                return ["Content-type" : "application/json"]
            }
            //2.发送网络请求
            Alamofire.request(URLString, method: method, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON { (response) in
                
                //3.获取结果
                guard let result = response.result.value else {
                    Log("请求错误\(String(describing: response.result.error))")
                    return
                }
                
                if parameters != nil {
                    Log("\(URLString)?\n\(parameters!.dic2urlString()) \n \(String(describing: response.result.value))")
                }
                //4.将结果返回
                finishedCallback(result as AnyObject)
            }
        }
    }
    
    // 扩展方法
    private extension String {
        var utf8Encoded: Data {
            return data(using: .utf8)!
        }
    }
    

    使用方法

     //3.请求第一部分推荐数据
            NetworkTools.requestData(type: .get, URLString: "http://capi.douyucdn.cn/api/v1/getbigDataRoom", parameters: ["time" : Date.getCurrentTime()]) { (result) in
                let json = JSON(result)
                let data = json["data"].arrayValue
    
                for dic in data{
                    let model = RoomModel.init(jsonData: dic)
                    self.bigDataGroup.room_list.append(model)
                }
                self.bigDataGroup.tag_name = "热门"
                self.bigDataGroup.icon_name = "home_header_hot"
    
            }
    

    SwiftyJSON 的使用 model 类构建

    import UIKit
    import SwiftyJSON
    
    struct RoomModel {
        var specific_catalog:String?
        var vertical_src:String?
        var nickname :String?
        var game_name:String?
        var room_name:String?
        var anchor_city:String?
        var icon_url:String?
        var tag_name:String?
    
        var room_id:Int?
        var show_time:Int?
        var isVertical:Int?
        var owner_uid:Int?
        var online:Int?
        
        
        init() {
            
        }
        init(jsonData:JSON) {
            specific_catalog = jsonData["specific_catalog"].stringValue
            vertical_src = jsonData["vertical_src"].stringValue
            nickname = jsonData["nickname"].stringValue
            game_name = jsonData["game_name"].stringValue
            room_name = jsonData["room_name"].stringValue
            anchor_city = jsonData["anchor_city"].stringValue
            icon_url = jsonData["icon_url"].stringValue
            tag_name = jsonData["tag_name"].stringValue
    
            
            online = jsonData["online"].intValue
            room_id = jsonData["room_id"].intValue
            show_time = jsonData["show_time"].intValue
            isVertical = jsonData["isVertical"].intValue
            owner_uid = jsonData["owner_uid"].intValue
    
        }
    }
    

    什么是MVVM ?

    87E7B604-2232-4C8F-BE4B-CF54A8BDA4C7.jpeg

    看明白了吗?看不懂没关系直接上代码


    26C8049F-FB42-4DD0-AD90-D6F93C540512.png

    MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。modelView 它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。本项目中的Viewmodel 负责处理 网络请求的,这样我们的控制器中更加简单。

    是不是很简单呢

    更多代码详情技巧 请到 Demo 中查看,欢迎留下足迹,共同进步!

    相关文章

      网友评论

        本文标题:swift 项目实战演练

        本文链接:https://www.haomeiwen.com/subject/axdzfftx.html