美文网首页otherS界面
TableViewCell嵌套TableView实现评论列表盖楼

TableViewCell嵌套TableView实现评论列表盖楼

作者: T92 | 来源:发表于2017-02-28 15:57 被阅读310次

    效果




    tableView的使用时需要细心去优化的,我这里就随便做了一下,界面目前没有卡顿现象。

    如上图,我的界面是ViewController中加了一个TableView,tableView分了两组,第一组是显示的问题,第二组显示评论,现在实现的效果:直接点击最下面回复则回复楼主,点第二组cell上的回复层主,层主楼层中的回复不能再被评论。

    思路:

    由于评论条数,字数未知,所以最外层tableViewcell高度不固定,里层tableViewcell高度也不固定,就需要用Autolayout来布局,在这里选择用Snapkit做,在给里面的tableView布局时必须用 tableView.snp_removeConstraints()清空原来的约束,否则会冲突,当然也可以用更新约束的方法,自己尝试

    嵌入的tableViewcell是系统自带的,最外层tableViewcell定制如下

    import UIKit
    
    protocol WenCellStyleTwoDelegate:class {
        func huifuButtonClicked(touser_id:String,answer_id:String)
    }
    class WenWenDetailTableViewCellStyleTwo: UITableViewCell {
    
        //属性
        weak var delegate: WenCellStyleTwoDelegate? = nil
        var headView:WenDetailcellHeadView!
        let titleLabel = UILabel()
        let tableView = UITableView()
        
        //tableViewCell高度数组
        var cellHeightArray = [CGFloat]()
        
        //数据源数组
        var childArray:NSArray? = nil{
            didSet{
                if childArray == nil {
                    return
                }
                //计算本cell中tableView的cell高度
                cellHeightArray.removeAll()
                for item in childArray! {
                    let model = item as! childModel
                    let text = "\(model.mobile_phone)回复\(model.tomobile_phone):\(model.content)"
                    let height = ToolManager.calculateStringSize(text, maxW: kScreen_W - 16, maxH: 10000, fontSize: 17).height
                    cellHeightArray.append(height+10)
                    //                print(cellHeightArray)
                }
                tableView.reloadData()
            }
        }
        
        var model:WenWenCellStyleTwoMode? = nil{
            didSet{
                if model == nil {
                    return
                }
                if model?.child != nil {
                    childArray = nil
                    childArray = model!.child!
                }
                
                let url = NSURL(string: appURL+model!.head_img)
                headView.userHeadImageView.kf_setImageWithURL(url!, placeholderImage: nil)
                headView.userNameLabel.text = ToolManager.stringByX(model!.mobile_phone, startindex: 3, endindex: 7)
                headView.timeLabel.text = model!.timestuts
                
                titleLabel.text = model!.content
                
                setNeedsDisplay()
            }
        }
        
        override func awakeFromNib() {
            super.awakeFromNib()
        }
        
        override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            
            creatUI()
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        override func setSelected(selected: Bool, animated: Bool) {
            super.setSelected(selected, animated: animated)
        }
    
    }
    
    //MARK: - 界面相关
    extension WenWenDetailTableViewCellStyleTwo{
        
        func creatUI(){
            contentView.backgroundColor = UIColor.whiteColor()
            
            let nib = UINib(nibName: "WenDetailcellHeadView", bundle: nil)
            headView = nib.instantiateWithOwner(self, options: nil).first as! WenDetailcellHeadView
            
            contentView.addSubview(headView)
            contentView.addSubview(titleLabel)
            contentView.addSubview(tableView)
            
            //head
            headView.huifuButton.addTarget(self, action: #selector(WenWenDetailTableViewCellStyleTwo.buttonClicked(_:)), forControlEvents: .TouchUpInside)
            
            //titleLabel
            titleLabel.numberOfLines = 0
            titleLabel.textColor = UIColor.darkGrayColor()
            titleLabel.font = UIFont.systemFontOfSize(17)
            
            //tableView
            tableView.separatorStyle = .None
            tableView.tableFooterView = UIView()
            tableView.delegate = self
            tableView.dataSource = self
            tableView.userInteractionEnabled = false
            
        }
        
        override func layoutSubviews() {
            super.layoutSubviews()
            if model == nil {
                return
            }
            headView.snp_makeConstraints { (make) in
                make.left.equalTo(self.snp_left)
                make.right.equalTo(self.snp_right)
                make.top.equalTo(self.snp_top)
                make.height.equalTo(70)
            }
            
            titleLabel.snp_makeConstraints { (make) in
                make.left.equalTo(self.snp_left).offset(8)
                make.right.equalTo(self.snp_right).offset(-8)
                make.top.equalTo(headView.snp_bottom)
                make.height.equalTo(ToolManager.calculateStringSize(model!.content, maxW: kScreen_W - 16, maxH: 1000, fontSize: 18).height)
            }
            
            tableView.snp_removeConstraints()
            tableView.snp_makeConstraints { (make) in
                make.left.equalTo(self.snp_left)
                make.right.equalTo(self.snp_right)
                make.top.equalTo(titleLabel.snp_bottom)
                var height:CGFloat = 4
                for item in cellHeightArray {
                    height += item
                }
                //                print(height)
                make.height.equalTo(height)
            }
        }
    }
    
    //MARK: - 协议
    extension WenWenDetailTableViewCellStyleTwo:UITableViewDelegate,UITableViewDataSource{
        
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            if childArray == nil {
                return 0
            }
            return childArray!.count
        }
        
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            var cell = tableView.dequeueReusableCellWithIdentifier("cell")
            if cell == nil {
                cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
            }
            cell?.selectionStyle = .None
            if indexPath.row < childArray!.count {
                cell?.textLabel?.textColor = UIColor.darkGrayColor()
                let model = childArray![indexPath.row] as! childModel
    //            print("模型:\(model)")
                let str1 = ToolManager.stringByX(model.mobile_phone, startindex: 3, endindex: 7)
                let str2 = ToolManager.stringByX(model.tomobile_phone, startindex: 3, endindex: 7)
                let attr1 = NSMutableAttributedString(string: "\(str1)回复\(str2):\(model.content)")
                let attr2 = ToolManager.mixTextColor(attr1, from: 0, to: 11, color: userNameColor) as! NSMutableAttributedString
    //            print("字符串:\(attr1)")
                cell?.textLabel?.attributedText = ToolManager.mixTextColor(attr2, from: 13, to: 11, color: userNameColor)
                cell?.textLabel?.numberOfLines = 0
            }
            return cell!
        }
        
        func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
            if indexPath.row < cellHeightArray.count {
                return cellHeightArray[indexPath.row]
            }
            return 0
        }
    }
    
    //MARK: - 计算外层(即本身)cell高度
    extension WenWenDetailTableViewCellStyleTwo{
        
        func getCellHeightArray(array:NSMutableArray) -> [CGFloat]{
            var cellHArray = [CGFloat]()
            
            for item in array {
                let model = item as! WenWenCellStyleTwoMode
                let h1 = ToolManager.calculateStringSize(model.content, maxW: kScreen_W - 16, maxH: 1000, fontSize: 18).height
                let array2 = model.child
                if array2?.count > 0 {
                    var h2:CGFloat = 0
                    for comen in array2! {
                        let model2 = comen as! childModel
                        h2 += ToolManager.calculateStringSize("\(model2.mobile_phone)回复\(model2.tomobile_phone):\(model2.content)", maxW: kScreen_W - 16, maxH: 10000, fontSize: 17).height + 10
                    }
                    cellHArray.append(h1 + h2 + 84*kScrennScale + 5)
                }else{
                    cellHArray.append(h1 + 75)
                }
            }
            return cellHArray
        }
    }
    
    //MARK:按钮点击
    extension WenWenDetailTableViewCellStyleTwo{
        
        func buttonClicked(sender:UIButton){
            print("回复层主")
            self.delegate?.huifuButtonClicked(model!.user_id, answer_id: model!.id)
        }
    }
    

    在最外层tableView中相关方法

    import UIKit
    import Alamofire
    
    class WenWenDetailViewController: BasicViewController {
        
        //上一个界面传递问题id
        var questionID = ""
        // 数据源
        var cellOneModel:WenWenCellStyleOneMode? = nil//第一组
        //第二组
        lazy var dataArray: NSMutableArray = {
           return NSMutableArray()
        }()
        
        //cell高度
        var cellOneHeight:CGFloat = 0 //第一组
        //第二组
        var cellHeightArray = [CGFloat]()
        
        //属性
        var tableView = UITableView()
        let huifuView = UIView()
        let textView = UITextView()
        
        /// 判断是回复还是回答 1:回答 2:回复 默认1
        var type = 1
        
        //存储回复层主的id
        var touser_id = ""
        var answer_id = ""
        
        //MARK: 生命周期
        override func viewDidLoad() {
            super.viewDidLoad()
            creatUI()
            navigationSetting()
            getNetData()
            NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(WenWenDetailViewController.keyboardWillAppear(_:)), name:UIKeyboardWillShowNotification, object:nil)
        }
        override func viewWillAppear(animated: Bool) {
            super.viewWillAppear(animated)
            self.navigationController?.navigationBar.translucent = false
        }
        
        override func viewWillDisappear(animated: Bool) {
            super.viewWillDisappear(animated)
            self.navigationController?.navigationBar.translucent = true
            self.clearAllNotice()
        }
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
        
        deinit{
            NSNotificationCenter.defaultCenter().removeObserver(self)
        }
    }
    
    //MARK: 界面相关
    extension WenWenDetailViewController{
        override func creatUI() {
            self.automaticallyAdjustsScrollViewInsets = false
            view.backgroundColor = APSGrayColor
            
            //tableView
            tableView.frame = CGRectMake(0, 0, kScreen_W, kScreen_H - 64 - 70*kScrennScale)
            view.addSubview(tableView)
            tableView.tableFooterView = UIView()
            tableView.delegate = self
            tableView.dataSource = self
            
            //回复框
            huifuView.frame = CGRectMake(0,kScreen_H - 64 - 70,kScreen_W,70*kScrennScale)
            huifuView.backgroundColor = APSGrayColor
            view.addSubview(huifuView)
            textView.frame = CGRectMake(30, 10*kScrennScale, kScreen_W - 150, 40*kScrennScale)
            textView.layer.masksToBounds = true
            textView.layer.cornerRadius = 3
            textView.delegate = self
            textView.returnKeyType = .Done
            textView.font = UIFont.systemFontOfSize(17)
            huifuView.addSubview(textView)
            let huifuButton = UIButton(frame: CGRectMake(textView.frame.origin.x+textView.frame.width+10,10*kScrennScale,kScreen_W-60-10-textView.frame.width,40*kScrennScale))
            huifuView.addSubview(huifuButton)
            huifuButton.setTitle("回复", forState: .Normal)
            huifuButton.backgroundColor = APSOrangeColor
            huifuButton.layer.masksToBounds = true
            huifuButton.layer.cornerRadius = 3
            huifuButton.addTarget(self, action: #selector(WenWenDetailViewController.buttonClicked(_:)), forControlEvents: .TouchUpInside)
            
            //注册cell
            tableView.registerClass(WenWenDetailTableViewCellStyleOne.self, forCellReuseIdentifier: "cellOne")
            tableView.registerClass(WenWenDetailTableViewCellStyleTwo.self, forCellReuseIdentifier: "cellTwo")
            
        }
        override func navigationSetting() {
            self.navigationItem.title = "问题详情"
            self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.blackColor()]
        }
    }
    
    //MARK: - tableView协议
    extension WenWenDetailViewController: UITableViewDelegate,UITableViewDataSource{
        
        func numberOfSectionsInTableView(tableView: UITableView) -> Int {
            return 2
        }
        
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            if section == 0 {
                return 1
            }
            return dataArray.count
        }
        
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            //第一组
            if indexPath.section == 0{
                let cell = tableView.dequeueReusableCellWithIdentifier("cellOne", forIndexPath: indexPath) as! WenWenDetailTableViewCellStyleOne
                cell.selectionStyle = .None
                cell.model = nil
                if cellOneModel != nil {
                    cell.model = cellOneModel
                }
                return cell
            }
            
            //第二组
            let cell = tableView.dequeueReusableCellWithIdentifier("cellTwo", forIndexPath: indexPath) as! WenWenDetailTableViewCellStyleTwo
            cell.selectionStyle = .None
            cell.model = nil
            if indexPath.row < dataArray.count {
                let model = dataArray[indexPath.row] as! WenWenCellStyleTwoMode
                cell.model = nil
                cell.model = model
                cell.delegate = self
            }
            return cell
        }
        
        func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
            if indexPath.section == 0 {
                return cellOneHeight
            }
            //第二组
            if indexPath.row < cellHeightArray.count {
                return cellHeightArray[indexPath.row]
            }
            return 0
        }
        
        func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
            
        }
    }
    
    //MARK: - 网络请求
    extension WenWenDetailViewController{
        
        func getNetData(){
            pleaseWait()
            Alamofire.request(.GET, getComentsListURL, parameters: ["id":questionID,"user_id":crrentUser!.user_id], encoding: .URL, headers: nil).responseJSON(options: NSJSONReadingOptions.MutableContainers) { (result) in
                self.clearAllNotice()
                if let json = result.result.value{
                    let code = json.objectForKey("code")?.stringValue
                    if code == "200"{
                        if let data = json.objectForKey("data") as? NSDictionary{
                            self.cellOneModel = WenWenCellStyleOneMode.yy_modelWithDictionary(data as [NSObject : AnyObject])
                            if self.cellOneModel != nil{
                                self.cellOneHeight = WenWenDetailTableViewCellStyleOne().getCellHeight(self.cellOneModel!)
                            }
                            
                            //第二组
                            let child = data["child"]
                            let modelArray = NSArray.yy_modelArrayWithClass(WenWenCellStyleTwoMode.self, json: child!)
                            self.dataArray.removeAllObjects()
                            self.dataArray.addObjectsFromArray(modelArray!)
                            self.cellHeightArray.removeAll()
                            self.cellHeightArray = WenWenDetailTableViewCellStyleTwo().getCellHeightArray(self.dataArray)
                            
                            self.tableView.reloadData()
                        }//data结束
                    }//code结束
                }//json结束
            }//Alamofire结束
        }//函数结束
    }
    
    //MARK: textViewDelegate
    extension WenWenDetailViewController:UITextViewDelegate{
        
        func keyboardWillAppear(notification:NSNotification) {
        
        let userInfo = notification.userInfo![UIKeyboardFrameEndUserInfoKey]
        
        let keyboardY = userInfo!.CGRectValue.size.height
    
            UIView.animateWithDuration(1) {
                self.huifuView.frame = CGRectMake(0,kScreen_H - 64 - 70 - keyboardY,kScreen_W,70*kScrennScale)
            }
        }
        
        func textViewDidBeginEditing(textView: UITextView) {
            
        }
        
        func textViewDidEndEditing(textView: UITextView) {
            UIView.animateWithDuration(0.2) {
                self.huifuView.frame = CGRectMake(0,kScreen_H - 64 - 70,kScreen_W,70*kScrennScale)
            }
        }
        
        func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
            if text.containsString("\n") {
                self.view.endEditing(true)
                return false
            }
            return true
        }
    }
    
    //MARK:按钮点击事件
    extension WenWenDetailViewController:WenCellStyleTwoDelegate{
        
        func buttonClicked(sender:UIButton){
            sender.userInteractionEnabled = false
            print("回复")
            textView.resignFirstResponder()
            
            //提交
            if textView.text.characters.count == 0 {
                noticeOnlyText("回复内容不能为空", autoClear: true, autoClearTime: 1)
                sender.userInteractionEnabled = true
                return
            }
            
            //回答
            var url = answerURL
            var parameters = ["user_id":crrentUser!.user_id,"id":cellOneModel!.id,"content":textView.text!]
            
            if type == 2 {
                //回复
                url = huifuURL
                parameters = ["user_id":crrentUser!.user_id,"touser_id":touser_id,"id":cellOneModel!.id,"answer_id":answer_id,"content":textView.text!]
            }
    //        print(url)
    //        print(parameters)
            Alamofire.request(.GET, url, parameters: parameters, encoding: .URL, headers: nil).responseJSON(options: NSJSONReadingOptions.MutableContainers) { (result) in
                self.type = 1
                sender.userInteractionEnabled = true
                if let json = result.result.value{
                    let code = json.objectForKey("code")?.stringValue
    //                print(code)
                    if code == "200"{
                        self.textView.text = nil
                        self.noticeOnlyText("评论成功", autoClear: true, autoClearTime: 1)
                        self.performSelector(#selector(WenWenDetailViewController.getNetData), withObject: nil, afterDelay: 1)
                    }else{
                        self.noticeOnlyText("参数错误", autoClear: true, autoClearTime: 1)
                    }
                }else{
                    self.noticeOnlyText("服务器开小差啦", autoClear: true, autoClearTime: 1)
                }
            }
        }
        
        func huifuButtonClicked(touser_id:String,answer_id:String){
            //回复层主
            textView.becomeFirstResponder()
            textView.text = nil
            self.type = 2
            self.answer_id = answer_id
            self.touser_id = touser_id
        }
        
    }
    

    相关文章

      网友评论

      本文标题:TableViewCell嵌套TableView实现评论列表盖楼

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