Create new column cell on button click outlineview - swift

I have an outlineview which displays list of data items. Attaching code and screenshot below. When I click on "Create New" button added to cell, I want to add a new item below selected cell.Any help?
#IBAction func CreateFolderClicked(_ sender: Any) {
let newMember = CubeData()
let newIndex = selectedItemIndex
let parent = foldersOutlineView.parent(forItem: foldersOutlineView.item(atRow: selectedRow))
if let parentTemp = parent as? CubeData{
let Temp = newMember.initWithNodeName(appName: "Testing", parent: parentTemp)
newMember.addFolder(folder: Temp)
foldersOutlineView.insertItems(at: newIndex, inParent: parentTemp.node, withAnimation: .slideDown)
foldersOutlineView.reloadData()
}

Related

How to save unique score in each TableViewCell?

I would like to save a score in a cell that I saved with Realm.
Here is an image of my program.
When I press the top left button, an alert pops up to add a new cell with a label. The cell is saved with realm and is displayed properly. Then on the cell, there is two buttons on each side which can add or subtract a number to the score under the label of the cell.
Now I want to save the score when I change it of each cell and if possible with realm too.
Here is where I want to save it :
class CellVC: UITableViewCell {
var scorepts: Int = 0
let realm = try! Realm()
var infosScore: Results<ScoreInfos>?
#IBAction func minusPressed(_ sender: Any) {
if scorepts != 0 {
scorepts -= 1
countScore.text = "\(scorepts)"
// save the score of the this cell cell
}
}
#IBAction func addPressed(_ sender: Any) {
scorepts += 1
countScore.text = "\(scorepts)"
// save the score of this cell cell
}
Then when it's saved, I need to load the cell scores when the view loads.
Thanks for your help.

How to open a view on long pressing on a collection view's particular row in swift?

This is the code I am using:
In viewDidLoad-
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.tapLeaveView))
self.collectionView.addGestureRecognizer(longPressRecognizer)
The method-
#objc func tapLeaveView(longPressGestureRecognizer: UILongPressGestureRecognizer){
if longPressGestureRecognizer.state == UIGestureRecognizer.State.began {
let touchPoint = longPressGestureRecognizer.location(in: self.view)
if let indexPath = collectionView.indexPathForItem(at: touchPoint) {
// code for the view I want
}
}
}
It works but it opens view on every row and I want it to open it at row no- 2 only.
The problem is in your code, you are getting the wrong touchpoint, it gets the wrong indexPath.
To get correct touchPoint
let touchPoint = longPressGestureRecognizer.location(in: collectionView)
Also, first, you need to find all the indexes of the particular row and need to check whether it contains in a row or not. If contain then you need to perform your action.
// Calculation for finding row index for particuler row
let numberOfColumn = 5 // Number of column in collection
let rowForTap = 2 // Your particuler row
let startingIndex = ((rowForTap * numberOfColumn) - numberOfColumn)
let arrGestureIndex: [Int] = Array((startingIndex)..<startingIndex + numberOfColumn) // Indexes of particuler row
In last
#objc func tapLeaveView(longPressGestureRecognizer: UILongPressGestureRecognizer){
if longPressGestureRecognizer.state == UIGestureRecognizer.State.began {
let touchPoint = longPressGestureRecognizer.location(in: collectionView)
if let indexPath = collectionView.indexPathForItem(at: touchPoint), arrGestureIndex.contains(indexPath.item) {
print(indexPath)
// code for the view you want
}
}
}
Another way you can add Gesture for particular cell inside the cellForItem method.

how to get parent item of selected item outlineview Swift

I have multilevel hierarchy in my outlineview. I am able to get the selected item and it's parent item using below code.
func outlineViewSelectionDidChange(_ notification: Notification) {
guard let outlineView = notification.object as? NSOutlineView else {return}
if let item = outlineView.item(atRow: outlineView.selectedRow) as? CubeData{
// Getting the parent item
if let parentItem = outlineView.parent(forItem: item) as? CubeData{
print("Parent Item value:", parentItem.node)
}
print("Selected Item value:", item.node)
}
}
But not able to get all the grand parent items.
For example A->B->C->D is my hierarchy and whenever I am selecting "D" I am able to get "C" and "D". I want all the parent items. Any help?

Function creating 2 identical instances of class instead of only 1

