Following is the image i have taken from an app from the App Store:
I have created an app that is using StoryBoard with custom tableview cell. The data is loaded in it from a web service. This is what i want:
1) How can i change the size of the uitableviewcell according to the image? For example if one image is 640*500, then the UITableViewCell will change its size accordingly. If the size if the image is 640*1000, then the cell should change its size accordingly.
2) How can i add the grey coloured border around the tableview cells just like in the image above?
3) How can i add a shadow dropping from the UITableViewCell just like in the image above?
Thanks!
Currently i have a partial answer to your question. Part 2 of the question that is the colored border can be solved by the following code:
[cell.contentView.layer setBorderColor:[UIColor colorWithRed:222/255.0f green:222/255.0f blue:222/255.0f alpha:1.0f].CGColor];
[cell.contentView.layer setBorderWidth:5.0f];
Part-1
The height of the tableviewcell is determined using
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
/*
Get the image size
CGFloat width = myImage.size.width;
CGFloat height = myImage.size.height;
use this to return the height of your cell.
*/
}
Part-2 and Part-3
Use..
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
//This will give you access to the cell being rendered and any customization you want can be done here... You can use the earlier answer for this part.. I havent tried it but should work..
}
Hope this helps..
Im using a tableview to display some information in a quiz app that Im working on. My question is how do i make the tableview only show the number of cells that I need. Ive set the number of rows delegate method like this:
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
but at the bottom of the table view are empty cells that are not needed. If I set the tableview style to grouped I get 5 cells and no empty ones below them. Ive seen that other people have done this but cant seem to work it out. I was wondering if they have somehow added a custom view to the table footer to cancel the empty cells out?
Any ideas or help appreciated.
If you do want to keep the separator, you could insert a dummy footer view. This will limit the tableview to only show the amount of cells you returned in tableView:numberOfRowsInSection:
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
In swift:
self.tableView.tableFooterView = UIView(frame: CGRectZero)
A much nicer method which doesn't require cell resizing is to turn off the default separator (set the style to none) and then have a separator line in the cell itself.
I was having a similar problem, how to show only separators for the cells that contain data.
What I did was the following:
Disable separators for the whole tableView. You can do that in the
inspector for the tableview in Interface builder or by calling
[yourTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];.
Inside your cellForRowAtIndexPath where you populate your tableview with cells create a new UIView and set it as a subview to the cell. Have the background of this view lightgray and slightly transparent. You can do that with the following:
UIView *separatorView = [[UIView alloc] initWithFrame:CGRectMake:
(0, cell.frame.size.height-1,
cell.frame.size.width, 1)];
[separatorView setBackgroundColor:[UIColor lightGrayColor]];
[separatorView setAlpha:0.8f];
[cell addSubView:separatorView];
The width of this view is 1 pixel which is the same as the default separator, it runs the length of the cell, at the bottom.
Since cellForRowAtIndexPath is only called as often as you have specified in numberOfRowsInSection these subviews will only be created for the cells that possess data and should have a separator.
Hope this helps.
This worked for me - I had extra empty rows at the bottom of the screen on an iphone 5 -
In my case I needed 9 rows
- (CGFloat)tableView:(UITableView *)tabelView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return self.tableView.frame.size.height / 9;
}
You can implement heightForRowAtIndexPath: and compute the correct height to only show 5 cells on the screen.
Are you always going to have 5 rows? If it's a dynamic situation you should set the number of rows according to the datasource of the tableview. For example:
return [postListData count];
This returns the count of the records in the array holding the content.
The tableview is only going to display the number of rows and sections that you tell it to. If you're always going to have just a single section, DON'T implement the method below.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
Without this the tableview will only have 1 section. With it, as you would imagine, you can specify the number of sections.
It is quite Simple. Just set the size of the popover like this:
self.optionPickerPopOver.popoverContentSize = CGSizeMake(200, 200);
Certainly you can adjust the size (200,200) depending upon the size of contents and number if rows.
Easy way would be to shrink tableView size. I.e. 5 cells 20 points each gives 100.0f, setting height to 100.0f will cause only 5 rows will be visible. Another way would be to return more rows, but rows 6,7 and so would be some views with alpha 0, but that seems cumbersome. Have you tried to return some clerColor view as footerView?
I think u can try changing the frame of the table view, if you want to adjust with the number of cells.
Try something like this:
[table setFrame:CGRectMake(x, y, width, height*[list count])];
height refers to height of the cell
As Nyx0uf said, limiting the size of the cell can accomplish this. For example:
- (CGFloat)tableView:(UITableView *)tabelView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat result;
result = 100;
return result;
}
implement these two methods in your UITableViewController:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
if (section == tableView.numberOfSections - 1) {
return [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
}
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if (section == tableView.numberOfSections - 1) {
return 1;
}
return 0;
}
In fact, these codes are telling tableview that you don't need to render the seperator line for me anymore, so that it looks the empty cells won't be displayed(in fact , the empty cell can not be selected too)
I have a UITableView with two sections. It is a simple table view. I am using viewForHeaderInSection to create custom views for these headers. So far, so good.
The default scrolling behavior is that when a section is encountered, the section header stays anchored below the Nav bar, until the next section scrolls into view.
My question is this: can I change the default behavior so that the section headers do NOT stay anchored at the top, but rather, scroll under the nav bar with the rest of the section rows?
Am I missing something obvious?
Thanks.
The way I solved this problem is to adjust the contentOffset according to the contentInset in the UITableViewControllerDelegate (extends UIScrollViewDelegate) like this:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat sectionHeaderHeight = 40;
if (scrollView.contentOffset.y<=sectionHeaderHeight&&scrollView.contentOffset.y>=0) {
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
} else if (scrollView.contentOffset.y>=sectionHeaderHeight) {
scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
}
}
Only problem here is that it looses a little bit of bounce when scrolling back to the top.
{NOTE: The "40" should be the exact height of YOUR section 0 header. If you use a number that is bigger than your section 0 header height, you'll see that finger-feel is affected (try like "1000" and you'll see the bounce behaviour is sort of weird at the top). if the number matches your section 0 header height, finger feel seems to be either perfect or near-perfect.}
You can also add a section with zero rows at the top and simply use the footer of the previous section as a header for the next.
Were it me doing this, I'd take advantage of the fact that UITableViews in the Plain style have the sticky headers and ones in the Grouped style do not. I'd probably at least try using a custom table cell to mimic the appearance of Plain cells in a Grouped table.
I haven't actually tried this so it may not work, but that's what I'd suggest doing.
I know it comes late, but I have found the definitive solution!
What you want to do is if you have 10 sections, let the dataSource return 20. Use even numbers for section headers, and odd numbers for section content. something like this
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section%2 == 0) {
return 0;
}else {
return 5;
}
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section%2 == 0) {
return [NSString stringWithFormat:#"%i", section+1];
}else {
return nil;
}
}
Voilá! :D
Originally posted Here, a quick solution using the IB. The same can be done programmatically though quite simply.
A probably easier way to achieve this (using IB):
Drag a UIView onto your TableView to make it its header view.
Set that header view height to 100px
Set the tableview contentInset (top) to -100
Section headers will now scroll just like any regular cell.
Some people commented saying that this solution hides the first header, however I have not noticed any such issue. It worked perfectly for me and was by far the simplest solution that I've seen so far.
There are several things that need done to solve this problem in a non-hacky manner:
Set the table view style to UITableViewStyleGrouped
Set the table view backgroundColor to [UIColor clearColor]
Set the backgroundView on each table view cell to an empty view with backgroundColor [UIColor clearColor]
If necessary, set the table view rowHeight appropriately, or override tableView:heightForRowAtIndexPath: if individual rows have different heights.
I was not happy with the solutions described here so far, so I tried to combine them. The result is the following code, inspired by #awulf and #cescofry. It works for me because I have no real table view header. If you already have a table view header, you may have to adjust the height.
// Set the edge inset
self.tableView.contentInset = UIEdgeInsetsMake(-23.0f, 0, 0, 0);
// Add a transparent UIView with the height of the section header (ARC enabled)
[self.tableView setTableHeaderView:[[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 23.0f)]];
Just change TableView Style:
self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped];
UITableViewStyle Documentation:
UITableViewStylePlain-
A plain table view. Any section headers or footers are displayed as inline separators and float when the table view is scrolled.
UITableViewStyleGrouped-
A table view whose sections present distinct groups of rows. The section headers and footers do not float.
Select Grouped Table View style from your tableView's Attribute Inspector in storyboard.
Set the headerView of the table with a transparent view with the same height of the header in section view. Also initi the tableview with a y frame at -height.
self.tableview = [[UITableView alloc] initWithFrame:CGRectMake(0, - height, 300, 400)];
UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)] autorelease];
[self.tableView setTableHeaderView:headerView];
Change your TableView Style:
self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped];
As per apple documentation for UITableView:
UITableViewStylePlain- A plain table view. Any section headers or
footers are displayed as inline separators and float when the table
view is scrolled.
UITableViewStyleGrouped- A table view whose sections present distinct
groups of rows. The section headers and footers do not float. Hope
this small change will help you ..
I found an alternative solution, use the first cell of each section instead a real header section, this solution don't appears so clean, but works so fine, you can use a defined prototype cell for your headers section, and in the method cellForRowAtIndexPath ask for the indexPath.row==0, if true, use the header section prototype cell, else use your default prototype cell.
Now that the grouped style looks basically the same as the plain style in iOS 7 (in terms of flatness and background), for us the best and easiest (i.e. least hacky) fix was to simply change the table view's style to grouped. Jacking with contentInsets was always a problem when we integrated a scroll-away nav bar at the top. With a grouped table view style, it looks exactly the same (with our cells) and the section headers stay fixed. No scrolling weirdness.
Assign a negative inset to your tableView. If you have 22px high section headers, and you don't want them to be sticky, right after you reloadData add:
self.tableView.contentInset = UIEdgeInsetsMake(-22, 0, 0, 0);
self.tableView.contentSize = CGSizeMake(self.tableView.contentSize.width, self.tableView.contentSize.height+22);
Works like a charm for me. Works for section footers as well, just assign the negative inset on the bottom instead.
I add the table to a Scroll View and that seems to work well.
Check my answer here. This is the easiest way to implement the non-floating section headers
without any hacks.
#LocoMike's answer best fitted my tableView, however it broke when using footers as well.
So, this is the corrected solution when using headers and footers:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return (self.sections.count + 1) * 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section % 3 != 1) {
return 0;
}
section = section / 3;
...
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section % 3 != 0) {
return nil;
}
section = section / 3;
...
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (section % 3 != 0) {
return 0;
}
section = section / 3;
...
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if (section % 3 != 2) {
return 0;
}
section = section / 3;
...
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if (section % 3 != 0) {
return nil;
}
section = section / 3;
...
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
if (section % 3 != 2) {
return nil;
}
section = section / 3;
...
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
int section = indexPath.section;
section = section / 3;
...
}
Swift version of #awulf answer, which works great!
func scrollViewDidScroll(scrollView: UIScrollView) {
let sectionHeight: CGFloat = 80
if scrollView.contentOffset.y <= sectionHeight {
scrollView.contentInset = UIEdgeInsetsMake( -scrollView.contentOffset.y, 0, 0, 0)
}else if scrollView.contentOffset.y >= sectionHeight {
scrollView.contentInset = UIEdgeInsetsMake(-sectionHeight, 0, 0, 0)
}
}
I've learned that just setting the tableHeaderView property does it, i.e. :
tableView.tableHeaderView = customView;
and that's it.
Since upgraded XCode to Version 3.2.3 with iPhone SDK 4 my code doesn't work anymore.
I have a default cell with style UITableViewCellStyleSubtitle and want to set the textAlignment of textLabel and detailTextLabel to center, but nothing happens.
Same code used before now not working anymore. On UITableViewCellStyleDefault center alignment still works.
Does anyone know how to solve this? I don't want to use a custom cell only in fact of this.
The reason why text isn't centered is because the label is only as wide as the text. You can confirm this by setting the background color of the text label:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.textLabel.backgroundColor = [UIColor orangeColor];
}
Setting the cell width manually also doesn't seem to have an effect. So you should really add your own subviews or create your own subclass of UITableViewCell.
The docs for UITableViewCellStyleSubtitle even say:
A style for a cell with a left-aligned
label across the top and a
left-aligned label below it in smaller
gray text. The iPod application uses
cells in this style.
here is a two-part solution to alter the label width after rendering, thus allowing the centering to happen:
-- (void) updateCenteringForTextLabelInCell:(UITableViewCell*)cell {
UILabel* label = cell.textLabel;
label.frame = CGRectMake(label.frame.origin.x, label.frame.origin.y, cell.contentView.frame.size.width, label.frame.size.height);
}
-- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// do your usual
// call the helper method
[self performSelector:#selector(updateCenteringForTextLabelInCell:) withObject:cell afterDelay:0.05];
}
ok finally the Apple development team answered my bug report from 23rd June 2010:
"Please try setting the text alignment
in layoutSubviews after calling
super."
I am building a UITableViewCell. I am using the style UITableViewCellStyleSubtitle for my table view cell. In the textLabel of the cell I have data that can require a wrap. So to accomodate, I want to move down the detailTextLabel so that the wrapped text isn't covered by the text in the detailTextLabel. I am attempting the following:
CGPoint tempPoint = tableViewCell.detailTextLabel.center;
tempPoint.y += 100;
tableViewCell.detailTextLabel.center = tempPoint;
I have tried similar approaches with the frame of the label, but I could not get it to move. When I log the y of the center point before and after, I always see it start as 0 and then it is just 100 afterwards. I am using the %f flag in NSLog to view the value. This all occurs in the function:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Any help would be great.
I subclassed UITableViewCell and implemented the - (void)layoutSubviews method. I moved the label in that method.