So my UITableView has a header, which is the UIImageView shown, and comments below the image. I am trying to increase the space between the image and the comments table.
(I have tried increasing the height of the header, but it doesn't work in my case because it will result in a bigger UIImageView and the image won't cover the view completely)
I experimented with this hack:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CommentsTableCell";
CommentsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Comment *comment = [self.comments objectAtIndex:indexPath.row];
[cell setUsername:comment.handle andText:comment.text];
/* Dirty hack:
1. We cannot increase the height of the header because that will leave spaces in the image.
2. The only way we can increase the margin from the comments table to the picture is by
increasing the individual inset of the first and last comments cell
*/
if (indexPath.row == 0) {
[cell setContentInset:UIEdgeInsetsMake(COMMENTS_PADDING * 10 , 0, 0, 0)];
} else if (indexPath.row == [self.comments count] - 1) {
[cell setContentInset:UIEdgeInsetsMake(0, 0, COMMENTS_PADDING * 10 , 0)];
}
return cell;
}
and in my CommentsCell.m:
- (void)awakeFromNib {
self.commentText.scrollEnabled = false;
self.commentText.editable = false;
self.commentText.contentInset = UIEdgeInsetsMake(-1 * COMMENTS_PADDING, 0, 0, 0);
}
- (void)setUsername:(NSString *)username andText:(NSString *)text {
[self.commentText setAttributedText:[CommentsCell getContentStringForUsername:username andText:text]];
}
- (void)setContentInset:(UIEdgeInsets)inset {
self.commentText.contentInset = inset;
}
but the first comment still has the same inset. I checked the debugger and awakeFromNib is occurring before cellForRowAtIndexPath. Do you see why my method is not working?
I am also open to other suggestions.
You should be able to add some space to the header view just below the image you display. Instead of setting the table's header view to a UIImageView, why not create a container view that you can add the image view to and then just have some space below it.
- (UIView *) buildTableHeaderView {
UIImage *image = [UIImage imageNamed: #"my_image.png"];
CGFloat height = image.size.height + 20;
UIImageView *imageView = [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, self.myTableView.frame.size.width, height)];
[imageView setImage: image];
UIView *headerView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, self.myTableView.bounds.size.width, height)];
[headerView addSubview: imageView];
return headerView;
}
What you can do is create a custom UIView (with .xib if you want for easier UI design) with a space on the bottom and return it from - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section method of the UITableViewDelegate, also don't forget to return the height for the header view by implementing the - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section method of the same UITableViewDelegate.
Here is a short example:
-UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
YourCustomHeaderView *headerView = [YourCustomHeaderView instantiateView]; //static method (you can rename it) that will load the custom view from a .xib
//do aditional UI setup or not
return headerView;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return DEFAULT_HEADER_HEIGHT; //a defined value
}
If you are having a single header view, then you should use the same custom header view creation/init/setup, but move your table downwards in is superview and add the custom header view at the top at any position you like.
Related
Hi i am new for ios and in my app i have created one UITableView and i have set background image for UITableViewcell but image not filling the whole width of screen as like below screen. Why this problem is occuring?
I mean UITableViewCell left and right sides gap is coming images is not filling whole cell width.
please help me someone
my code:-
#import "TableViewController.h"
#interface TableViewController ()
{
UITableView * tableList;
TableCell * Cell;
}
#end
#implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
tableList = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen]bounds].size.width, [[UIScreen mainScreen]bounds].size.height) style:UITableViewStylePlain];
tableList.delegate = self;
tableList.dataSource = self;
tableList.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:tableList];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"MyCell";
Cell = (TableCell *)[tableList dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (Cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"TableCell" owner:self options:nil];
Cell = [nib objectAtIndex:0];
}
//UIImageView *imageBackground = [[UIImageView alloc] init];
if (indexPath.row == 0) {
Cell.backGroundImage.image = [UIImage imageNamed:#"cell_top.png"];
} else if (indexPath.row == 9) {
Cell.backGroundImage.image = [UIImage imageNamed:#"cell_bottom.png"];
} else {
Cell.backGroundImage.image = [UIImage imageNamed:#"cell_middle.png"];
}
//imageBackground.contentMode = UIViewContentModeScaleToFill;
//Cell.backgroundView = imageBackground;
return Cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 44.0;
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if ([cell respondsToSelector:#selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:#selector(setPreservesSuperviewLayoutMargins:)]) {
[cell setPreservesSuperviewLayoutMargins:NO];
}
if ([cell respondsToSelector:#selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
#end
Try to set the layoutMargins property of the cells and the UITableView to UIEdgeInsetsZero.
- (void) viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
tableList.layoutMargins = UIEdgeInsetsZero;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
[...]
Cell.layoutMargins = UIEdgeInsetsZero;
return Cell;
}
Also check for the contentMode of the UIImageview.
Cell.backGroundImage.contentMode = UIViewContentModeScaleAspectFill;
try set contentInset on Left = 0
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
Use Debug View Hierarchy to figure out UITableView, UITableViewCell or UIImage is not filling the whole width of screen
http://www.raywenderlich.com/98356/view-debugging-in-xcode-6
Please check your "TableCell" in the storyboard. Did you select custom insets option for your custom cell?
Rather than setting up your table view with code, you want to do this in a storyboard. Then you'll want to use auto layout to connect constraints from the table view to the view controller's view. There are lots of tutorials available to teach you how to do this. Learning this will make things much easier in the long run.
Change the name of your tableList property to tableView. That will make more sense to other developers (including yourself in the future), since that's what it is (a UITableView instance).
Your cell is named Cell with a capital C, but you don't want to name properties with capital letters. Also, it doesn't need to be a class property the way it's being used. Remove it from the #interface section.
Coding Guidelines for Cocoa
Remove the -numberOfSectionsInTableView: method. The default is 1, so you don't need code to return the default value.
Instead of -dequeueReusableCellWithIdentifier:, use -dequeueReusableCellWithIdentifier:forIndexPath:. Then you won't need to follow it with a test to see if a cell was returned (it always will be). You'll need to register your nib with -registerNib:forCellReuseIdentifier:. Or better yet, just design it in the storyboard.
It appears that your custom table view cell has a UIImageView named backGroundImage. That should be added as a subview to the cell's backgroundView property (which you'll need to create - the view, not the property, which is already part of UITableViewCell). Set the image view's autoresizingMask so it will resize with the backgroundView:
- (void)awakeFromNib
{
[super awakeFromNib];
self.backgroundView = [[UIView alloc] initWithFrame:self.bounds];
self.backGroundImage.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.backGroundImage.frame = self.backgroundView.bounds;
[self.backgroundView addSubview:self.backGroundImage];
}
Remove the -tableView:heightForRowAtIndexPath: method. You only want to use this if you return different values. The default row height is 44.0, so you don't need to do anything else.
I have a tableview with a header view on it and paging enabled:
[super viewDidLoad];
CGRect headerFrame = [UIScreen mainScreen].bounds;
UIView *header = [[UIView alloc] initWithFrame:headerFrame];
header.backgroundColor = [UIColor flatWhiteColor];
self.tableView.tableHeaderView = header;
self.tableView.pagingEnabled = YES;
The Cells are the height of the screen:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [UIScreen mainScreen].bounds.size.height;
}
however, when I run it on my iPhone 6, the first table cell is never highlighted properly:
when its not highlighted
when I select the cell
help anyone?
The problem is because the height of headerView it's not actually equal with the size of the tableView and on the next page(the first table cell) you are seeing a part from the headerView.
Try this code:
CGRect headerFrame = CGRectMake(0, 0, self.tableView.frame.size.width, self.tableView.frame.size.height);
and
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return self.tableView.frame.size.height;
}
I found out the answer. It turns out a UIView inside my header was a bit too long and overlapped into my table cell. Thanks for your answers!
I have to add one background rectangle image on top of all rows in UITableView.
For example, please check the below reference image where a red arrow indicates this image.
This image is appended in tableview itself, because if I scroll the tableView, this image moves alongwith it.
I'd like to know how to insert such an image on top of all rows in UITableView.
I added UITableView in XIB and displaying contents handled in coding.
Please help!
The UITableView has tableHeaderView property
Example:
UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 130.0f)];
UIImageView *thumbnail = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 130.0f)];
[thumbnail setImageWithURL:[NSURL URLWithString:[[initDictionary objectForKey:#"cover_image"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
thumbnail.contentMode = UIViewContentModeScaleAspectFill;
thumbnail.clipsToBounds = YES;
[header addSubview:thumbnail];
self.tableView.tableHeaderView = header;
Ref: UITableView Apple Doc
Create a view and set is as a tableHeaderView property of your UITableView.
Example:
// Create a view.
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0.0f,
0.0f,
320.0f,
70.0f)];
// Customize your view.
// ...
// Set the view as a table view header.
self.tableView.tableHeaderView = headerView;
You can place this code for example in viewDidLoad method of your view controller. Here is what documentation says about it:
tableHeaderView
An accessory view that is displayed above the table.
Based on UITableView Class Reference
You have to mix dynamic with static cells, only the first cell will be static in this case, with the code something like:
#pragma Mark TableView DataSource Methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 2;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if(section == 0){
return 1;
}else{
return 10;
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if(indexPath.section == 0 ){
//Static cell
static NSString *idCell = #"cell";
UITableViewCell * cell = (UITableViewCell * )[tableView dequeueReusableCellWithIdentifier:idCell forIndexPath:indexPath];
return cell;
}
//Then you code your dynamic cells...
}
Hope it helps!
I have a UITableView with a number of sections (not rows). I'd like to add the UIImageView as a separator between each sections at the center (except the last cell).
The space between cells is 30
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 30;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = [[UIView alloc] init];
headerView.backgroundColor = [UIColor clearColor];
return headerView;
}
The screenshot
I'd like to set the position like at the screenshot.
The code I've made
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
The cell height is 81.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Some code
UIImageView *separatorIView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 96, 196, 2)];
[separatorIView setImage:[UIImage imageNamed:#"grayline.png"]];
[cell.contentView addSubview:separatorIView];
return cell;
}
The grayline appears if I set the y coordinate < then cell height.
Thanks in advance.
The result
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 30;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = [[UIView alloc] init];
headerView.backgroundColor = [UIColor clearColor];
if (section > 0) {
UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(62, 14, 196, 2)];
[img setImage:[UIImage imageNamed:#"grayline.png"]];
[headerView addSubview:img];
}
return headerView;
}
Custom separator position is not possible because they are privately defined for its frame, apart from that if you need that kind of effect then you have to add a image in header like custom space and color with require view with that only you can get the desired view
As you are setting a head view height you can add separator in header. Table View has a delegate method named "viewForHeaderInSection".
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 5)];
[img setImage:[UIImage imageNamed:#"grayline.png"]];
return img;
}
If you set the separator image in this delegate method you don't need to do anything in cellForRowAtIndexPath.
Let me know if that helps... :)
Edit:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 5;
}
`
You can set Separator color using setSeparator color in which you can pass image
like,
[self.tableView setSeparatorColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"grayline.png"]]];
just try to make the height of the last header as zero and see if it works.
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if(make_cndition_for_lastsection)
return 0;
else
return 30;
}
I am trying to get section header view using this code:
[tableView headerViewForSection:indexPath.section];
but this code always returns me nil.
Could you give me some examples to get section header view from table view?
This is my viewForHeader implementation:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
DynamicHeader *headerView = [[DynamicHeader alloc] init];
headerView.frame = CGRectMake(0, 0, 320, 40);
UILabel *headerLbl = [[UILabel alloc] init];
headerLbl.frame = CGRectMake(10, 10, 300, 20);
if(((SectionViewController *)sharedInstance.currentViewController).currentSectionType == 25)
{
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"minus.png"]];
imgView.frame = CGRectMake(285, 14.5, 16, 13);
[headerView addSubview:imgView];
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:sharedInstance action:#selector(headerTap:)];
[headerView addGestureRecognizer:recognizer];
headerView.tableView = tableView;
headerView.heightForRows = 95;
headerView.isOpen = YES;
}
headerLbl.text = [[[[[((SectionViewController *)sharedInstance.currentViewController).responseDictionary valueForKey:DATA_PARAMETER] valueForKey:SECTION_TABLE_PARAMETER] objectAtIndex:section] valueForKey:TABLE_SECTION_HEADER] capitalizedString];
[headerView addSubview:headerLbl];
return headerView;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if((DynamicHeader *)[tableView headerViewForSection:indexPath.section] != nil)
{
return ((DynamicHeader *)[tableView headerViewForSection:indexPath.section]).heightForRows;
}
else
{
return 95;
}
}
- (void)headerTap: (UITapGestureRecognizer *)recognizer
{
DynamicHeader *view = (DynamicHeader *)[recognizer view];
if(view.isOpen)
{
view.heightForRows = 0;
}
else
{
view.heightForRows = 95;
}
view.isOpen = !view.isOpen;
[view.tableView beginUpdates];
[view.tableView endUpdates];
}
Quite old question, but maybe a solution is helpful to others too...
An UITableView does create cell, header and footer views only if they are needed (e.g. they are visible in the table view content area).
If the cell, header or footer view isn't visible in the table view, a call to 'cellForRowAtIndexPath:', 'headerViewForSection:' or 'footerViewForSection:' might return 'nil'.
(See UITableView.h for documentation of this behaviour. The only exception would be, that the view has not jet been recycled by the table view)
Of course you can create any table view subview by calling the responsible delegate method directly, but UITableView wouldn't do so by itself.
So the solution to access a cell, header oder footer view is to make it visible in the table view first.
An example for an header view:
CGRect sectionHeaderRect = [self.tableView rectForHeaderInSection:groupSectionIndex];
[self.tableView scrollRectToVisible:sectionHeaderRect
animated:NO];
// Let the tableview load the needed views
dispatch_async(dispatch_get_main_queue(), ^{
UITableViewHeaderFooterView* groupSectionHeaderView = [self.tableView headerViewForSection:sectionIndex];
// Use groupSectionHeaderView
});
Use this delegate method to access the header view:
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
Have you implemented
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
and
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
in your ViewController subclass?
And if yes, probably you have some problem in one of these methods.
Your header view must inherit from UITableViewHeaderFooterView or else this call will not work and always returns nil.
Where are you calling [tableView headerViewForSection:indexPath.section];?
If you are calling it in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath before the tableView is visible then you will get nil back as the tableView is not setup yet.
If you call it else where once the tableView is loaded, you should get a UITableViewHeaderFooterView back.
heightForRowAtIndexPath called before viewForHeaderInSection so of course you will get nil.