NSTableView - Trying to fit exactly 9 rows - objective-c

I'm trying to size the rows of a NSTableView to exactly 9 rows fit. I've tried [menuTableView setRowHeight:floor(menuRect.size.height / 9)]; and I've tried [menuTableView setRowHeight:(menuRect.size.height / 9)]; and [menuTableView setRowHeight:ceil(menuRect.size.height / 9)]; but all of them have the same issue, if I've selected row 0 then row 9 is clipped at the bottom and if I select row 9 then row 0 is clipped at the top.
How can I set up a NSTableView to show 9 full rows so no matter what there is never a partial row visible?
Thanks,
edit: Yes menuRect is the frame for the menuTableView
edit:
Below is the full method I use to position the NSTableView and set the row height I've tried to remove any rounding issues with the use of the rowHeight variable. You can see with the attached screen shot that the last row isn't fully displayed
- (void) updateGUIPositions
{
NSRect screenRect = [self frame];
NSRect menuRect;
// Set the menu location on screen
NSInteger spacer = screenRect.size.width / 9;
menuRect.size.width = floor(screenRect.size.width - (spacer * 3)) / 2;
menuRect.size.height = ceil(screenRect.size.height - (spacer * 2));
NSInteger rowHeight = menuRect.size.height / 9;
menuRect.size.height = rowHeight * 9;
menuRect.origin.x = menuRect.size.width + (spacer * 2);
menuRect.origin.y = spacer;
[menuScrollView setFrame:menuRect];
// Setup the row height
[menuTableView setRowHeight:rowHeight];
}

I am not sure if this will work, but it sounds like a rounding error(I had the same problem with a UITableView). Try making the height of the NSTableView's frame 1px larger. So, menuTableView.frame.height = menuTableView.frame.height+1;
EDIT
Try using this...
`float rowHeight = menuRect.size.height / 9.0f;`

If you can fix the size of the rows and instead set the size of the frame programmatically, this related question suggests this formula works:
numRows * (rowHeight + intercellSpacing.height)
Using that formula, the scroller will draw, but you could just turn it off.

Related

Xcode - Round to closest X value considering altered base x/y positions

I'm currently working on a UICollectionViewLayout which is more or less similar to the Garageband iPad Appication - featuring reusable decoration/supplementary views.
One of the main features is gridline snapping - which would enable you to snap the X/Y frame positions of the GREEN cells to the nearest horizontal/vertical gridline.
The issue I'm having, is that the base X/Y position doesn't start at 0,0 because I have a floating column and floating row - so my snapping calculation is wrong because it doesn't consider the floating row/floating column width/height.
Here is an image illustrating my problem:
Here is my code for calculating the snapped positions:
CGPoint cellTopLeft = self.frame.origin;
CGFloat gridlineWidth = 30;
CGFloat floatingColumnWidth = 120; // width of the floating left column
CGFloat floatingRowHeight = 100; // height of the floating top row
CGFloat rowHeight = 100; // height of rows on the left (table 0, table 1, table 2, etc)
float snapped_x = [self closest:cellTopLeft.x toValue:gridlineWidth];
float snapped_y = [self closest:cellTopLeft.y toValue:rowHeight];
- (float)closest:(float)input toValue:(float)value {
return value * floorf((input / value) + 0.5);
}
As you can see by the "Grand 0" green cell that I'm actively dragging, the position is wrong.
Thanks #zrzka - sometimes the seemingly complicated bugs can be the easiest ones to solve, and just takes an extra pair of eyes.
The solution was:
float snapped_x = [self closest:cellTopLeft.x - floatingColumnWidth toValue:gridlineWidth] + floatingColumnWidth
float snapped_y = [self closest:cellTopLeft.y - floatingRowHeight toValue:rowHeight] + floatingRowHeight;

UITabBar Arrow Indicator for iPad

Following this tutorial, i ended up with a nice arrow for my UITabBar in iPhone.
Now i wanted to do the same for iPad, but it seems to not work.
I tried
- (CGFloat) horizontalLocationFor:(NSUInteger)tabIndex
{
CGFloat tabItemWidth;
CGFloat halfTabItemWidth;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
tabItemWidth = 320 / tabBarController.tabBar.items.count;
halfTabItemWidth = (tabItemWidth / 2.0) - (tabBarArrow.frame.size.width / 2.0);
}
else
{
tabItemWidth = 768 / tabBarController.tabBar.items.count;
halfTabItemWidth = (tabItemWidth / 2) - (tabBarArrow.frame.size.width / 2);
}
return (tabIndex * tabItemWidth) + halfTabItemWidth;
}
following the example, taking the tabBar dimensions for iPad, but the arrow is still so far from being in the middle of each tab.
Any help?
Try this in place of the current "horizontalLocationFor" method you have:
- (CGFloat) horizontalLocationFor:(NSUInteger)tabIndex
{
// Get the frame of the selected tab item's view.
// Add one becuase the first subview is the not a button.
CGRect tabFrame = [[[[[self tabBarController] tabBar] subviews] objectAtIndex:tabIndex+1] frame];
// Add tab x to half tab width and substract hald arrow image width to center it.
return tabFrame.origin.x + (tabFrame.size.width * .5) - (tabBarArrow.frame.size.width * .5);
}
The original solution assumed that the tab bar width was the entire screen, but on ipad 4 items only fills a portion of the tab bar width, hence dividing the width by the number of items doesn't get you the correct positions.

