微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

基于视图的NSTableView滚动性能

如何解决基于视图的NSTableView滚动性能

我有一个NSTableView,它的父级是NSMenuItem的视图。 NSTableView是基于视图的表。我正在使用绑定表填充来自NSArrayController的数据。

在NSTableView中滚动的性能非常糟糕。滚动功能似乎不是“连续的”,仅在我将手指从触控板抬起时才滚动。这种行为有点像当您有一个文本字段时,它只在按下返回键时才发送其动作,而不是连续发送该动作。

如果我打开和关闭菜单次数足够多,则该表将在NSTableView的一部分中平滑滚动,但很快会恢复为原始滚动。我也可以单击并拖动以相对平滑地有效滚动行,但同样,两指滚动手势非常笨拙。

下面是用于填充表的代码。在IB中,文本字段绑定到name属性,而NSImageView绑定到名为AmphRunningApp的自定义类的icon属性

AmphRunningApp类:

import Foundation
import Cocoa

class AmphRunningApp: NSObject
{
    @objc var app: NSRunningApplication
    @objc var name: String
    @objc var icon: NSImage

init(app: NSRunningApplication,name: String,icon: NSImage)
{
    self.name = name
    self.app = app
    self.icon = icon
}

填充表格:

@IBAction @objc func updateRunningAppsTable(sender: Any)
{
    // Get all currently running apps
    // and sort them alphabetically by localized name:
    
    let runningApps = NSWorkspace.shared.runningApplications.sorted
    {
        $0.localizedname! < $1.localizedname!
    }

    // For every running app,// add it to the array controller:
    
    for app in runningApps
    {
        var duplicateApp = false
        
        // Check that this app does not already exist in the array controller
        for dupeApp in self.menuRunningAppAC.arrangedobjects as! [AnyObject]
        {
            if dupeApp.name == app.localizedname
            {
                duplicateApp = true
            }
        }

        // If this app has not already been added
        // to the array controller,add it
        if duplicateApp == false
        {
            self.menuRunningAppAC.addobject(AmphRunningApp(app: app,name: app.localizedname!,icon: app.icon!))
        }
    }

    self.statusMenuAppTable.reloadData()
}

enter image description here

解决方法

该问题似乎与NSStatusItem的button属性和GCD上的performClick()函数有关。如果我简单地为我的NSStatusItem分配一个菜单(然后单击任意打开(即,单击鼠标左键或单击鼠标右键),则滚动非常平滑;如果我不使用GCD调用performClick()函数,则滚动也是黄油般光滑。**

进阶笨拙的滚动:

@objc func statusItemClicked(_ sender: Any?)
{
    NSApp.activate(ignoringOtherApps: true)

    if (NSApp.currentEvent != nil)
    {
        print("right click")
        let event = NSApp.currentEvent!

        if event.type == NSEvent.EventType.rightMouseUp || event.modifierFlags.contains(.control) // RIGHT-CLICK
        {
            

            // THIS IS THE PROBLEM:
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.01)
            {
                self.statusItem.menu = self.statusItemMenu
                self.statusItem.button?.performClick(nil)
            }
            // END PROBLEM


        }
        else // LEFT-CLICK
        {
            print("left click")
        }
}



BUTTERY-SMOOTH滚动:

@objc func statusItemClicked(_ sender: Any?)
{
    NSApp.activate(ignoringOtherApps: true)

    if (NSApp.currentEvent != nil)
    {
        print("right click")
        let event = NSApp.currentEvent!

        if event.type == NSEvent.EventType.rightMouseUp || event.modifierFlags.contains(.control) // RIGHT-CLICK
        {
            self.statusItem.menu = self.statusItemMenu
            self.statusItem.button?.performClick(nil)
        }
        else // LEFT-CLICK
        {
            print("left click")
        }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。