i want to change the height of the view based NStableview cell based on label added to the cell using swift?

喜你入骨 提交于 2020-01-03 04:47:07

问题


How to change view based tableview cell height dynamically after loading data into cell using swift os x application. Programmatically I added labels to the custom view based on that i want to change the height of the tableview cell.

I used visual format language to add autolayout constraints. i have created imageview and labels programmatically inside custom view based nstableview cell. i want to change the cell height according to the labels added to the custom cell.

import Cocoa

class ViewController: NSViewController {

    var fileName:String?
    var size:String?
    var image:NSImage?
    var rowHeight:CGFloat?
    var imageView:NSImageView?
    var fileNameLabel:NSTextField?
    var fileSizeLabel:NSTextField?

    @IBOutlet weak var tableView: NSTableView!

    var data: [Int:[String]]=[:]
    let fileInfo=FileInfo()

    override func viewDidLoad() {
        super.viewDidLoad()
        let nib = NSNib(nibNamed: "MyCellView", bundle: NSBundle.mainBundle())
        tableView.registerNib(nib!, forIdentifier: "MyCellView")

    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }


    override var representedObject: AnyObject? {
        didSet {
        // Update the view, if already loaded.

        }
    }

    @IBAction func scanAction(sender: AnyObject) {

        var i:Int=0

        let dictDupeFiles=fileInfo.enumerateDirectory()

        print(dictDupeFiles.count)
        for value in dictDupeFiles{
            print(value)
        }

        for value in dictDupeFiles.values{
            //print("\(key):\(value)")
            data[i++]=value.componentsSeparatedByString("\n")
        }
        print(data.count)
        tableView.reloadData()
    }
}

extension ViewController: NSTableViewDataSource, NSTableViewDelegate {

    func numberOfRowsInTableView(tableView: NSTableView) -> Int {
        return data.values.count
    }

    func tableView(tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
        let cell = tableView.makeViewWithIdentifier("MyCellView", owner: self) as! MyCellView
        cell.bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds))
        return 300
    }


    func RowHeightChanged(notification:NSNotification){
        NSAnimationContext.beginGrouping()
        NSAnimationContext.currentContext().duration=0
        let indexSet:NSIndexSet=NSIndexSet(index: notification.object as! Int)
        tableView.noteHeightOfRowsWithIndexesChanged(indexSet)
        NSAnimationContext.endGrouping()
    }

    func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
        let cell = createCustomCellForRow(row)

        NSAnimationContext.beginGrouping()
        NSAnimationContext.currentContext().duration=0
        cell.translatesAutoresizingMaskIntoConstraints=true
        let indexSet:NSIndexSet=NSIndexSet(index: row)
        tableView.noteHeightOfRowsWithIndexesChanged(indexSet)
        NSAnimationContext.endGrouping()
        return cell
    }

    func createCustomCellForRow(row:Int) -> MyCellView{
        let cell = tableView.makeViewWithIdentifier("MyCellView", owner: self) as! MyCellView
        let customConstraints=CustomViewConstraints()
        var previousLabel:NSTextField?
        var label:NSTextField?

        if(data.count>0){

            rowHeight=0.0
            for object in cell.subviews
            {
                object.removeFromSuperview()
            }
            imageView=customConstraints.createImageView()

            fileNameLabel=customConstraints.createFileNameLabel()

            fileSizeLabel=customConstraints.createLabel()

            cell.addSubview(imageView!)
            cell.addSubview(fileNameLabel!)
            cell.addSubview(fileSizeLabel!)

            cell.translatesAutoresizingMaskIntoConstraints=true
            for value in data[row]!{
                if(value == ""){
                    continue
                }else{

                    imageView!.image=customConstraints.makeThumbnail(value)

                    fileNameLabel!.stringValue=(value as NSString).lastPathComponent

                    let filesize=String(customConstraints.sizeForLocalFilePath(value))
                    size=(NSByteCountFormatter.stringFromByteCount(Int64(filesize)!,countStyle: NSByteCountFormatterCountStyle.Binary))
                    fileSizeLabel!.stringValue=size!

                    var views = ["imageView": imageView!,
                        "fileNameLabel": fileNameLabel!,
                        "fileSizeLabel": fileSizeLabel!]
                    var allConstraints = customConstraints.createConstraints(cell, value: value, views: views)
                    if(previousLabel == nil){
                        label=customConstraints.createLabel()
                        label?.stringValue=value
                        previousLabel=label

                        cell.addSubview(label!)

                        views["filePathLabel"]=label
                        let filePathLabelVerticalConstraints = customConstraints.createLayoutConstraints("V:[fileSizeLabel]-[filePathLabel]", views: views)
                        allConstraints += filePathLabelVerticalConstraints

                        let filePathLabelHorizontalConstraints = customConstraints.createLayoutConstraints("H:[imageView]-[filePathLabel]-|", views: views)
                        allConstraints += filePathLabelHorizontalConstraints
                    }else{

                        label=customConstraints.createLabel()
                        label?.stringValue=value

                        cell.addSubview(label!)
                        views["previousLabel"]=previousLabel
                        views["newFilePathLabel"]=label
                        let format:String?
                        if(value == data[row]?.last){
                            format="V:[previousLabel]-[newFilePathLabel]-|"
                        }else{
                            format="V:[previousLabel]-[newFilePathLabel]"
                        }
                        let newFilePathLabelVerticalConstraints = customConstraints.createLayoutConstraints(format!, views: views)
                        allConstraints += newFilePathLabelVerticalConstraints

                        let newFilePathLabelHorizontalConstraints = customConstraints.createLayoutConstraints("H:[imageView]-[newFilePathLabel]-|", views: views)
                        allConstraints += newFilePathLabelHorizontalConstraints
                        previousLabel=label

                    }
                    NSLayoutConstraint.activateConstraints(allConstraints)
                    rowHeight=(fileNameLabel?.frame.height)! + (fileSizeLabel?.frame.height)! + (previousLabel?.frame.height)! + 30
                    tableView.rowHeight=rowHeight!

            NSNotificationCenter.defaultCenter().postNotificationName("RowHeightChanged", object: row)
                }//end of if

            }//end of for
        }//end of if

        return cell
    }

    func tableViewColumnDidResize(notification: NSNotification) {
        tableView.reloadData()
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "RowHeightChanged:", name:"RowHeightChanged" , object: notification.object)
    }
}

