how to get parent item of selected item outlineview Swift - 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?

Related

Expand item in NSOutlineView with NSTreeController

I'm trying (unsuccessfully) to get the node from a disclosure button clicked
I think this function is the more appropriate:
func outlineViewItemDidExpand(_ notification: Notification) {
let nodeToExpand = notification.userInfo as! Node
let nodeToExpand2 = notification.userInfo["NSObject"] as! Node
//Error #selector(_outlineControlClicked:) from sender NSButton 0x10053d710
}
NSTreeController wraps your nodes in NSTreeNode objects. Your node is representedObject of the NSTreeNode.
if let treeNode = notification.userInfo["NSObject"] as? NSTreeNode,
let node = treeNode.representedObject as? Node {
…
}

Create new column cell on button click outlineview

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()
}

uitableview scroll to top on data's first load

I am using reloadData() to load tableview data but my table view on its first load scrolls to top when it's loading data like so ... and that's not so nice to the user experience. Does anybody of you know the solution guys to stop this behavior. Thank you for your help !
I getting users from firebase and I am loading the images like so :
func getUsersFromFirebase(){
refUsers.observeSingleEvent(of: .value, with: { (snapshot) in
let usersNbr = snapshot.childrenCount
var counter = 0
var newUsers: [User] = []
for item in snapshot.children {
counter = counter + 1
let newitem:DataSnapshot = item as! DataSnapshot
let user = User(snapshot: item as!DataSnapshot,uid:newitem.key.description)
var newWishlists:[WishList]=[] self.refProducts.child(newitem.key.description).observeSingleEvent(of : DataEventType.value, with: { (snapshot) in
for item in snapshot.children {
let newItem:DataSnapshot = item as! DataSnapshot
let newWishlist=WishList.init(snapshot: newItem)
if(newWishlist.products.count != 0 && !newWishlist.name.trimmingCharacters(in: .whitespaces).isEmpty){
newWishlists.append(newWishlist)
}
}
user.wishLists=newWishlists
if(!(user.name=="" || user.image=="" ) ){
print("user privacy 1: " + user.isPrivate.description)
if(!user.isPrivate && user.wishLists.count != 0){
if(!user.isPrivate){
newUsers.append(user)
}
}
}
self.firebaseUsers = newUsers.shuffled()
GlobalVar.isAppFirstLoad=false
GlobalVar.allUsers = self.firebaseUsers
DispatchQueue.main.async {
self.reload(tableView: self.usersTableView)
print("user tableview reloaded 1")
}
})
}
}) { (error) in
print(error.localizedDescription)
MBProgressHUD.hideAllHUDs(for: self.usersTableView, animated: true)
}
}
func reload(tableView: UITableView) {
let contentOffset = tableView.contentOffset
tableView.reloadData()
tableView.layoutIfNeeded()
tableView.setContentOffset(contentOffset, animated: false)
}
I found the trick and its the .shuffled() that cause the behavior I think the array still shuffling when the tableview is reloading the data.
So anyone of you knows how the check if the array has finished shuffling?
So if you check in your code you have flag
GlobalVar.isAppFirstLoad=false
If you think with commom sense why it exist? you should check for
if condition that contains GlobalVar.isAppFirstLoad this value as true and in its block their will be some code that will be scrolling tableView to top.
Find it and remove it.

Can not insert items into NSOutlineView

I've been fighting with this NSOutlineView that should insert new items to the end of a group. My code is being called/hitting breakpoints but the new items don't appear in the NSOutlineView until I kill and restart the app.Not sure what I'm missing.
#objc func didReceaveNewFeeds(aNotification: Notification) {
guard let userinfo: [AnyHashable : Any] = aNotification.userInfo,
let newFeed: ManagedFeed = userinfo[Notification.Name.newFeedKey] as? ManagedFeed else {
return
}
let index: Int = sidebarDataSource?.allFeeds.count ?? 0
unowned let unownedSelf: MainViewController = self
DispatchQueue.main.async {
unownedSelf.sidebarDataSource?.allFeeds.append(newFeed)
unownedSelf.outlineview.insertItems(at: IndexSet([index]),
inParent: unownedSelf.sidebarDataSource?.allFeeds,
withAnimation: .slideRight)
}
}
I suspect the trouble you are having is because of this line:
unownedSelf.outlineview.insertItems(at: IndexSet([index]),
inParent: unownedSelf.sidebarDataSource?.allFeeds,
withAnimation: .slideRight)
I assume allFeeds is an array of data objects, and inParent argument expects an item (row) in the outline view's tree, or nil which would mean the root item.
You can get a reference to an outline view item with this method:
func item(atRow row: Int) -> Any?
You are correct in adding the new data to your data source with this line:
unownedSelf.sidebarDataSource?.allFeeds.append(newFeed)
So when you reload the application you are likely calling reloadData somewhere on the outline view and seeing the new data appear.
Because you are missing this sentence
unownedSelf.outlineview.expandItem(unownedSelf.sidebarDataSource?.allFeeds, expandChildren: true)

Print the NSTableView's row number of the row clicked by the user

I have a NSTableView with one column. I would like to print the row number of the row that the user has clicked on. I am not sure where I should start with this. Is there a method for this?
You can use the selectedRowIndexes property from the tableView in the tableViewSelectionDidChange method in your NSTableView delegate.
In this example, the tableView allows multiple selection.
Swift 3
func tableViewSelectionDidChange(_ notification: Notification) {
if let myTable = notification.object as? NSTableView {
// we create an [Int] array from the index set
let selected = myTable.selectedRowIndexes.map { Int($0) }
print(selected)
}
}
Swift 2
func tableViewSelectionDidChange(notification: NSNotification) {
var mySelectedRows = [Int]()
let myTableViewFromNotification = notification.object as! NSTableView
let indexes = myTableViewFromNotification.selectedRowIndexes
// we iterate over the indexes using `.indexGreaterThanIndex`
var index = indexes.firstIndex
while index != NSNotFound {
mySelectedRows.append(index)
index = indexes.indexGreaterThanIndex(index)
}
print(mySelectedRows)
}
Use -selectedRowIndexes
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSTableView_Class/#//apple_ref/occ/instp/NSTableView/selectedRowIndexes
Then you can use those indexes to grab the data from your dataSource
(typically an array)