otherS界面

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

2017-02-28  本文已影响310人  T92

效果




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
    }
    
}
上一篇下一篇

猜你喜欢

热点阅读