how to keep the visible content after nstableview reloaddata? - cocoa

I have a subclassed nstableview whose data source array may increase, by calling reloadData: I can refresh to reflect the data updating.
But after reloadData:, the tableview will always scroll to the new cell with the same old row number (for example, if the tableview was showing the 2nd cell, after reloadData:, the tableview will scroll to the new 2nd cell, therefore, the visible content of the tableview will change). How can I disable this automatic behavior and keep the visible content unchanged after the updating?
thanks in advance!

Table views don't re-scroll when their content changes. Since you're changing the table content which underlies the currently displayed rows, you need to move the scroll yourself.
I don't have code for this, but I suggest using rowAtPoint: to find the initial position of the table view, identifying or calculating the new row index for that row's content, and then calling:
[tableView reloadData];
[tableView scrollRowToVisible:newIndex];

I got this problem fixed: first, I got the rect size changed amount; then after the reloadData: , scroll the tableview to the changed point (original point + delta parts) immediately with the clipview's scrollToPoint: method. It does it so fast that you cannot realize the operation there.

Related

Pre-creating UICollectionView cells - layout issue

I have a UITableView with 6 rows. Each row contains a single UICollectionView. Each collection view contains a single section with 10-15 cells. One view controller is the datasource and delegate for both the table view and the collection view.
I would like to address some performance issues when scrolling the tableview. Whenever a new section comes into view, there is a small pause while the collection view is created and filled. Since I have a fixed number of cells (< 100) and they are almost static (they are initially loaded from a web API but the data will change only a couple of times a week), I would like to pre-build each of the collection view cells in advance. I would prefer the user waits an extra half-second on launch than encounters jerky scrolling.
To accomplish this, I have updated my collectionView: cellForItemAtIndexPath: to check a dictionary of cells I am maintaining. It looks for a key composited from the collection view index and the indexPath for the cell. If the key exists, the corresponding object is returned. If none is found, the cell is built and also added to the dictionary. This step effectively prevents cells from being un-loaded and recycled, at the expense of using more memory.
But on launch, I still need to run this once for each cell to pre-populate the dictionary. I iterate over each table view cell, find the collection view, and call
[self collectionView:collectionView cellForItemAtIndexPath:indexPath];
This is almost enough. The cells are being created and stored in the dictionary, and when I scroll to a new collection view, I see that they are being pulled from the dictionary and are displayed. But all of the cells, and all of their contents, are shoved up in the top-left corner at {0,0}.
Some logging tells me that at the time the cells are created, the frame of the collection view is {{0, 0}, {0, 0}}. I assume this is why none of my layout is being applied?
How can I resolve this?
(Would also be interested in any general comments on my pre-loading implementation).
I resolved this by calling [cell layoutIfNeeded] on the UITableViewCell (not the collection view). A more thorough explanation is welcomed.

View based NSTableView with each view contains 3 labels with should resize based on Text

I need to create a view based tableview in Popover as specified below:
Tableview should be placed in Popover(Popover height should be same as tableview).
Each row should contain a view.
Each row view will contain 3 labels.
Labels should be auto re sizable based on its text height.
Based on 3 labels height, Cell row height should resize.
Based on all cell rows, tableview height should resize.
Based on tableview height, Popover should resize.
I have done this in a static format, but i need to do it in more dynamic format(in future i should be able to add more rows using same classes and methods).
Main problem i am facing is, i am unable calculate the size of cell view in tableView:heigthOfRow: since i don't know the text of labels in this point of time.
So i just created tableview cells in loadView itself and saved in array, and fetching from array in tableview delegate methods. But i think this is wrong way of doing so.
Note: All data to tableview will be given while loading the view itself. Labels are not editable.
Cocoa system resizes the subviews based on superview ,I think scenario that you are looking for is to resize super view based on subview size.
Following 2 solutions i can suggest right awyay,
1.You can choose to post notification upon size change in each subview and make immediate superview observe that.
2.Use globals for size of each subview in your case 3 labels, and have an API to calculate finalRect in your view of view based table view.
Hope this helps:) have a nice day.

mouseOver for NSTableView

