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.
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.
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Above Function is not Getting called when i select the cell inside UITableView which i have inserted inside the footerView of another UITableView
I have added the UITableView inside the below function and I able to see all the items which i have inserted
But I am not able to click on Cells.
I Have Also inserted Some UIButton to check if the click is working ,which working fine
(UIView *)tableView:(UITableView * )tableView viewForFooterInSection:(NSInteger)section
thanks in advance.
- (UIView *)tableView:(UITableView * )tableView viewForFooterInSection:(NSInteger)section {
if(tableView==_ordersListTable)
{
//creating view to pass to footerview
UIView *footerView;
footerView.userInteractionEnabled=true;
if(footerView == nil) {
//allocate the view if it doesn't exist yet
footerView = [[UIView alloc] init];
}
//initializing table
_paymentInfoTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 40, 320, 80)];
_paymentInfoTable.backgroundColor = [UIColor whiteColor];
_paymentInfoTable.delegate = self;
_paymentInfoTable.dataSource = self;
//_paymentInfoTable.separatorStyle = UITableViewCellSeparatorStyleNone;
_paymentInfoTable.separatorInset = UIEdgeInsetsMake(0, 110, 0, 180);
[footerView addSubview:_paymentInfoTable];
}
//return the view for the footer
return footerView;
} else
{
return 0;
}
}
Since you have two UITableViews to control, the delegates of both the UITableViews have to be set correctly. Did you set these delegates?
By checking the UITableView in the delegate methods, you can control both UITableViews:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.tableView1) {
// Do your thing with the first UITableView
}
else {
// Do your thing with the other UITableView
}
}
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 added Tableview on xib file(you can see on image).tableview is loading well . But last cell is out of screen so when I Swipe Up last index is showing. When I get off my hand, last cell is not appear. I don't change any height of tableview . Why not fixed to my screen ?
I am using reveal menu like facebook in this project : https://github.com/mikefrederick/MFSideMenu
Also You can see problem on movie.
https://www.dropbox.com/s/usfwdhl5w9znkl6/IMG_0006.MOV
viewcontroller.h
#property(nonatomic,retain)IBOutlet UITableView * tableview;
viewcontroller.m
-(void)viewDidAppear:(BOOL)animated
{
self.tableview.backgroundColor=[UIColor colorWithRed:(28/255.0) green:(28/255.0) blue:(28/255.0) alpha:1];
[self.tableview setSeparatorColor:[UIColor blackColor]];
}
- (void)viewDidLoad
{
[super viewDidLoad];
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
}
#pragma mark -
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section==0)
{
return 5;
}
if (section==1)
{
return 3;
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text =#"exampleCell";
NSLog(#"cell.contentView.bounds.size.width %1.0f",cell.contentView.bounds.size.width);
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if(section == 1)
return 40;
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
self.tableview.layer.cornerRadius = 10.0f;
tableView.layer.borderWidth = 2.0;
tableView.layer.borderColor = [UIColor redColor].CGColor;
return 60;
}
#pragma mark UITableViewDelegate
- (void)tableView: (UITableView*)tableView
willDisplayCell: (UITableViewCell*)cell
forRowAtIndexPath: (NSIndexPath*)indexPath
{
cell.backgroundColor =[UIColor colorWithRed:(41/255.0) green:(41/255.0) blue:(41/255.0) alpha:1];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
if([indexPath row] == ((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row){
//end of loading
//for example [activityIndicator stopAnimating];
}
}
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 30)];
[headerView setBackgroundColor:[UIColor colorWithRed:(112/255.0) green:(112/255.0) blue:(112/255.0) alpha:1]];
UILabel *titleLabel = [ [UILabel alloc] initWithFrame:CGRectMake(20, 0, 300, 44)];
titleLabel.text = #"MÜŞTERİ ALANI";
titleLabel.textColor = [UIColor whiteColor];
titleLabel.backgroundColor = [UIColor clearColor];
[headerView addSubview:titleLabel];
return headerView;
}
In your video, this menu appears to be a slide out menu, presumably using some third party slide out menu controller library. So this view controller is contained within some container view from that. It is possible that the slide out menu controller isn't properly sizing your view controller to fit its container view.
One solution would be to check any example apps that come with the slide out controller you're using to see if they suffer from the bug and report this to the developer if it is the case. This would be good because other developers would benefit from the improvements. In fact it's possible the slide out controller you're using has fixed this bug with a newer version already that you don't have yet.
Another solution, assuming there's an example app that doesn't suffer from this, is to see how it is adding its slide out menu and see if you're failing to do something that they're doing.
Lastly, if there's no example app or you can't figure out why theirs is working differently, try adding the following to your view controller's viewDidAppear: method:
self.view.frame = self.view.superview.bounds;
This assumes that the container view they create is properly sized.
Your problem seems to be in your xib.
You have to set the size of your View to "Freeform" then add autosizing constraints on your view like you did on your tableView.
first you should select the CELL, not the TABLE VIEW. Next, go to the attribute inspector and click the separator, and you should select the custom inserts. Lastly you can adjust the separator line according to your wish. Hope this will help you and others. Thanks for the question too.
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.