UITableViewAutomaticDimension not working in Xcode 6.3 - xcode

I updated my Xcode to 6.3 along with Swift 1.2, and I made the transition.
Everything works except dynamic row height for table view. I have those on 3 completely different table views, so it probably isn't something else influencing the bug.
I set all of the table views to:
tableView.rowHeight = UITableViewAutomaticDimension
and all of my xib files are properly constrained.
Any ideas?

I simply added UITableViewAutomaticDimension to estimatedrowforindexpath as well. You can see how it works on the BEAM App (under 'people' category).
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;
}

Estimated row height needs to be provided.
It is better not to implement estimatedHeightForRowAtIndexPath: unless necessary.
estimatedRowHeight is cheaper provided you can come up with a value
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 30 //Provide any appropriate value

Related

Add a custom section to UITableView when working with NSFetchedResultsController

I'm working with NSFetchedResultsController to fill one of my UITableViews with data grouped into sections. Now I want to add a new section atop all the fetched sections created by data that would not be fetched (I'm creating an additional array for that). Is there a nice way to insert that array without breaking all the nice NSFetchedResultsController behavior?
Update
What I've tried so far is to manually adjust every use of the indexPath. When ever a method (i.e. -tableView:numbersOfRowsInSection) get's called I check if it's the first section and if so I would take the data from my array instead of the NSFetchedResultsController. If not, I would just create a new NSIndexPath with the original indexPath's row and the section - 1 to access the fetchedResults. This seems to be a rather naive approach. At least, this does not work for me (yet).
Thanks!
–f
I created a UITableViewDataSource with a mixture of static and dynamic sections. I do it by modifying NSIndexPath like you planned. Important is to modify the NSIndexPath in the delegate methods of NSFetchedResultsControllerDelegate, too:
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
indexPath = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:kSectionWithAdditionalRowIndex];
if (newIndexPath) {
newIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row + 1 inSection:kSectionWithAdditionalRowIndex];
}
[super controller:controller didChangeObject:anObject atIndexPath:indexPath forChangeType:type newIndexPath:newIndexPath];
}
The sample is taken from a subclass of my class CBUIFetchResultsDataSource.m, which is a generic UITableViewDataSource powered by a NSFetchedResultsController. I had to also overwrite -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section, -(id)objectAtIndexPath:(NSIndexPath*)indexPath and -(NSIndexPath*)indexPathForObject:(id)object.

Same code but different result with Xcode 3.2.6 and Xcode 4

Compiling with Xcode 3.26 and SDK 4.3 and I had a table with a search field and below that a section header which came into view after a search. To indicate it was a search table. The header was green and just said "Result". If not searching it was invisible.
Now compiling the same code with Xcode 4.1.1 and SDK 5.1 the header works the same way after a search but is always visible even when not searching. Turns grey and is floating on top of the table all the time below the navigation bar.
What can I do about it? Prefer the way it was before.
The code is like this.
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection: (NSInteger)section{if(tableView == self.searchDisplayController.searchResultsTableView)
{ UILabel *tempHeaderLabel=[[UILabel alloc]initWithFrame:CGRectMake(0,0,320,30)];
tempHeaderLabel.backgroundColor=[UIColor colorWithRed:67.0/255.0 green:126.0/255.0 blue:71.0/255.0 alpha:1.0];
tempHeaderLabel.textColor=[UIColor colorWithRed:227.0/255.0 green:227.0/255.0 blue:227.0/255.0 alpha:1.0];
tempHeaderLabel.font = [UIFont fontWithName:#"Georgia-BoldItalic" size:16];
tempHeaderLabel.text=#" Result";
return tempHeaderLabel;
}
else
return nil;
}

How to add row-span in view-based NSTableView?

I'm trying to get a table layout as shown below working with view-based NSTableViews that have been introduced in Lion.
There were multiple approaches described for cell-based NSTableViews, e.g. Mimic the artwork column, but these don't really apply for view based table views.
The idea is that the table gets populated by an array of objects, in one (or more) column spanning rows indicating that objects share some data in common. numberOfRowsInTableView: returns to total number of items (19 in the case of the attached image).
Has anyone tried something like this?
Layout
I was able to do this by using two separate NSTableViews that have their NSScrollView's scrolling synchronized. To learn how to synchronize multiple scroll view's (with the exact subclass code) read Scroll View Programming Guide for Mac - Synchronizing Scroll Views
I have groupTableView that has a single column and shows the views that represent the group. I also have itemTableView that has columns representing the items of the group. I use the same delegate/datasource methods with if-else-statements to check which NSTableView is being used and respond accordingly with the proper # of rows, cell view, etc.. Additionally, I implement the following delegate method to adjust the group table view's row height to be equal the sum of the item row heights of the rows in the group:
- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
if (tableView == self.groupTableView) {
NSUInteger firstRowIndexForGroup = ...;
NSUInteger lastRowIndexForGroup = ...;
CGFloat groupHeight = 0.0;
for (NSUInteger currentRowIndex = firstRowIndexForGroup; currentRowIndex <= lastRowIndexForGroup; currentRowIndex++) {
groupHeight += [self.itemTableView rectOfRow:lastRowIndexForGroup].size.height;
}
return groupHeight - [self.itemTableView intercellSpacing].height;
} else {
return self.itemTableView.rowHeight;
}
}
You must also call -noteHeightOfRowsWithIndexesChanged: every time the table view needs a group view because the height changes according to the number of rows in the group.
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
if (tableView == self.groupTableView) {
GroupRowView *view = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
// configure view
[tableView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndex:row]];
return view;
} else {
ItemRowView *view = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
// configure view
return view;
}
}
I disabled row selection and horizontal and vertical scroll bars on the group table view. I also made the horizontal grid solid for both table views. Finally, I position the group table view directly next to the item table view with no gap in between so it appears as if it's simply another column in a single table view. The result is a flawless implementation that has zero lag between the table views. To the user, it appears as if it's a single table view.
Could you not use an NSOutlineView instead? It's specifically designed to have grouping support.

