I have a Table View Cell and have added an action to it that I want to execute when a value is changed.
I have added the action method in the viewController
#IBAction func valueEntered(sender: NSTextFieldCell)
{
print("valueEntered")
}
I can edit the Table View Cell by double clicking on it, but my method is never called.
I know I have done this before but I must be missing a step.
You have to hook up the NSTableView delegate.
In your case, control-click and drag from Reseller Table up to File's Owner and choose delegate.
Related
I have a custom UICollectionViewCell (let's call it MyCustomCell) that has a custom UITextField (let's call it MyCustomField) inside it that users can add text to. However, it seems no matter what I do, the tap inputs don't get from the MyCustomCell to its sub-view MyCustomField. Previously, I had this same arrangement, except MyCustomCell is a UITableViewCell, and that worked for some reason.
Right now I had to do a workaround, where whenever a cell is tapped, the cell sends a becomeFirstResponder() message to the textfield. However, this doesn't let the user tap on the "clear text" button inside the MyCustomField, nor does it let the user move the cursor around in the text field:
// function inside the MyCustomCell, called by the view controller
// whenever it thinks the user tapped on a cell:
func cellTapped()
{
// this is an instance of MyCustomField:
input.becomeFirstResponder();
}
Is there any way to "pass" the actual gesture to the MyCustomField (from either the MyCustomCell, or from the the view controller that manages them both)?
Update: this is what the view hierarchy looks like for the MyCustomCell (sub-class of UICollectionViewCell):
This may be of help to others who have similar issue: I believe #MultiColourPixel is correct in the comment above that there is a hidden "view" standing between the MyCustomField and MyCustomCell. What I did was:
Backed up the .xib and .swift files for the code for MyCustomCell and MyCustomField.
Delete the .xib and .swift files.
From the XCode menu, re-create the .swift file -- and make sure you check the "create XIB" as well when you create the .swift file / class that is subclass of the UICollectionViewCell.
Copy paste the old xib / swift contents into the new xib / swift.
It should work, without needing to explicitly send becomeFirstResponder() to the MyCustomField.
I have a (subclassed) NSCollectionView open, containing multiple text views. Each of the text views is mapped to a (subclassed) NSDocument object. (The idea is to use the document architecture's save functions but not its windowing functions, because I need multiple documents in the same window and the traditional document architecture doesn't allow that.)
Now, there's a function I'd like the user to be able to call from the main menu that will affect their currently selected document. That is: the document is currently visible in a text view with current focus, and the menu command should make an alteration to that document. But the sender of the menu command is just the menu. When the window controller handles the command from the menu, how can I tell it what the currently selected document is?
This is what the responder chain is for.
Since you're using NSCollectionView, you probably already have a subclass of NSCollectionViewItem. If not, create one. Implement your action method in this subclass. Example:
class DocumentItem: NSCollectionViewItem {
var document: MyDocument? {
return representedObject as? MyDocument
}
#IBAction func doThatThing(sender: AnyObject?) {
Swift.print("This is where I do that thing to \(document)")
}
// #IBOutlets and whatnot here...
}
You may need to set this as the custom class of your NSCollectionViewItem in your xib or storyboard.
Next, if your cell view (the view owned by your NSCollectionViewItem) isn't a custom subclass of NSView already, you should make it a custom subclass. You must override acceptsFirstResponder to return true:
class DocumentCellView: NSView {
override var acceptsFirstResponder: Bool { return true }
// #IBOutlets and whatnot here...
}
Make sure you set this as the custom class of your cell view in your storyboard or xib.
Finally, connect the action of your menu item to doThatThing: on First Responder:
Here's how it works:
Because the cell view now returns true for acceptsFirstResponder, when the user clicks a cell view in the collection view, the system will make it the first responder (the start of the responder chain).
When a view has a view controller, it makes that view controller the next responder after itself in the responder chain (if you are on OS X 10.10 Yosemite or later). Your cell view has a view controller: the item object you return from outlineView:itemForRepresentedObjectAtIndexPath:. (NSCollectionViewItem is a subclass of NSViewController, so your custom item is a view controller.)
When the user clicks the menu item, the menu item asks NSApplication to send its action along the responder chain, starting with the first responder. The first responder is the cell view, but it doesn't respond to the doThatThing: message. So NSApplication asks the view for its nextResponder, which is an instance of your NSCollectionViewItem subclass. That object does respond to doThatThing:, so NSApplication sends doThatThing: to your item object (with the NSMenuItem object as the sender argument) and doesn't check the rest of the responder chain.
I have a little problem, I want to add a function to two BarItems in my UINavigationBar, which is placed above the UITableView in a normal ViewController. I'm very new to programming so can you please give me the complete code that I need? The functions I want to have are:
An edit button so I can delete and change the data of a cell (title + subtitle)
An add button so I can add a new cell to my UITableView. Maybe also a function that points to another ViewController where I can type the data for Title and subtitle to save it afterwards.
Thanks!
For editing record:
You cannot get the cell that your planning to edit using button on UINavigationController, the buttons should be placed at the same cell on your UITableview to edit that specific cell. and in this way you need custom UITableviewcell.
For creating new record :
First link the button to your UIViewController class as Action.
You can append the array that your using to fill the UITableview and then call your UITableview like to refresh the data:
self.tableview.reloadData()
For presenting another UIViewController:
First drag new ViewController in your storyboard and link the button on the first ViewController into your new UIViewController and choose segue as "Show".
To save your data its a big topic you have either NSUserDefaults or CoreData so Google it.
Note : linking means by pressing ctrl-drag with mouse to your target.
Update :
Download your sample from here : https://yadi.sk/d/EJf610XWhkxDT
I have a tableview of items and when i click one row, I use uiactionsheet with 3 button: edit, remove and cancel. When I click button edit, I will open a modal view, so how can I do this ? what is the code to delete tablerow ?
If you want to delete a row from a UITableView, use the method named deleteRowsAtIndexPaths:withRowAnimation:. You can find all the details on the UITableView Class Reference page.
Also don't forget to remove the corresponding item from your model!
UIActionSheet has a delegate property. Add the UIActionSheetDelegate protocol to your view controller and set yourself as the delegate to the action sheet before you display it.
The action sheet will call
– actionSheet:clickedButtonAtIndex:
on it's delegate when the user selects and action.
In your implementation of this, you can do what you want, such as delete the row as fguchelaar described.
This method doesn't directly know which row the action sheet was called for, so you can either subclass UIActionSheet so it can store the indexPath, store the indexPath in your viewController, or pass the information in some other way.
I was wondering if with a UINavigationController, can you have a "+" sign, like the Contacts app, that adds a row to the main root view and has a default name as "Setup", then you can click on that row to go to one level below, change a value in a UIPickerview in the one level below UIViewController, and then press the back button and have that value from the UIPickerView be the name of the new row that was created?
Yes (though it's not very Apple-like UI behavior!)
You'd have to put some special logic in your table view data source to add the "Setup" row and go to the picker when that row was selected. The root view controller should implement the delegate from the picker to receive the new row's name, then call [self.tableView reloadData] to update the view.
A better practice would be to model the Contacts app and let the "+" button present a modal view controller from the bottom for your picker view. Look at the addButton implementation in SQLiteBooks or CoreDataBooks.