Constraints which are added

 var previousLabel:NSTextField?
var label:NSTextField?

func createConstraints(cell:MyCellView,value:String, views:[String:AnyObject]) -> [NSLayoutConstraint]{

    var allConstraints = [NSLayoutConstraint]()
    let imageViewHorizontalConstraints = createLayoutConstraints("H:|-[imageView]", views: views)
    allConstraints += imageViewHorizontalConstraints

    let imageViewVerticalConstraints = createLayoutConstraints("V:|-[imageView]", views: views)
    allConstraints += imageViewVerticalConstraints

    let fileNameHorizontalConstraints = createLayoutConstraints("H:[imageView]-[fileNameLabel]-|", views: views)
    allConstraints += fileNameHorizontalConstraints

    let fileSizeHorizontalConstraints = createLayoutConstraints("H:[imageView]-[fileSizeLabel]-|", views: views)
    allConstraints += fileSizeHorizontalConstraints

    let fileNameLabelVerticalConstraints = createLayoutConstraints("V:|-[fileNameLabel]", views: views)
    allConstraints += fileNameLabelVerticalConstraints

    let fileSizeLabelVerticalConstraints = createLayoutConstraints("V:[fileNameLabel][fileSizeLabel]", views: views)
    allConstraints += fileSizeLabelVerticalConstraints

    return allConstraints
}

func createLayoutConstraints(format:String,views:[String:AnyObject]) -> [NSLayoutConstraint]{
    let constraint=NSLayoutConstraint.constraintsWithVisualFormat(
        format,
        options: [],
        metrics: nil,
        views: views)
    return constraint
}


func createLabel() -> NSTextField{
    let label = NSTextField(frame:NSMakeRect(0, 0, 0,0))
    label.translatesAutoresizingMaskIntoConstraints=false
    label.font=NSFont.systemFontOfSize(11)
    label.selectable=false
    label.drawsBackground=false
    label.bezeled=false
    label.editable=false

    return label
}

func createFileNameLabel() -> NSTextField{
    let label = NSTextField(frame:NSMakeRect(0, 0, 0,0))
    label.translatesAutoresizingMaskIntoConstraints=false
    label.font=NSFont.boldSystemFontOfSize(14)
    label.selectable=false
    label.drawsBackground=false
    label.bezeled=false
    label.editable=false

    return label
}

func createImageView() -> NSImageView{
    let imageView=NSImageView()
    imageView.translatesAutoresizingMaskIntoConstraints=false
    imageView.needsLayout=true
    imageView.addConstraint(NSLayoutConstraint(item: imageView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 100))

    imageView.addConstraint(NSLayoutConstraint(item: imageView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 100))
    return imageView
}

func sizeForLocalFilePath(filePath:String) -> UInt64 {
    do {
        let fileAttributes = try NSFileManager.defaultManager().attributesOfItemAtPath(filePath)
        if let fileSize = fileAttributes[NSFileSize]  {
            return (fileSize as! NSNumber).unsignedLongLongValue
        } else {
            print("Failed to get a size attribute from path: \(filePath)")
        }
    } catch {
        print("Failed to get file attributes for local path: \(filePath) with error: \(error)")
    }
    return 0
}

func makeThumbnail(filePath:String) -> NSImage{
    let size:NSSize=CGSizeMake(300, 300)
    let option=NSDictionary(object: NSNumber(bool: false), forKey: kQLThumbnailOptionIconModeKey as NSString)
    let fileURL=NSURL(fileURLWithPath: filePath)
    if let thumb=QLThumbnailImageCreate(kCFAllocatorDefault, fileURL, size, option){

        let thumbnail=NSImage(CGImage: thumb.takeUnretainedValue(), size: NSZeroSize)

        return thumbnail
    }else{
        let image: NSImage = NSWorkspace.sharedWorkspace().iconForFile((fileURL).path!)
        return image
    }
}

来源:https://stackoverflow.com/questions/35285965/i-want-to-change-the-height-of-the-view-based-nstableview-cell-based-on-label-ad

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!