View Based Table Cells on OS X not showing data properly

So I admit to being a total noob to cocoa, so I offer a noob question. I'm probably just missing the dumb obvious somewhere but i just cant seem to get my table to populate data.
I'm following the table view playground example but everytime i try to mimic the Basic TableView Window the first row becomes the height of the number of rows i added (at least thats what it looks like. Here is my code:
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
{
NSString *identifier = [tableColumn identifier];
if ([identifier isEqualToString:#"filename"]) {
// We pass us as the owner so we can setup target/actions into this main controller object
NSTableCellView *cellView = [fileBrowserTable makeViewWithIdentifier:identifier owner:self];
// Then setup properties on the cellView based on the column
cellView.textField.stringValue = [fileList filenameAtIndex:row];
cellView.imageView.objectValue = [[NSWorkspace sharedWorkspace] iconForFile:[fileList fullPathAtIndex:row]];
return cellView;
}
else if ([identifier isEqualToString:#"path"]) {
NSTextField *textField = [fileBrowserTable makeViewWithIdentifier:identifier owner:self];
textField.objectValue = [fileList pathAtIndex:row];
return textField;
}
else if ([identifier isEqualToString:#"preview"]) {
NSTextField *textField = [fileBrowserTable makeViewWithIdentifier:identifier owner:self];
textField.objectValue = [fileList previewAtIndex:row];
return textField;
}
return nil;
}
I think its worth mentioning that when using a the old school text field cell, I have no problems displaying data (of course the above code is different in that case) so im positive sure its not a problem with my data structure that holds the values. I have also set the correct delegate and data source
The cell using the 'filename' identifier uses the 'image and text table view cell' while the others use just a 'text table cell view'. Neither of them work so i'm guessing something is wrong with how I set my table up. But when comparing my table with that of the example, it's just a spitting reflection (minus identifiers file names).
One thing that I notice that I can't quite figure out is that the example says:
The NSTableView has two reuse identifier assocations: "MainCell" and "SizeCell" are both associated with the nib ATBasicTableViewCells.xib
I don't really understand this statement. However that being said, the example doesn't contain any ATBasicTableViewCells.xib nor does it have any associations with it (code or ib) that I can find.
Have you tried to set the rowSizeStyle of the NSTableView to NSTableViewRowSizeStyleCustom?
[UPDATE] Re-reading your question, it's not clear for me what your problem is. The solution I have given is related to problems with the size of each cell which is not taken into account unless the rowSizeStyle is set to custom.

Multiple UITableView but some rows smaller than others

I have multiple UITableViews for layout purposes on the screen. These are functionally working fine, I'm just boggled as to why they are displaying differently.
My 3 table views are: loginTableView, forgotPass and openAccount The delegate and datasource of all 3 is file's owner. This is what I have on the viewDidLoad:
#define TABLE_CELL_HEIGHT 50;
loginTableView.rowHeight = TABLE_CELL_HEIGHT;
forgotPass.rowHeight = TABLE_CELL_HEIGHT;
openAccount.rowHeight = TABLE_CELL_HEIGHT;
The loginTableView cells show up fine but the other two tables' cells are smaller in height than it. I'm using a custom method to create the cells (same method for all tables) and I can't spot any difference between how the different tables are set up.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return TABLE_CELL_HEIGHT;
}
try implementing this method in your tableView delegate.
Ah - it looks like the correct table view had "Separator = None" set in interface builder where the other two table views did not. This was adding a separator and making them the tiniest bit smaller than the other table view.

Resources