I have NSTableView in my application and i have added the hovering effect for the rows by using HoverTableDemo.
I can get the hovering effect only for one row in my table.
It is not apply for the whole table.
How can i get Hovering effect for full table.
Can any body have any idea please revert me.
Take a look: https://stackoverflow.com/a/464828/1758762
You're on the right track with -mouseEntered: and -mouseExited:.
Look into NSView's -addTrackingRect:owner:userData:assumeInside: and -removeTrackingRect: methods.
I can get the hovering effect only for one row in my table.
You can either set up your tableView to create trackingRects for every row that's in there whenever the contents of the tableView change, or alternatively, set up/update one tracking area on the entire tableView whenever -tile or another layout related method is called.

View-based NSTableView renders blank rows after inserting new rows with animation

I have a view-based NSTableView that I'm backing with an `NSMutableArray . Periodically I go out grab some data and want to insert new rows into the table at the top.
When I do this without specifying an animation to insertRowsAtIndexes:withAnimation: it seems to work fine for hours on end. However, if I specify an animation, after about 7 or 8 inserts the table view starts to show blank rows where the inserts occurred. Scrolling down and then back up causes the new rows to render properly.
The code that calls insertRowsAtIndexes:withAnimation is in a block, and not running on the main thread, but my inserts happen inside of dispatch_async on the main queue, so I dont' think it related to multithreading.
Here is some code ... self.contents is my NSMutableArray.
dispatch_async(dispatch_get_main_queue(), ^{
[self.contentsTableView beginUpdates];
if(posts.count) {
for(NSDictionary* dictionary in [posts reverseObjectEnumerator]) {
FNPost* post = [[FNPost alloc] initWithDictionary:dictionary width:self.contentsTableView.frame.size.width];
post.delegate = self;
[self.contents insertObject:post atIndex:0];
[self.contentsTableView insertRowsAtIndexes:[NSIndexSet indexSetWithIndex:0] withAnimation: NSTableViewAnimationSlideLeft];
}
}
[self.contentsTableView endUpdates];
});
One thing I'm confused about is the part of the Apple NSTableView documentation for insertRowsAtIndexes:withAnimation that says:
The numberOfRows in the table view will automatically be decreased by
the count of indexes.
I'm confused by what that statement implies about the relationship between the number of objects in my array (and hence the result of numberOfRowsInTableView:) and the number of rows the table view thinks it has. To my thinking the number of rows in the table view should equal my array count and I want to make sure that my understanding of this is not at the root of the problem but like I said, the table works fine if no animation is specified.
Am I doing something obviously wrong here?
This issue turns out to be caused by having the NSTableView in a layer based view hierarchy. Two superviews up, I had a layer-backed view. After reading some other posts about NSTableView showing other errant behavior when in a layer-backed hierarchy I decided to turn off the layer in IB. Table animations now occur as I would expect at the expense of having to maintain some additional state to control the layer backing state when I want to use CA transitions between my views.

UITableView Scroll when new cells are added

In my app I have a pull down to refresh feature. Basically what this does is it adds some more cells to the top of my UITableView. However when I do this the screen automatically scrolls down. I want to keep my position on the screen when the new cells are loaded.
[dataPosts insertObject:[[MainButton alloc] initWithFrame:CGRectMake(0, 0, 320, 260) withData:0 hasNick:[self createRandomStringWithLength:140]] atIndex:0];
dataPosts is the data array of my UITableView. MainButton is a UIView with size 320,260 and it is added as a view into a UITableViewCell. So whenever I add a new entry to my data, the table automatically scrolls down 260 units but I want my position to stay the same. Thanks in advance.
-C
When the new rows are to be inserted you are aware how many rows are going to be inserted. So based on that you can call scrollToRowAtIndexPath:atScrollPosition:animated: method of UITableView to be at the same place even when new rows are inserted at the top.
E.g:
Currently 10 rows are displayed and 1st row is at the top.
Now suppose, new more 20 rows are to be inserted. Insert them without animation.
Now, call above mentioned method with indexPath.row of 21 without animation.
Hope that helps. Let me know if you are looking for something else.

Resources