简体   繁体   中英

NSTableView: replace empty table with image

When I don't have any rows to display in my NSTableView, I'd like to display an image instead. I tried the following in my custom NSViewController class, but I still see an empty table. I have "ic_empty_image" in Assets.xcassets.

func numberOfRowsInTableView(tableView: NSTableView) -> Int {
    if model.numRows == 0 {
        let image = NSImage(named: "ic_empty_image")
        let imageView = NSImageView()
        imageView.image = image
        self.view.replaceSubview(tableView, with: imageView)
        self.view.setNeedsDisplayInRect(imageView.visibleRect)
    } else {
        return model.numRows
    }
}

If you take advantage of view based table, you can just flip view for the cell when you know you have empty data set. The trick is to bind you table to the array and instead of having it empty just have one item - indicator.

I created sample project for you here: https://github.com/emankovski/nstableview-empty-picture

But general logic is actually pretty simple: I created NSTableCellView object in nib and just return it when I see the indicator of no data. Note that I also change row height for table view as my cell with image way taller than cells with text. I hope it helps.

 class AppDelegate: NSObject, NSApplicationDelegate, NSTableViewDataSource {

private static let placeholder = "<Placeholder>"
dynamic var items = [String]()

@IBOutlet weak var window: NSWindow!
@IBOutlet weak var tableView: NSTableView!
@IBOutlet weak var imageCell: NSTableCellView!

@IBAction func addRowsPressed(sender: AnyObject) {
    appendItems()
}

@IBAction func clearTablePressed(sender: AnyObject) {
    removeItems()

}

func applicationDidFinishLaunching(aNotification: NSNotification) {
    appendItems()

}

func applicationWillTerminate(aNotification: NSNotification) {
    // Insert code here to tear down your application
}

func appendItems() {


    items.removeAll()

    items.append("One")
    items.append("Two")
    items.append("Three")

    tableView.rowHeight = 20

}

func removeItems() {

    items.removeAll()
    tableView.rowHeight = 50
    items.append(AppDelegate.placeholder)


}

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

    if items[row] == AppDelegate.placeholder {

        return imageCell
    }

    let cellView = tableView.makeViewWithIdentifier("CellView", owner: nil) as! NSTableCellView

    return cellView
}


 }

UPDATE for storyboards: Picture of how to drag table cell view to view controller in storyboards:

在此处输入图片说明

Then just create outlet and connect-drag that object to that outlet:

  @IBOutlet var tableCellView: NSTableCellView!

instead of replacing table view you could just simply play with hidden property of tableView and image view.

This will work if your base class is UIViewController

private var imageView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()

        let image = NSImage(named: "ic_empty_image")
        let imageView = NSImageView()
        imageView.frame = tableView.frame
        imageView.image = image
        self.view.addSubview(imageView)
        imageView.hidden = true
    }

    func numberOfRowsInTableView(tableView: NSTableView) -> Int {
        if model.numRows == 0 {
            tableView.hidden = true
            imageView.hidden = false
            return 0 // Table view will still be active and therefore we need to give it return value
        } else {
            tableView.hidden = false
            imageView.hidden = true
            return model.numRows
        }
    }

Even if this should work (didn't test it) I would not recommend going this way. There are some approaches that could be better (it depends on what do you need).

If you're using UITableViewController, you can add background image based on number of rows in UITableView. If you're on Storyboards or xibs you can create imageView and add image to it. You would only need to show/hide image view based on number of rows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM