This is a bit complex but I hope that someone can help me. I am trying to build a drag and drop function for my OSX application.
This is how it is looking at the moment. So there is just a single textfield which the user can drag and drop around the view. It is simple enough with just one textfield but if there are several textfields it is getting complicated and I don't know how to approach. This is what I currently have:
@IBOutlet weak var test: NSTextField!
@IBAction override func mouseDragged(theEvent: NSEvent) {
NSCursor.closedHandCursor().set()
var event_location = theEvent.locationInWindow
test.frame.origin.x = event_location.x - 192
test.frame.origin.y = event_location.y
}
Test is the name of my NSTextField. I know the name of it so it is simple to move it arround. But if the user adds more textfields (see on the left pane) then I don't know how to address this textfield because I have no name of it (like "test" for the first input).
I am adding the textfields via this code:
let input = NSTextField(frame: CGRectMake(width, height, 100, 22))
self.MainView.addSubview(input)
How can I determine which textfield (if there are multiple on the view) was selected and then move the appropriate via drag and drop?
The drag and drop is working for that single static textfield
In computer graphical user interfaces, drag and drop is a pointing device gesture in which the user selects a virtual object by "grabbing" it and dragging it to a different location or onto another virtual object.
An item provider for conveying data or a file between processes during drag-and-drop or copy-and-paste activities, or from a host app to an app extension.
I have prepared a sample app, so consider this:
https://github.com/melifaro-/DraggableNSTextFieldSample
The idea is to introduce SelectableTextField
which inherits NSTextField
. SelectableTextField
provides facility for subscription of interested listener on text field selection event. It has didSelectCallback
block variable, where you need to set you handling code. Something like this:
textField.didSelectCallback = { (textField) in
//this peace of code will be performed once mouse down event
//was detected on the text field
self.currentTextField = textField
}
By using mentioned callback mechanism, once text field selected, we can store it in currentTextField
variable. So that when mouseDragged
function of ViewController
is called we are aware of currentTextField
and we can handle it appropriatelly. In case of sample app we need adjust currentTextField
origin according drag event shift. Hope it became better now.
P.S. NSTextField
is opened for inheriting from it, so you can freely use our SelectableTextField everywhere where you use NSTextField, including Interface Builder.
EDIT
I have checked out your sample. Unfortuantly I am not able to commit /create pull request into you repository, so find my suggestion here:
override func viewDidLoad() {
super.viewDidLoad()
didButtonSelectCallback = { (button) in
if let currentButton = self.currentButton {
currentButton.highlighted = !currentButton.highlighted
if currentButton == button {
self.currentButton = nil
} else {
self.currentButton = button
}
} else {
self.currentButton = button
}
button.highlighted = !button.highlighted
}
addButtonAtRandomePlace()
addButtonAtRandomePlace()
didButtonSelectCallback(button: addButtonAtRandomePlace())
}
override func mouseDragged(theEvent: NSEvent) {
guard let button = currentButton else {
return
}
NSCursor.closedHandCursor().set()
button.frame.origin.x += theEvent.deltaX
button.frame.origin.y -= theEvent.deltaY
}
private func addButtonAtRandomePlace() -> SelectableButton {
let viewWidth = self.view.bounds.size.width
let viewHeight = self.view.bounds.size.height
let x = CGFloat(rand() % Int32((viewWidth - ButtonWidth)))
let y = CGFloat(rand() % Int32((viewHeight - ButtonHeight)))
let button = SelectableButton(frame: CGRectMake(x, y, ButtonWidth, ButtonHeight))
button.setButtonType(NSButtonType.ToggleButton)
button.alignment = NSCenterTextAlignment
button.bezelStyle = NSBezelStyle.RoundedBezelStyle
button.didSelectCallback = didButtonSelectCallback
self.view.addSubview(button)
return button
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With