2017-09-07 3 views
0

Dans mon application Mac OS, j'ai besoin d'une fonctionnalité pour pouvoir déplacer NSImageView à l'intérieur d'un NSView après que l'événement mouseDown (déclenché par l'utilisateur) se soit produit dans ce NSImageView. Lorsque l'utilisateur déclenche un événement Up de la souris, cette vue doit être déplacée vers la dernière direction de l'événement mouseDrag et y rester. Pendant le mouvement, je veux que NSImageView soit visible sur l'écran (il devrait se déplacer avec le curseur de la souris).Comment déplacer NSImageView dans NSView dans Cocoa?

J'ai lu un guide des événements Souris Manipulation par Apple, https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/HandlingMouseEvents.html Aussi j'ai téléchargé cet exemple de code: https://developer.apple.com/library/content/samplecode/DragItemAround/Introduction/Intro.html

Les deux liens contiennent du code dans le code Objectif C pour DragItemAround est obsolète. J'ai essayé de rechercher des solutions sur GitHub et d'autres threads StackOverflow, mais je n'ai trouvé aucune solution de travail.

Je serais ravi d'entendre les réponses à cette question. J'utilise Swift 3.

J'ai créé un MovableImageView personnalisé qui est une sous-classe de NSImageView avec ce code:

import Cocoa 

class MovableImageView: NSImageView { 

    override func draw(_ dirtyRect: NSRect) { 
     super.draw(dirtyRect) 

     // Drawing code here. 
     // setup the starting location of the 
     // draggable item 

    } 

    override func mouseDown(with event: NSEvent) { 
     Swift.print("mouseDown") 

     //let window = self.window! 
     //let startingPoint = event.locationInWindow 


    } 


    override func mouseDragged(with event: NSEvent) { 
     Swift.print("mouseDragged") 

     self.backgroundColor = NSColor.black 

    } 

    override func mouseUp(with event: NSEvent) { 
     Swift.print("mouseUp") 
    } 

} 

Après cela dans Interface Builder j'ai mis cette classe à NSImageView. J'ai également défini des contraintes dans Interface Builder pour ce NSImageView.

Maintenant j'essaie de comprendre comment déplacer NSImageView dans NSView? (Swift 3, XCode 8)

+0

Vous une mauvaise créature sous-classement. Sous-classe NSView à la place. –

+2

@ElTomato Non, NSImageVIew est une sous-classe de NSControl qui est une sous-classe de NSView. Donc ça devrait aller. – brianLikeApple

Répondre

1

Vous devez enregistrer le point mouseDown et l'utiliser ultérieurement pour le décalage. S'il vous plaît vérifier le code suivant:

class MovableImageView: NSImageView { 

var firstMouseDownPoint: NSPoint = NSZeroPoint 

init() { 
    super.init(frame: NSZeroRect) 
    self.wantsLayer = true 
    self.layer?.backgroundColor = NSColor.red.cgColor 
} 

required init?(coder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 

override func draw(_ dirtyRect: NSRect) { 
    super.draw(dirtyRect) 

    // Drawing code here. 
} 

override func mouseDown(with event: NSEvent) { 
    Swift.print("mouseDown") 
    firstMouseDownPoint = (self.window?.contentView?.convert(event.locationInWindow, to: self))! 
} 

override func mouseDragged(with event: NSEvent) { 
    Swift.print("mouseDragged") 
    let newPoint = (self.window?.contentView?.convert(event.locationInWindow, to: self))! 
    let offset = NSPoint(x: newPoint.x - firstMouseDownPoint.x, y: newPoint.y - firstMouseDownPoint.y) 
    let origin = self.frame.origin 
    let size = self.frame.size 
    self.frame = NSRect(x: origin.x + offset.x, y: origin.y + offset.y, width: size.width, height: size.height) 
} 

override func mouseUp(with event: NSEvent) { 
    Swift.print("mouseUp") 

    } 
} 

Dans la vue parent, il suffit d'ajouter cette MovableImageView comme sous-vue comme ceci:

let view = MovableImageView() 
view.frame = NSRect(x: 0, y: 0, width: 100, height: 100) 
self.view.addSubview(view) //Self is your parent view 

enter image description here

+0

C'est idiot. Adelmaer dit qu'il ou elle a un conteneur NSView avec un ou plusieurs objets à déplacer avec le pointeur de la souris. Dans ce cas, c'est NSView que vous devriez sous-classer. –

+2

@ElTomato NSImageView hérite finalement de NSView et met NSImageView à l'intérieur de NSView est très courant OOP. Qu'est-ce qui va pas avec ça? – brianLikeApple

+0

Merci @brianLikeApple, votre solution fonctionne très bien! – Adelmaer