I am relatively new to iOS development, any help will be greatly appreciated!
I'm trying to create a new instance of a class 'Event'.
class Event {
var EventName: String
var EventPhoto: UIImage?
init?(EventName: String, EventPhoto: UIImage?) {
guard !EventName.isEmpty else {
return nil
}
// Initial initilization of the values
self.EventName = EventName
self.EventPhoto = EventPhoto
// If some of the values are left blank, this will return nil to signal the problem
}
}
Below is the override function, which from my understanding is responsible for creating the instance:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
guard let button = sender as? UIBarButtonItem, button === saveButton else {
os_log("Cancelling Action, The Save Button Was not Pressed", log: OSLog.default,type: .debug)
return
}
let EventName = NewEventNameField.text ?? ""
let EventPhoto = NewEventImage.image
event = Event(EventName: EventName, EventPhoto: EventPhoto)
}
From my understanding, the override function should create a new instance of the class, which would then be displayed in a table view controller displaying a table of 'events'. My problem here is; when the function is called by the "create instance" button, it creates 2 identical instances with the same EventName and EventPhoto extracted from a textfield and an image in the view controller. In the tableview, there are basically 2 events that are exactly the same being displayed, which is what I am having trouble with since I don't see the code calling init twice anywhere, and can't figure out why the instances was created twice. After being created the 2 instances act independently and function like 2 separate instances would.
Thanks!
Thank You for the help, I found the issue in TableViewController's code file:
#IBAction func unwindToEventList(sender: UIStoryboardSegue){
if let sourceViewController = sender.source as?
NewEventViewController, let event = sourceViewController.event{
if let selectedIndexPath = tableView.indexPathForSelectedRow {
events[selectedIndexPath.row] = event
tableView.reloadRows(at: [selectedIndexPath], with: .none)
} else {
//Adding a new event instead of editing it.
let newIndexPath = IndexPath(row: events.count, section: 0)
events.append(event)
tableView.insertRows(at: [newIndexPath], with: .automatic)
}
//let newIndexPath = IndexPath(row: events.count, section: 0)
//events.append(event)
//tableView.insertRows(at: [newIndexPath], with: .automatic)
}
}
Turns out that I accidentally appended the instance to the list events and inserted it into the table an extra time outside the if statement.

How do I change/modify the displayed title of an NSPopUpButton

I would like an NSPopUpButton to display a different title than the title of the menu item that is selected.
Suppose I have an NSPopUpButton that lets the user pick a list of currencies, how can I have the collapsed/closed button show only the currencies abbreviation instead of the menu title of the selected currency (which is the full name of the currency)?
I imagine I can override draw in a subclass (of NSPopUpButtonCell) and draw the entire button myself, but I would prefer a more lightweight approach for now that reuses the system's appearance.
The menu items have the necessary information about the abbreviations, so that's not part of the question.
Subclass NSPopUpButtonCell, override drawTitle(_:withFrame:in:) and call super with the title you want.
override func drawTitle(_ title: NSAttributedString, withFrame frame: NSRect, in controlView: NSView) -> NSRect {
var attributedTitle = title
if let popUpButton = self.controlView as? NSPopUpButton {
if let object = popUpButton.selectedItem?.representedObject as? Dictionary<String, String> {
if let shortTitle = object["shortTitle"] {
attributedTitle = NSAttributedString(string:shortTitle, attributes:title.attributes(at:0, effectiveRange:nil))
}
}
}
return super.drawTitle(attributedTitle, withFrame:frame, in:controlView)
}
In the same way you can override intrinsicContentSize in a subclass of NSPopUpButton. Replace the menu, call super and put the original menu back.
override var intrinsicContentSize: NSSize {
if let popUpButtonCell = self.cell {
if let orgMenu = popUpButtonCell.menu {
let menu = NSMenu(title: "")
for item in orgMenu.items {
if let object = item.representedObject as? Dictionary<String, String> {
if let shortTitle = object["shortTitle"] {
menu.addItem(withTitle: shortTitle, action: nil, keyEquivalent: "")
}
}
}
popUpButtonCell.menu = menu
let size = super.intrinsicContentSize
popUpButtonCell.menu = orgMenu
return size
}
}
return super.intrinsicContentSize
}
Ok, so I found out how I can modify the title. I create a cell subclass where I override setting the title based on the selected item. In my case I check the represented object as discussed in the question.
final class MyPopUpButtonCell: NSPopUpButtonCell {
override var title: String! {
get {
guard let selectedCurrency = selectedItem?.representedObject as? ISO4217.Currency else {
return selectedItem?.title ?? ""
}
return selectedCurrency.rawValue
}
set {}
}
}
Then in my button subclass I set the cell (I use xibs)
override func awakeFromNib() {
guard let oldCell = cell as? NSPopUpButtonCell else { return }
let newCell = MyPopUpButtonCell()
newCell.menu = oldCell.menu
newCell.bezelStyle = oldCell.bezelStyle
newCell.controlSize = oldCell.controlSize
newCell.autoenablesItems = oldCell.autoenablesItems
newCell.font = oldCell.font
cell = newCell
}
A downside though is that I have to copy over all attributes of the cell I configured in Interface Builder. I can of course just set the cell class in Interface Builder, which makes this superfluous.
One thing I haven't figured out yet is how I can have the button have the correct intrinsic content size now. It still tries to be as wide as the longest regular title.
And the second thing I haven't figured out is how to make this work with bindings. If the buttons content is provided via Cocoa Bindings then I can only bind the contentValues, and the cell's title property is never called.