NSOutlineView拖动线卡住+蓝色边框 [英] NSOutlineView drag line stuck + blue border

查看:152
本文介绍了NSOutlineView拖动线卡住+蓝色边框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望蓝色拖动栏中的行为正确,并且在拖动时没有蓝色矩形.

你知道我的错误在哪里吗?

(如您所见,蓝色条卡在顶部,如本主题所示:

 导入可可类ViewController:NSViewController,NSOutlineViewDataSource,NSOutlineViewDelegate,NSPasteboardItemDataProvider {@IBOutlet弱var outlineView:NSOutlineView!让REORDER_PASTEBOARD_TYPE ="com.test.calques.item"覆盖func viewDidLoad(){super.viewDidLoad()//注册接受的对象类型.outlineView.register(forDraggedTypes:[REORDER_PASTEBOARD_TYPE])//禁用将项目从我们的视图拖到其他应用程序.outlineView.setDraggingSourceOperationMask(NSDragOperation(),forLocal:false)//启用将项目拖入我们的视图中.outlineView.setDraggingSourceOperationMask(NSDragOperation.every,forLocal:true)outlineView.delegate =自我;outlineView.dataSource =自我;}覆盖var表示的对象:可以吗?{didSet {//更新视图(如果已加载).}}var个项目:[(String,NSColor)] = [("Item 1",NSColor.black),(第2项",NSColor.red),(第3项",NSColor.red),(第4项",NSColor.red),(第5项",NSColor.red),("Item 6",NSColor.red)];//NSOutlineViewDataSourcefunc outlineView(_ outlineView:NSOutlineView,numberOfChildrenOfItem项目:任何?)->诠释{返回items.count;}func outlineView(_ outlineView:NSOutlineView,isItemExpandable item:任何)->布尔{返回假}func outlineView(_ outlineView:NSOutlineView,子索引:Int,ofItem item:Any?)->任何 {退货项目[索引];}func outlineView(_ outlineView:NSOutlineView,viewFor tableColumn:NSTableColumn ?,项目:任何)->NSView?{let image:NSImage = NSImage(大小:NSSize(宽度:17,高度:17));让calquesItem:(String,NSColor)= item as!(String,NSColor);let path = NSBezierPath(ovalIn:CGRect(x:2,y:2,宽度:17-4,高度:17-4)));image.lockFocus();calquesItem.1.setFill();path.fill();image.unlockFocus();让单元格= outlineView.make(withIdentifier:"DataCell",所有者:无)为!NSTableCellView;cell.textField!.stringValue = calquesItem.0;cell.imageView!.image =图片;返回单元}//拖动-NSOutlineViewDataSourcevar fromIndex:Int?=零;func outlineView(_ outlineView:NSOutlineView,pasteboardWriterForItem项目:Any)->NSPasteboardWriting?{let pastBoardItem:NSPasteboardItem = NSPasteboardItem();pastBoardItem.setDataProvider(self,forTypes:[REORDER_PASTEBOARD_TYPE]);返回pastBoardItem;}func outlineView(_ outlineView:NSOutlineView,draggingSession会话:NSDraggingSession,willBeginAt screenPoint:NSPoint,forItems draggedItems:[任何]){Swift.print("willBeginAt")让item = draggedItems [0]为!(String,NSColor);fromIndex = items.index(其中:{(_item:(String,NSColor))-> Bool in返回_item.0 == item.0});session.draggingPasteboard.setData(Data(),forType:REORDER_PASTEBOARD_TYPE)}func outlineView(_ outlineView:NSOutlineView,acceptDrop info:NSDraggingInfo,item:Any ?, childIndex index:Int)->布尔{Swift.print("acceptDrop")if(fromIndex!!=索引&& index!= -1){让toIndex:Int = fromIndex!<指数 ?index-1:索引;outlineView.moveItem(at:fromIndex !, inParent:nil,to:toIndex,inParent:nil);items.insert(items.remove(at:fromIndex!),at:toIndex);返回true;}返回false;}func outlineView(_ outlineView:NSOutlineView,validateDrop信息:NSDraggingInfo,proposalItem项:Any ?, proposalChildIndex索引:Int)->NSDragOperation {if(item == nil){返回NSDragOperation.generic;}返回 [];}func outlineView(_ outlineView:NSOutlineView,draggingSession会话:NSDraggingSession,endAt screenPoint:NSPoint,操作:NSDragOperation){Swift.print(拖动会话结束")fromIndex = nil;}//NSPasteboardItemDataProviderfunc粘贴板(_粘贴板:NSPasteboard ?,项目:NSPasteboardItem,providerDataForType类型:字符串){item.setString("Outline Pasteboard Item",forType:type)}} 

解决方案

来自 https://developer.apple.com/reference/appkit/nsoutlineview :

大纲视图中的每个项目都必须是唯一的.为了折叠状态,以在重新加载项目之间保持一致指针必须保持相同,并且项必须保持isEqual(_ :)相同.

我正在使用元组(String,NSColor).而且元组不符合可哈希协议!

从Tuples项切换到MyClass项后,一切正常!(蓝色拖动栏中的行为正确,拖动时没有蓝色矩形)

  class MyClass {var名称:字符串!var color:NSColor!init(_ _名称:字符串,_ _color:NSColor){名称= _名称颜色= _颜色}} 

I'd like a correct behaviour from the blue drag bar, and no blue rect when dragging.

Do you know where is my mistake ?

(as you can see, the blue bar is stuck in top, like in this topic : Little circle-line bar stuck at top of NSOutlineView when rearranging using drag and drop)

import Cocoa

class ViewController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate, NSPasteboardItemDataProvider {

    @IBOutlet weak var outlineView: NSOutlineView!

    let REORDER_PASTEBOARD_TYPE = "com.test.calques.item"

    override func viewDidLoad() {
        super.viewDidLoad()

        //Register for the dropped object types we can accept.
        outlineView.register(forDraggedTypes: [REORDER_PASTEBOARD_TYPE])

        //Disable dragging items from our view to other applications.
        outlineView.setDraggingSourceOperationMask(NSDragOperation(), forLocal: false)

        //Enable dragging items within and into our view.
        outlineView.setDraggingSourceOperationMask(NSDragOperation.every, forLocal: true)

        outlineView.delegate = self;
        outlineView.dataSource = self;
    }

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

    var items: [(String, NSColor)] = [
        ("Item 1",  NSColor.black),
        ("Item 2",  NSColor.red),
        ("Item 3",  NSColor.red),
        ("Item 4",  NSColor.red),
        ("Item 5",  NSColor.red),
        ("Item 6",  NSColor.red)];

    //NSOutlineViewDataSource
    func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
        return items.count;
    }

    func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
        return false
    }

    func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
        return items[index];
    }

    func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
        let image: NSImage = NSImage(size: NSSize(width: 17, height: 17));
        let calquesItem: (String, NSColor) = item as! (String, NSColor);
        let path = NSBezierPath(ovalIn: CGRect(x: 2, y: 2, width: 17 - 4, height: 17 - 4));

        image.lockFocus();
        calquesItem.1.setFill();
        path.fill();
        image.unlockFocus();

        let cell = outlineView.make(withIdentifier: "DataCell", owner: nil) as! NSTableCellView;
        cell.textField!.stringValue = calquesItem.0;
        cell.imageView!.image = image;

        return cell;
    }

    //Drag - NSOutlineViewDataSource
    var fromIndex: Int? = nil;

    func outlineView(_ outlineView: NSOutlineView, pasteboardWriterForItem item: Any) -> NSPasteboardWriting? {
        let pastBoardItem: NSPasteboardItem = NSPasteboardItem();

        pastBoardItem.setDataProvider(self, forTypes: [REORDER_PASTEBOARD_TYPE]);

        return pastBoardItem;
    }

    func outlineView(_ outlineView: NSOutlineView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forItems draggedItems: [Any]) {

        Swift.print("willBeginAt")

        let item = draggedItems[0] as! (String, NSColor);

        fromIndex = items.index(where: { (_item: (String, NSColor)) -> Bool in
            return _item.0 == item.0
        });

        session.draggingPasteboard.setData(Data(), forType: REORDER_PASTEBOARD_TYPE)
    }

    func outlineView(_ outlineView: NSOutlineView, acceptDrop info: NSDraggingInfo, item: Any?, childIndex index: Int) -> Bool {
        Swift.print("acceptDrop")

        if(fromIndex! != index && index != -1) {
            let toIndex: Int = fromIndex! < index ? index - 1 : index;

            outlineView.moveItem(at: fromIndex!, inParent: nil, to: toIndex, inParent: nil);

            items.insert(items.remove(at: fromIndex!), at: toIndex);

            return true;
        }

        return false;
    }

    func outlineView(_ outlineView: NSOutlineView, validateDrop info: NSDraggingInfo, proposedItem item: Any?, proposedChildIndex index: Int) -> NSDragOperation {
        if(item == nil) {
            return NSDragOperation.generic;
        }

        return [];
    }

    func outlineView(_ outlineView: NSOutlineView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, operation: NSDragOperation) {
        Swift.print("Drag session ended")
        fromIndex = nil;
    }

    //NSPasteboardItemDataProvider
    func pasteboard(_ pasteboard: NSPasteboard?, item: NSPasteboardItem, provideDataForType type: String)
    {
        item.setString("Outline Pasteboard Item", forType: type)
    }

}

解决方案

From https://developer.apple.com/reference/appkit/nsoutlineview :

Each item in the outline view must be unique. In order for the collapsed state to remain consistent between reloads the item's pointer must remain the same and the item must maintain isEqual(_:) sameness.

I was using Tuples (String, NSColor). And Tuples don't conform to the hashable protocol !

After switching from Tuples items to MyClass items, everything works fine ! (correct behaviour from the blue drag bar, and no blue rect when dragging)

class MyClass {
    var name: String!
    var color: NSColor!

    init(_ _name: String, _ _color: NSColor) {
        name = _name
        color = _color
    }
}

这篇关于NSOutlineView拖动线卡住+蓝色边框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