iOS: UIPickerView default dimensions

I would like to know the width of the dark grey frame on either side of the inside picker part and the width of the separators between components. This would be at default settings (eg. what's shown in the .xib). Or, how to find such values programmatically. Thank you
To clarify, I'm looking for what the "suggested minimums" might be for those values. I'm putting my UIPickerView in a popover, and the UIPickerView is wider than 320 px (which is what the .xib gives as the "default"). I would like to know these values so I can add them to the popover's width to make sure it doesn't cut off components on the right side of the UIPickerView.
Well this can be a little tricky since the Picker can have a dynamic number of components. So in order to find the widths you have to take into account the number of components. This can be done like so:
NSInteger n = picker.numberOfComponents;
const CGFloat separatorWidth = 8.0f;
const CGFloat sectionExceedWidth = -2.0f;
CGFloat totalWidth = picker.bounds.size.width;
CGFloat panesWidth = totalWidth - separatorWidth * (n - 1);
for (NSInteger i = 0; i < n; i++) {
CGFloat sectionWidth = [picker rowSizeForComponent:i].width + sectionExceedWidth;
panesWidth -= sectionWidth;
}
CGFloat leftPaneWidth = ceilf(panesWidth * 0.5f);
CGFloat rightPaneWidth = panesWidth - leftPaneWidth;
CGFloat totalHeight = picker.bounds.size.height;
CGRect totalRect = CGRectMake(0, 0, totalWidth, totalHeight);
Where the left and right panes widths are found and the separator size is static.
This was pulled from here.

Adjust height of Storyboard-created UITableview to height of its contents

I've dragged a table view into my storyboard scene, but its height is static and won't adjust based on how many cells it contains unless I manually adjust it in storyboard. How can I get this table to adjust its own height based on the total height of its contents?
You're going to have to do some version of this:
Figure out how many cells will be displayed
Figure out the height for each cell
Do the math and set the height of the UITableView
Before you get mad (since I know that's pretty obvious), let me follow up with this:
If you know for sure how many cells will be displayed all the time (and it's a static value), you can just manually adjust the height in Interface Builder.
If you don't know for sure (which I'm guessing is the case, based on your question), you'll have to do #'s 1 thru 3 above at runtime. Then, because UITableView is a subclass of UIView, you can simply adjust its frame property.
For example:
I've got 7 cells.
Cells 1, 3 and 5 (indices 0, 2 and 4) are 20 pixels tall.
Cells 2, 4, 6 and 7 (indices 1, 3, 5 and 6) are 30 pixels tall.
I need a total display height of 180 pixels (you might actually need to play with this because of separators, etc..)
So, I can just call:
CGFloat newHeight = ... // Whatever you calculate
CGRect currentFrame = [[self MyTableView] frame];
[[self MyTableView] setFrame:CGRectMake(
currentFrame.origin.x,
currentFrame.origin.y,
currentFrame.size.width,
newHeight)
];
If you want to get really fancy, you can animate the change by wrapping it in a [UIView animationWithDuration:] block.
Hope this helps!
Update/Edit
Here's a kludgy way to do it... it works, but I'm sure there's a better way to do it. I do not claim this to be the best/fastest/most efficient way. This is more to show a principle. ;-)
- (CGFloat)totalHeightNeededForTableView:(UITableView *)tv {
CGFloat retVal = 0;
int sectionCount = [self numberOfSectionsInTableView:tv];
int rowCount = 0;
NSIndexPath *path = nil;
for (int i = 0; i < sectionCount; i = i + 1) {
rowCount = [self tableView:tv numberOfRowsInSection:i];
for (int j = 0; j < rowCount; j = j + 1) {
path = [NSIndexPath indexPathForRow:j inSection:i];
retVal = retVal + [self tableView:tv heightForRowAtIndexPath:path];
}
}
return retVal;
}

How do you change the width of a UITableView?

I'm new to iPhone development, coming from a web application development background and I'm working on my first project. I chose to create a Navigation based project, since after reading it seemed to be the easiest way to get what I'm after. How do you change the width of the UITableView? Eventually, I'd like to have a top bar, UITableView, and bottom bar be 304px wide. I've tried the following in my RootViewController's viewDidLoad method, but I'm doing it wrong:
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.size.width = 200;
self.tableView.frame = tableViewFrame;
Thanks for any help in advance.
If you want to change the width of the tableViewCell.. go to cellForRowAtIndexPath, and assign it there.
You could also do -
CGFloat tableBorderLeft = 1;
CGFloat tableBorderRight = 1;
CGRect tableRect = self.view.frame;
tableRect.origin.x += tableBorderLeft; // make the table begin a few pixels right from its origin
tableRect.size.width -= tableBorderLeft + tableBorderRight; // reduce the width of the table
tableView.frame = tableRect;
For changing the size of header
-(CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section
{
return 150.0; //Give a value
}
For changing size of footer
-(CGFloat)tableView:(UITableView*)tableView heightForFooterInSection:(NSInteger)section
{
return 150.0;//Give a value
}