代码之家  ›  专栏  ›  技术社区  ›  chibop

如何在Swift for MacOS中用程序创建NSTableView?

  •  0
  • chibop  · 技术社区  · 2 年前

    使用下面的Swift代码,我试图以编程方式在macOS上的表中显示快捷方式列表。

    但是,该表在屏幕上显示为空。

    有趣的是,没有生成错误消息,当我使用 debugPrint tableView 函数,它为每个单元格输出列名、行和正确的数据。

    谢谢你的帮助。

    class ShortcutsWindowController: NSWindowController, NSTableViewDelegate, NSTableViewDataSource {
        var shortcuts: [Shortcut]
        var tableView: NSTableView!
        init(shortcuts: [Shortcut]) {
            self.shortcuts = shortcuts
            super.init(window: nil)
            for shortcut in shortcuts {
                debugPrint(shortcut.name, shortcut.key, shortcut.modifiers, shortcut.keyName)
            }
            setupWindow()
            setupTableView()
            window?.contentView?.needsDisplay = true
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        private func setupWindow() {
            let window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 400, height: 300),
                                  styleMask: [.titled, .closable],
                                  backing: .buffered, defer: false)
            self.window = window
            self.window?.title = "Customize Shortcuts"
        }
        
        private func setupTableView() {
            tableView = NSTableView(frame: self.window!.contentView!.bounds)
            tableView.delegate = self
            tableView.dataSource = self
            let nameColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("NameColumn"))
            nameColumn.title = "Name"
            tableView.addTableColumn(nameColumn)
            let hotkeyColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("HotkeyColumn"))
            hotkeyColumn.title = "Hotkey"
            tableView.addTableColumn(hotkeyColumn)
            self.window?.contentView?.addSubview(tableView)
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }
    
        func numberOfRows(in tableView: NSTableView) -> Int {
            return shortcuts.count
        }
        
        func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
            let shortcut = shortcuts[row]
            debugPrint(tableColumn?.title, row)
            switch tableColumn?.identifier {
            case NSUserInterfaceItemIdentifier("NameColumn"):
                let cellView = NSTableCellView(frame: NSRect(x: 0, y: 0, width: tableColumn!.width, height: tableView.rowHeight))
                let textField = NSTextField(frame: cellView.bounds)
                textField.stringValue = shortcut.name
                textField.isEditable = false
                textField.isBezeled = false
                textField.drawsBackground = false
                textField.autoresizingMask = [.width, .height] // Resize with the cell view
                cellView.addSubview(textField)
                debugPrint("Cell Name:", shortcut.name)
                return cellView
    
            case NSUserInterfaceItemIdentifier("HotkeyColumn"):
                let cellView = NSTableCellView(frame: NSRect(x: 0, y: 0, width: tableColumn!.width, height: tableView.rowHeight))
                let button = NSButton(frame: NSRect(x: 0, y: 0, width: tableColumn!.width, height: tableView.rowHeight))
                button.title = shortcut.keyName
                button.tag = row
                button.target = self
                button.action = #selector(reassignShortcut(_:))
                cellView.addSubview(button)
                debugPrint("Cell Hotkey", shortcut.keyName)
                return cellView
    
            default:
                return nil
            }
        }
    
        @objc func reassignShortcut(_ sender: NSButton) {
            // logic
        }
        
    }
    
    0 回复  |  直到 2 年前
        1
  •  0
  •   apodidae    2 年前

    以下创建tableView的编程方法适用于我的系统。在添加滚动视图之前,我无法看到tableView。可以通过创建Swift项目、添加名为“main.Swift”的新文件并将此代码复制/粘贴到XCode中来运行源代码。删除预先提供的AppDelegate以避免重复符号。我试着尽可能多地使用你的代码。

    import Cocoa
    
    class AppDelegate: NSObject, NSApplicationDelegate, NSTableViewDelegate, NSTableViewDataSource {
        var window:NSWindow!
        var shortcuts = [["name": "print", "key":"P", "modifier":"shift"],
                         ["name": "copy",  "key":"C", "modifier":"alt"],
                         ["name": "cut",   "key":"X", "modifier":"alt"],
                         ["name": "paste", "key":"V", "modifier":"alt"]]
        
        func numberOfRows(in tableView: NSTableView) -> Int {
            
            return shortcuts.count
        }
        
        func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
            let cellView = NSTableCellView(frame: NSRect(x: 0, y: 0, width: tableColumn!.width, height: tableView.rowHeight))
            
            switch tableColumn?.identifier {
            case NSUserInterfaceItemIdentifier("NameColumn"):
                
                let textField = NSTextField(frame: cellView.bounds)
                textField.stringValue = shortcuts[row]["name"]!
                textField.isEditable = false
                textField.isBezeled = false
                textField.drawsBackground = false
                textField.autoresizingMask = [.width, .height] // Resize with the cell view
                cellView.addSubview(textField)
                return cellView
                
            case NSUserInterfaceItemIdentifier("HotkeyColumn"):
                
                let textField = NSTextField(frame: cellView.bounds)
                textField.stringValue = shortcuts[row]["key"]!
                textField.isEditable = false
                textField.isBezeled = false
                textField.drawsBackground = false
                textField.autoresizingMask = [.width, .height] // Resize with the cell view
                cellView.addSubview(textField)            
                return cellView
                
            default:
                return nil
            }
            
        }
        
        func buildMenu() {
            let mainMenu = NSMenu()
            NSApp.mainMenu = mainMenu
            // **** App menu **** //
            let appMenuItem = NSMenuItem()
            mainMenu.addItem(appMenuItem)
            let appMenu = NSMenu()
            appMenuItem.submenu = appMenu
            appMenu.addItem(withTitle: "Quit", action:#selector(NSApplication.terminate), keyEquivalent: "q")
        }
        
        func buildWnd() {
            
            let _wndW : CGFloat = 400
            let _wndH : CGFloat = 300
            
            window = NSWindow(contentRect:NSMakeRect(0,0,_wndW,_wndH),styleMask:[.titled, .closable, .miniaturizable, .resizable], backing:.buffered, defer:false)
            window.center()
            window.title = "Swift TableView Demo"
            window.makeKeyAndOrderFront(window)
            
            // **** TableView **** //
            let scrlView = NSScrollView(frame:NSMakeRect(10,10,380,240))
            let tableView = NSTableView(frame:NSMakeRect(0,0,364,240))
            tableView.delegate = self
            tableView.dataSource = self
            let nameColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("NameColumn"))
            nameColumn.title = "Name"
            nameColumn.width = 100
            tableView.addTableColumn(nameColumn)
            let hotkeyColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("HotkeyColumn"))
            hotkeyColumn.title = "Hotkey"
            hotkeyColumn.width = 200
            tableView.addTableColumn(hotkeyColumn)
            scrlView.documentView = tableView
            window.contentView!.addSubview(scrlView)
            
            // **** Quit btn **** //
            let quitBtn = NSButton (frame:NSMakeRect( _wndW - 50, _wndH - 40, 40, 40 ))
            quitBtn.bezelStyle = .circular
            quitBtn.autoresizingMask = [.minXMargin,.maxYMargin]
            quitBtn.title = "Q"
            quitBtn.action = #selector(NSApplication.terminate)
            window.contentView!.addSubview(quitBtn)
        }
           
        func applicationDidFinishLaunching(_ notification: Notification) {
            buildMenu()
            buildWnd()
        }
        
        func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
            return true
        }
        
    }
    let appDelegate = AppDelegate()
    
    // **** main.swift **** //
    let app = NSApplication.shared
    app.delegate = appDelegate
    app.setActivationPolicy(.regular)
    app.activate(ignoringOtherApps:true)
    app.run()