90378高仿 淘宝 -标签控制器 cell

转眼就到了18年的最后一个月份了,想必大家 一定都在期待 新年的到来吧,那小编就先在这里提前祝大家新年快乐了
在这里插入图片描述新年快乐

好了,上期我们有了解了ARC的运行方式以及Java语言的增删效果…
这期我们来简单了解一下S4语言的网络数据请求,
关于网络数据请求我们常见的有Get和POST请求.

GET

//MARK:-------------------获取网络数据-----------------
    func getNetData() -> Void {
        //菊花转动
        self.hud?.show(true)
        UIApplication.shared.isNetworkActivityIndicatorVisible = true
        
        
        //(1)网址字符串拼接
        let appKey = "1b9f570e367ce24e51135d69eac7d04e"
        
        var urlStr = "http://web.juhe.cn:8080/finance/gold/shgold?key=\(appKey)"
        //(2)将网址字符串做成网址对象
        let url = URL.init(string: urlStr)
        //(3)封装为请求对象,同时设置缓存策略和超时时长
        let req = URLRequest.init(url: url!, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0)
        //(4)连接服务器请求网络数据
        let task:URLSessionDataTask =  URLSession.shared.dataTask(with: req) { (data:Data?, response:URLResponse?, neterror:Error?) in
            
            //在主线程队列中异步执行,停止转动指示器
            DispatchQueue.main.async {
                
            self.hud?.hide(true)
            UIApplication.shared.isNetworkActivityIndicatorVisible = false
                //停止下拉刷新
                self.mjHeader?.endRefreshing()
                
            }
            //如果发生了服务器错误或请求超时
            if neterror  != nil  {
                
                DispatchQueue.main.async {
                    self.showMBAlert(msg: "服务器错误")
                }
                return
            }

            //json数据转化
            let jsonData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)
            
            
            //使用guarde-else语句
            guard let rightData = jsonData else{
                DispatchQueue.main.async {
                    self.showMBAlert(msg: "网络数据错误")
                }
                return
            }
            
            let dataDic = rightData as! [String:Any]
            
            
            let resultcode = dataDic["resultcode"] as! String
            
            let reason = dataDic["reason"] as! String
            
            
            if resultcode != "200" {
                
                DispatchQueue.main.async {
                    self.showMBAlert(msg: reason)
                }
                return
                
            }
            
            //获取result数组
            let result = dataDic["result"] as! NSArray
//            let result = dataDic["result"] as! [[String:[String:String]]]
            
            
            //获取最外层的字典
            let allDic = result[0] as! NSDictionary
            
            //开辟
            self.tableData = []
            
            //遍历字典中的键值对
            for oneDic in allDic.allValues{
                
                let oneGold = Gold.init()
                oneGold.setValuesForKeys(oneDic as! [String:String])
                
                self.tableData?.append(oneGold)
            }
            DispatchQueue.main.async {
                self.table?.reloadData()
            }
            
//            //在全局并发队列中异步执行,相当于开辟新的子线程
//            DispatchQueue.global().async {
//
//            }
            
        }
        //(5)启动任务
        task.resume()
        
    }
    
    //MARK:---------------------viewdidload----------------

}```

==POST==

//(1)指示器转动
UIApplication.shared.isNetworkActivityIndicatorVisible = true
//(2)网络请求
//<1>网址字符串拼接
let urlStr = “http://py.cmshop.net/tPyshNewnoticController.do?godongtai2&style2=(titlIndex)
//<2>转换为url地址
let url = URL.init(string: urlStr)
//<3>请求对象,并设置缓存策略超时时长
let req = URLRequest.init(url: url!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 8.0)
//<4>连接服务器任务
let task = URLSession.shared.dataTask(with: req){
(data,response,error) in

        //停止指示器
        DispatchQueue.main.async {
            UIApplication.shared.isNetworkActivityIndicatorVisible = false
            
            self.mjHeader?.endRefreshing()
        }
        //如果服务器连接失败或超时
        if error != nil{
            
            DispatchQueue.main.async {
                self.view.showMBAlert(msg: "服务器错误")
            }
            return
        }
        
        
        //如果连接服务器成功,将二进制数据转换为数组字典
        let jsonData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)
        //如果jsonData为nil表示转换失败,后台提供的json数据是错误的
        if jsonData == nil{
            DispatchQueue.main.async {
                self.view.showMBAlert(msg: "网络数据错误")
            }
            return
        }
        //转换成功,将数据强转为字典类型
        let jsonDic = jsonData! as! NSDictionary
        
        //获取resultcode值
        let resultcode = jsonDic["resultcode"] as! String
        
        //如果resultcode不为0,表示有错误发生,给出客户提示
        if resultcode != "0" {
            
            let errmsg = jsonDic["errmsg"] as! String
            DispatchQueue.main.async {
                self.view.showMBAlert(msg: errmsg)
            }
            return
            
        }
        
        
        //如果数据都正确,做json解析
        
        let dataArr = jsonDic["data"] as! [[String:Any]]
        
        self.tableData = News.createNewsArray(arr:dataArr)
        
        //回到主线程刷新表格
        DispatchQueue.main.async {
            self.table?.reloadData()
        }
        
    }
    
    //<5>开启任务
    task.resume()
}



那么就简单的了解一下详细的代码吧
![文件列表](https://img-blog.csdnimg.cn/20190307200339168.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzc3NTk5OA==,size_16,color_FFFFFF,t_70)



  ================== (1)EXten.Alert======================

import UIKit

extension UIView {

//显示MB提示框
func showMBAlert(msg:String) -> Void {
//实例化MB
let alert = MBProgressHUD.init(view: self)

    //设置提示为文本样式
    alert?.mode = MBProgressHUDModeText
    
    //设置隐藏时自动从父视图移除
    alert?.removeFromSuperViewOnHide = true
    
    //设置显示的提示文本
    alert?.labelText = msg
    
    //添加为子视图
    self.addSubview(alert!)
    
    //显示提示框
    alert?.show(true)
    
    //设置几秒自动隐藏
    alert?.hide(true, afterDelay: 3.0)
}

}




================== (2)Student类======================

==h==

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Student : NSObject
@property(nonatomic,strong)NSString * type;
@property(nonatomic,strong)NSString * id;
@property(nonatomic,strong)NSString * img;
@property(nonatomic,strong)NSString * title;
@property(nonatomic,strong)NSString * read_num;
@property(nonatomic,strong)NSString * content;
@property(nonatomic,strong)NSString * author;
@property(nonatomic,strong)NSString * create_time;
//把得到的json数据中的data数组转换为Student数组
+(NSArray<Student >)createNewsArrWithDataArr:(NSArray *)dataArr;

@end

NS_ASSUME_NONNULL_END


==m==

#import “Student.h”

@implementation Student
+(NSArray<Student >)createNewsArrWithDataArr:(NSArray *)dataArr{
//定义可变数组,用于储存3Student对象
NSMutableArray * newsArr = [[NSMutableArray alloc]init];

//遍历dataArr中的每个字典
for (NSDictionary * dic in dataArr){
    //将每个dic转化为Student对象
    Student * one = [[Student alloc]init];
    
    //对one的属性赋值
    [one setValuesForKeysWithDictionary:dic];
    
    //把每次循环生成的one对象加入到数组中
    [newsArr addObject:one];
}
//在循环外,将newsArr返回
return [newsArr copy];

}
@end

==桥接 文件==

#import “Student.h”
#import “UIImageView+WebCache.h”
#import “MJRefresh.h”
#import “MBProgressHUD.h”




================== (3)baset类======================

import UIKit

class BaseViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
  self.view.backgroundColor = UIColor.white
    self.navigationController?.navigationBar.isTranslucent = false
}
}

================== (3)One类======================

import UIKit
//屏幕的宽
var scrW = UIScreen.main.bounds.size.width
//屏幕的高
var scrH = UIScreen.main.bounds.size.height

class OneViewController: BaseViewController,UITableViewDelegate,UITableViewDataSource {

//MARK:--------------------属性的声明------------------
var tbv:UITableView?
var tbvData:[Student]?
var segment:UISegmentedControl?
var titles = ["推荐新闻","实时对话","行情分析","专栏"]
var onetitle = ["1","2","3","4"]
//下拉刷新控件
var mjHeader:MJRefreshHeaderView?

//MARK:--------------------UI创建------------------
func initUI() {
    //创建segment分段控制器
    self.segment = UISegmentedControl.init(items: titles)
    
    //设置位置
    self.segment?.frame = CGRect.init(x: 0, y: 0, width: scrW, height: 40)
    
    //设置默认选中的下标
    self.segment?.selectedSegmentIndex = 0
    
    //自动获取第一个标题的新闻数据
    self.getURLData(titleIndex: onetitle[0])
    
    //设置触发方法
    self.segment?.addTarget(self, action: #selector(segmentDidChange(seg:)), for: .valueChanged)
    
    self.segment?.tintColor = UIColor.black
    
    //添加到view子视图
    self.view.addSubview(self.segment!)
    
    
    
    //实例化表格
   self.tbv = UITableView.init(frame: CGRect.init(x: 0, y: 40, width: scrW, height: scrH - 40), style: .plain)
    
    
    //设置代理和数据源
    self.tbv?.delegate = self
    self.tbv?.dataSource = self
    
    //添加到子视图
    self.view.addSubview(self.tbv!)
    
    
    //实例化下拉刷新的控件
    self.mjHeader = MJRefreshHeaderView.init(scrollView: self.tbv!)
    
    //设置刷新的回调的闭包
    self.mjHeader?.beginRefreshingBlock = {refreshView in
        
    }
    
    self.tbv?.rowHeight = 150
}


//MARK:--------------------UI控件的触发方法------------------
@objc func segmentDidChange(seg:UISegmentedControl) -> Void {
    //根据选中的分段下标获取对应的标题,获取网络数据
    self.getURLData(titleIndex: titles[seg.selectedSegmentIndex])
}

//MARK:-------------------viewDidLoad-------------------
override func viewDidLoad() {
    super.viewDidLoad()
     self.initUI()
    

    
    
   
}



//MARK:------------------代理和数据源的实现的方法-------------------
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if let count = self.tbvData?.count{
        return count
    }
    return 0
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   //定义一个标识符
    let identifier = "Mycell"
    var cell = tableView.dequeueReusableCell(withIdentifier: identifier) as? StudentTableViewCell
    
    if cell == nil{
        cell = StudentTableViewCell.init(style: .subtitle, reuseIdentifier: identifier)
    }
    if let oneNew = self.tbvData?[indexPath.row]{
        //图片
        cell?.imgview?.sd_setImage(with: URL.init(string: oneNew.img), completed: nil)
        
        //标题
        cell?.titleLabel?.text = oneNew.title
        
        //作者
        cell?.author?.text = "作者\(oneNew.author)"
        
        //阅读量
        cell?.readNum?.text = "阅读量:\(oneNew.read_num)"
    }
    
    
    return cell!
}

//MARK:--------------------获取网络请求数据------------------
func getURLData(titleIndex:String) -> Void {
    //转动指示器
    UIApplication.shared.isNetworkActivityIndicatorVisible = true
    
    //网络请求,网址字符串拼接
    let url = URL.init(string: "http://buluokes.huimor.com/api")
    
    //创建请求对象,同时设置缓存策略及超时时长
    var req = URLRequest.init(url: url!, cachePolicy: .reloadRevalidatingCacheData, timeoutInterval: 5.0)
    
    //设置POST请求
    req.httpMethod = "POST"
    
    //把请求参数拼接成字符串
    let paramStr = "method=app.news.getarticlelist&class_id\(titleIndex)&page=1&user_token="
    
    //将参数字符串转换为二进制Data数据
    let paramData = paramStr.data(using: .utf8)
    
    //将参数二进制数据放入请求体中
    req.httpBody = paramData
    
    //正式请求网络数据,使用URLsession
    let task = URLSession.shared.dataTask(with: req) { (data, response, error) in
        //回到UI主线程停止转动指示器
        DispatchQueue.main.async {
            UIApplication.shared.isNetworkActivityIndicatorVisible = false
            self.mjHeader?.endRefreshing()
        }
        
        //如果服务器错误,给客户提示
        if error != nil{
            DispatchQueue.main.async {
               self.view.showMBAlert(msg: "服务器错误")
            }
            return
        }
        
        //如果连接成功,将二进制数据转换为数组或字典
        let jsonData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)
        
        //如果转换失败
        if  jsonData  == nil{
            DispatchQueue.main.async {
                self.view.showMBAlert(msg: "json数据解析错误")
            }
            return
        }
        
        //t如果转换成功,将数据转换为字典类型
        let jsonDic = jsonData as! NSDictionary
        
        //获取code值
        let oneCode = jsonDic["code"] as! Int
        
        //如果code的值不为200 ,表示有错误发生,给出用户提示
        if  oneCode != 200{
            DispatchQueue.main.async {
                self.view.showMBAlert(msg: "code值不是200")
            }
            return
        }
        
        //如果数据都正确,做JSON解析
        let resultDic = jsonDic["data"] as! NSDictionary
        let dataArr = resultDic["list"] as! NSArray
        print(dataArr)
        
        //将dataArr转换为News数组,赋值给表格数据数组
        self.tbvData = Student.createNewsArr(withDataArr: dataArr as! [Any])
        
        //刷新表格
        DispatchQueue.main.async {
            self.tbv?.reloadData()
        }

        
        
    }
    task.resume()
}

}




================== (4)StudentTableViewCell======================

import UIKit

class StudentTableViewCell: UITableViewCell {

//图片视图
var imgview:UIImageView?

//标题标签
var titleLabel:UILabel?

//作者标签
var author:UILabel?

//阅读量
var readNum:UILabel?

func initUI() {
    //图片
    self.imgview = UIImageView.init(frame: CGRect.init(x: 5, y: 5, width: 140, height: 140))
    self.contentView.addSubview(self.imgview!)
    
    
    //标题
    self.titleLabel = UILabel.init(frame: CGRect.init(x: 145, y: 5, width: scrW - 155, height: 50))
    
    self.titleLabel?.font = UIFont.systemFont(ofSize: 20.0)
    
    self.contentView.addSubview(self.titleLabel!)
    
    
    //作者标签
    self.author = UILabel.init(frame: CGRect.init(x: 145, y: 80, width: 150, height: 40))
    
    self.author?.font = UIFont.systemFont(ofSize: 17.0)
    
    self.author?.textColor = UIColor.gray
    
    self.contentView.addSubview(self.author!)
    
    //阅读量
    self.readNum = UILabel.init(frame: CGRect.init(x: 300, y: 80, width: 150, height: 40))
    
    self.readNum?.font = UIFont.systemFont(ofSize: 17.0)
    
    self.readNum?.textColor = UIColor.gray
    
    self.contentView.addSubview(self.readNum!)
    
    
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    self.initUI()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

}





================== (5)StudentTableViewCell======================

let oneVC = OneViewController()
let oneNav = UINavigationController.init(rootViewController: oneVC)
oneNav.tabBarItem = UITabBarItem.init(title: “新闻”, image: UIImage.init(named: “”), tag: 1)
oneVC.navigationItem.title = “我的新闻”

    let twoVC = TwoViewController()
    let twoNav = UINavigationController.init(rootViewController: twoVC)
    twoNav.tabBarItem = UITabBarItem.init(title: "娱乐", image: UIImage.init(named: ""), tag: 2)
    twoVC.navigationItem.title = "我的娱乐"
    
    
    let tbc = UITabBarController()
    tbc.viewControllers = [oneNav,twoNav]
    self.window?.rootViewController = tbc



END



11111111111111
1111111111111
111111111111
11111111111
1111111111
111111111
11111111
1111111
111111
11111
1111
111
11
1
标签控制器



懒惰初始化

使用lazy关键字可以让变量在使用的时候再初始化。

Global的变量是自动懒惰初始化的,不需要lazy关键字。
Static的变量也是自动懒惰初始化的,不需要lazy关键字。
Property变量用关键字lazy进行懒惰初始化。


如果没有lazy关键字,是不能通过编译的,因为MyView还没有初始化,不能调用实例方法。

一个比较常用的技术手段是结合使用define and call的函数来初始化lazy的成员变量:

//初始化
let one = oneViewController()
let two = VCTwo()
let three = threeViewController()
let four = fourViewController()
let five = fiveViewController()

    let oneNav = UINavigationController(rootViewController: one)
    let twoNav = UINavigationController(rootViewController: two)
    let threeNav = UINavigationController(rootViewController: three)
    let fourNav = UINavigationController(rootViewController: four)
    let fiveNav = UINavigationController(rootViewController: five)
    
    //添加图片
    oneNav.tabBarItem.image = UIImage(named: "tabbar_me")
    twoNav.tabBarItem.image = UIImage(named: "tabbar_me")
    threeNav.tabBarItem.image = UIImage(named: "tabbar_me")
    fourNav.tabBarItem.image = UIImage(named: "tabbar_me")
    fiveNav.tabBarItem.image = UIImage(named: "tabbar_me")
    
    //添加标题
    oneNav.tabBarItem.title = "1"
    oneNav.tabBarItem.title = "2"
    oneNav.tabBarItem.title = "3"
    oneNav.tabBarItem.title = "4"
    oneNav.tabBarItem.title = "5"
    
    //添加
    let  tabbar  = UITabBarController()
    
    tabbar.viewControllers = [oneNav,twoNav,threeNav,fourNav,fiveNav]
    tabbar.selectedViewController = twoNav
    
    //设置跟视图

    self.window?.rootViewController = tabbar
    self.window?.backgroundColor = UIColor.white


MD

import UIKit

class OneMD: NSObject {

var headImg:String
var title:String
var detailTitle:String
var img:String
var time:String
var num:String
var type:String
init(headImg:String,title:String,detailTitle:String,img:String,time:String,num:String,type:String) {
    
    self.headImg = headImg
    self.title = title
    self.time = time
    self.detailTitle = detailTitle
    self.img = img
    self.num = num
    self.type = type
    
}

}


无论是类成员还是全局变量,都可以定义成计算变量,就是在使用的时候计算一个值出来,而不是保存这个值。也就是getter和setter。

ALL

import UIKit

class VWC: UIViewController,UITableViewDelegate,UITableViewDataSource {

let mArr:NSMutableArray = []
var cellHight:CGFloat = 0
var tv:UITableView?

override func viewDidLoad() {
    super.viewDidLoad()
    
    // Do any additional setup after loading the view.
    
    NotificationCenter.default.addObserver(self, selector: #selector(test), name: NSNotification.Name(rawValue:"cellHight"), object: nil)
    
    view.backgroundColor = UIColor.white
    
    let path = Bundle.main.path(forResource: "daren", ofType: "json")
    let url = URL(fileURLWithPath: path!)
    
    do {
        let data = try Data(contentsOf: url)
        let jsonData:Any = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers)
        // print(jsonData)
        let jsonArr:NSArray = jsonData as! NSArray
        print(jsonArr)
        
        for item in jsonArr {
            
            let k:NSDictionary = item as! NSDictionary
            
            if k.object(forKey: "type") as! String == "0"{
                
                let md:OneMD = OneMD(headImg: k.object(forKey: "head") as! String, title: k.object(forKey: "title") as! String, detailTitle: k.object(forKey: "detailTitle") as! String, img: k.object(forKey: "img") as! String, time: k.object(forKey: "time") as! String, num: k.object(forKey: "num") as! String, type: k.object(forKey: "type") as! String)
                mArr.add(md)
                
            }else if k.object(forKey: "type") as! String == "1" {
                
                let md:TwoMD = TwoMD(headImg: k.object(forKey: "head") as! String, title: k.object(forKey: "title") as! String, detailTitle: k.object(forKey: "detailTitle") as! String, img: k.object(forKey: "img") as! NSMutableArray, time: k.object(forKey: "time") as! String, num: k.object(forKey: "num") as! String, type: k.object(forKey: "type") as! String)
                mArr.add(md)
            }else{
                let md:ThreeMD = ThreeMD(headImg: k.object(forKey: "head") as! String, title: k.object(forKey: "title") as! String, detailTitle: k.object(forKey: "detailTitle") as! String, img: k.object(forKey: "img") as! String, time: k.object(forKey: "time") as! String, num: k.object(forKey: "num") as! String, type: k.object(forKey: "type") as! String)
                mArr.add(md)
            }
            
        }
        
        
        
    } catch let error as Error? {
        print(error as Any)
    }
    
    
    tv = UITableView(frame:CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height-120), style: .plain)
    view.addSubview(tv!)
    
    tv!.delegate = self
    tv!.dataSource = self
    
    tv!.register(UINib(nibName: "OneCell", bundle: Bundle.main), forCellReuseIdentifier: "cell1")
    tv?.register(UINib(nibName: "TwoCell", bundle: Bundle.main), forCellReuseIdentifier: "cell2")
    tv!.register(UINib(nibName: "ThreeCell", bundle: Bundle.main), forCellReuseIdentifier: "cell3")
    
    tv!.tableFooterView = UIView()
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return mArr.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    let item = mArr[indexPath.row]
    
    if item is OneMD{
        let md:OneMD = mArr[indexPath.row] as! OneMD
        
        let cell:OneCell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! OneCell
        cell.setCellWithData(model: md)
        return cell
    } else if item is TwoMD{
        let md:TwoMD = mArr[indexPath.row] as! TwoMD
        
        let cell:TwoCell = tableView.dequeueReusableCell(withIdentifier: "cell2") as! TwoCell
        cell.setCellWithData(model: md)
        print(cellHight)
        return cell
    }else{
        let md:ThreeMD = mArr[indexPath.row] as! ThreeMD
        
        let cell:ThreeCell = tableView.dequeueReusableCell(withIdentifier: "cell3") as! ThreeCell
        cell.setCellWithData(model: md)
        return cell
    }
    
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    
    let item = mArr[indexPath.row]
    
    if item is TwoMD{
        return cellHight+10
        
    } else{
        
        return 200
    }
}

@objc func test(nofi : Notification){
    
    cellHight = nofi.userInfo!["post"] as! CGFloat
    tv?.reloadData()
    /// 移除通知
    NotificationCenter.default.removeObserver(self)
}

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值