I have strange problem with tableViewHeader which I resize on scroll.
After first scroll to top, I have space between tableHeader and cells and after each next scroll, space increasing.
In tableViewHeader custom class, after scrolling I change height and return back, then resetting it, so UITableView will update frame size.
Also I have 0.1f height for first section view, UITableViewController,
self.automaticallyAdjustsScrollViewInsets = NO;
I double checked that tableViewHeader have right height.
I have tried many solutions, but nothing works for me.
What happens? Who is adding extra space and why?
EDIT: Table delegate and data source methods
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 0.001;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0.001;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0 && indexPath.row == 0) {
return [self nameCell];
}
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0 && indexPath.row == 0) {
return 60;
}
return 0;
}
-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if (section == 0) {
UIView* view = [[UIView alloc] initWithFrame: CGRectMake(0.0f, 0.0f, self.tableView.frame.size.width, 0.001f)];
return view;
}
return nil;
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView == self.tableView) {
[_tableHeader didScroll:scrollView.contentOffset];
}
}
Found a solution.
First of all, don't set tableViewHeader in custom class. Do it in controller where tableView inserted.
Second: wrap tableViewHeader set in beginUpdates, endUpdates.
I don't know how "updates" for cells used with tableViewHeader, but it works
i fixed that by putting the header(auto layout) into a wrap view which is a fixed UIView as subview. the gap will be gone.
self.header = [[NSBundle mainBundle] loadNibNamed:#"FriendDetailHeaderView"
owner:nil
options:nil][0];
self.header.frame = CGRectMake(0, 0, ScreenWidth, ScreenWidth/16*9+25);
UIView *aView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, ScreenWidth, ScreenWidth/16*9+25)];
aView.backgroundColor = [UIColor blackColor];
[aView addSubview:self.header];
self.tableView.tableHeaderView = aView;
the auto layout tableViewHeader sometimes can not work out. but in my previous project, set the auto layout view to tableView.tableViewHeader it works perfectly
Related
I have a scrollview which contains different subviews, one of which is tableview. I also have a UITapGestureRecognizer and UISwipeGestureRecognizer initialized on the scroll view. The tableview uses a nib to initialize its cell.
What I would like to do is that, when I swipe the cell to the left, I want a button to swipe in. I am able to trigger my handler when left swipe the cell. The problem is that it doesn't trigger the editActionsForRowAtIndexPath where I am handling the code to create a button.
Instead, it goes to editingStyleForRowAtIndexPath and ends executing showing a red icon with a minus sign to the left of the cell.
My swipe handler and related code is as below:
- (void)swipeLeftDirection:(UIGestureRecognizer*)gesture
{
if (!tblInviteesTable.editing)
{
CGPoint location = [gesture locationInView: tblInviteesTable];
iPath = [tblInviteesTable indexPathForRowAtPoint:location];
// quitEditing = NO;
OpenHouseTableViewCell *currentCell = (OpenHouseTableViewCell *)[self tableView:tblInviteesTable cellForRowAtIndexPath:iPath];
[currentCell setEditing:YES];
[tblInviteesTable setEditing:YES animated:YES];
[self tableView:tblInviteesTable editActionsForRowAtIndexPath:iPath];
}}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSLog(#"Handled editing style! %ld", (long)editingStyle);
} else {
NSLog(#"Unhandled editing style! %ld", (long)editingStyle);
}
}
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([tableView isEqual: tblInviteesTable]){
UITableViewRowAction *button = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Resend" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(#"Resending email");
// [_delegate listingAgentsView: self selected: indexPath];
}];
button.backgroundColor = [UIColor redColor];
return #[button];
}
return #[];
}
Any help is greatly appreciated.
After scrolling i want my TableView to display like this :
not like this :
and i have set my rowHeight = tableViewHeight / 3:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return CGRectGetHeight(self.tableView.frame)/3;
}
There are a couple things you need for this. Firstly, you need to detect when the table view has stopped scrolling:
How to know exactly when a UIScrollView's scrolling has stopped?
Next, you need to set the scroll view position:
How can I set the scrolling position of an UIScrollView?
The position you're going to want to set it might be the tableview contentOffset - (contentOffset % rowHeight) to move it up to show the row partially shown at the top.
Follow this steps:
In .h , declare
NSMutableArray *arrayForBool;
NSMutableArray *arrPastOrder;
In .m ,
- (void)viewDidLoad {
arrPastOrder=[[NSMutableArray alloc] init];
int range=1+arc4random()%10;
for(int i=0;i<range;i++)
{
NSMutableArray *arrinside=[[NSMutableArray alloc] init];
for(int j=0;j<3;j++)
{
if(j==0)
[arrinside addObject:[NSString stringWithFormat:#"Some Header %i",i]];
else
[arrinside addObject:[NSString stringWithFormat:#"Subindex %i",j]];
}
[arrPastOrder addObject:arrinside];
}
arrayForBool=[[NSMutableArray alloc]init];
for (int i=0; i<[arrPastOrder count]; i++)
{
[arrayForBool addObject:[NSNumber numberWithBool:YES]];
}
}
#pragma mark -
#pragma mark TableView DataSource and Delegate Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([[arrayForBool objectAtIndex:section] boolValue])
{
return [[arrPastOrder objectAtIndex:section] count]-1;
}
else
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *cellid=#"hello";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellid];
if (cell==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellid];
}
BOOL manyCells = [[arrayForBool objectAtIndex:indexPath.section] boolValue];
/********** If the section supposed to be closed *******************/
if(!manyCells)
{
cell.backgroundColor=[UIColor clearColor];
NSLog(#"cellForRowAtIndexPath---if");
cell.textLabel.text=#"";
}
/********** If the section supposed to be Opened *******************/
else
{
//cell.textLabel.text=[NSString stringWithFormat:#"%# %ld",[sectionTitleArray objectAtIndex:indexPath.section],indexPath.row+1];
// ic_keyboard_arrow_up_48pt_2x ic_keyboard_arrow_down_48pt_2x.png
cell.textLabel.text=[NSString stringWithFormat:#"%#",[[arrPastOrder objectAtIndex:indexPath.section] objectAtIndex:indexPath.row+1]];
}
cell.textLabel.textColor=[UIColor blackColor];
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [arrPastOrder count];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%li--%li",(long)indexPath.section, (long)indexPath.row);
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[arrayForBool objectAtIndex:indexPath.section] boolValue]) {
return 40;
}
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 100;
}
#pragma mark - Creating View for TableView Section
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *sectionView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 540,100)];
sectionView.backgroundColor=[UIColor whiteColor];
sectionView.tag=section;
UILabel *viewLabel=[[UILabel alloc]initWithFrame:CGRectMake(10, 30, 530, 40)];
viewLabel.backgroundColor=[UIColor whiteColor];
viewLabel.textColor=[UIColor blackColor];
viewLabel.font=[UIFont boldSystemFontOfSize:20];
viewLabel.text=[NSString stringWithFormat:#"%#",[[arrPastOrder objectAtIndex:section] objectAtIndex:0]];
[sectionView addSubview:viewLabel];
/********** Add UITapGestureRecognizer to SectionView **************/
UITapGestureRecognizer *headerTapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(sectionHeaderTapped:)];
[sectionView addGestureRecognizer:headerTapped];
return sectionView;
}
#pragma mark - Table header gesture tapped
- (void)sectionHeaderTapped:(UITapGestureRecognizer *)gestureRecognizer{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:gestureRecognizer.view.tag];
//Get which section is open, from here Set the value of arrafool. and expand collapse. Normally whole table is expanded.
}
Just run it. You will get the same structure. happy Coding !!
Here are my 2 NSTableCellViews:
The 1st is bigger than the 2nd (this one is used when the user is searching the tableview and there are no results) but when i run my app the 2nd gets the size of the 1st:
Why is this happening? Here's my part of the code
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
if (noResults){
return 1;
}else{
return [array count];
}
}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
if (noResults){
NSTableCellView *result = [tableView makeViewWithIdentifier:#"NoResults" owner:self];
result.textField.stringValue = [NSString stringWithFormat:#"No results for \"%#\"", _searchTXT.stringValue];
return result;
}else{
SearchTableCell *result = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
result.textField.stringValue = #"Name";
result.textField2.stringValue = #"Last Name";
return result;
}
}
You need to implement the tableView:heightForRowAtIndexPath: method. Otherwise the cell will all be the height of the table views rowHeight property.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (noResults){
// return NSTableCellView height here;
}else{
// return SearchTableCell height here;
}
}
Hope this helps you.
For a view based NSOutlineView, implement the delegate method outlineView:heightOfRowByItem: to return the desired row height.
To avoid constants within your code, consider determining the height from the associated view:
- (CGFloat)outlineView:(NSOutlineView *)outlineView heightOfRowByItem:(id)item
{
NSView* view = [self outlineView:outlineView viewForTableColumn:nil item:item];
return (view ? NSHeight(view.frame) : outlineView.rowHeight);
}
I would like to implement some code, which changes footer text in one section of the tableView (in viewDidAppear or viewWillAppear method). But how can I do it?
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
doesn't fit my requirements (It changes only once, during load of the tableView, but I need to change the footer's text after text in tableView cell is changed.
-(CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 120;
}
-(NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == 0) {
return #"Things We'll Learn";
} else {
return #"Things Already Covered";
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[tableView reloadData];
}
Implement viewForFooterInSection and add your textField there. Also make that textField a property.
When you have finished editing you tableViewCells, implement the textFieldDidEndEditing method and assign necessary value to the textField of your footerView.
Once your textField is set, use [tableView reloadData] to implement the viewForFooterInSection again and it should work now.
Edit:
If you want to change the title of the Footer section after editing the UITableViewCell,
Set a global variable or use NSUserDefaults to indicate that tableViewCell has been edited.
self.tableView reloadData right after edit.
In the method titleForFooterInSection check for that variable (this would mean that tableView has been edited) and set the title accordingly.
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
if(section == 1)
{
// For Lable
UIView *view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 40)] autorelease];
tableView.sectionHeaderHeight = view.frame.size.height;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, view.frame.size.width - 20, 44)];
label.text = [self tableView:tableView titleForHeaderInSection:section];
label.font = [UIFont boldSystemFontOfSize:16.0];
label.shadowOffset = CGSizeMake(0, 1);
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
label.adjustsFontSizeToFitWidth = YES;
[label setLineBreakMode:NSLineBreakByTruncatingTail];
[label setNumberOfLines:0];
label.text = #“Your Text Here…..your Text Here”;
[view addSubview:label];
[label release];
return view;
}
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if(section == 1)
{
return 60.0;
}
return 0;
}
In my table view I had more than 200 rows and Im managing then by keeping loadmoreresults in last cell to display only 40 rows per page.when the user clicks on the load more results 40 more cells is displayed.I changed the row height of loadmoreresults cell as different from other. The problem is when there is no more results the height for other cell is effected with the height of the loadmoreresults cell I dont want to sffect the last row height to other rows.
The code I written as:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
ZohoAppDelegate* appDelegate = (ZohoAppDelegate*) [ [UIApplication sharedApplication] delegate];
int maxResults = [appDelegate.invoiceMaxValues intValue];
int noOfResults = [invoiceArray count] ;
if (noOfResults != 0 )
{
if (maxResults > noOfResults)
{
noOfResults++;
rowCount = noOfResults;
}
}
return noOfResults;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == (rowCount -1))
{
return 50;
}
return 80;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"MasterViewIdentifier"] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.accessoryType = UITableViewCellAccessoryNone;
UIView* elementView = [[UIView alloc] initWithFrame:CGRectMake(5,5,312,480)];
elementView.tag = 0;
[cell.contentView addSubview:elementView];
[elementView release];
}
UIView* elementView = [cell.contentView viewWithTag:0];
for(UIView* subView in elementView.subviews)
{
[subView removeFromSuperview];
}
UIImageView* imaeView=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 78)];
if(indexPath.row == (rowCount-1))
{
elementView.backgroundColor = [UIColor colorWithRed:0.92578125 green:0.92578125 blue:0.92578125 alpha:1];
}
else
{
imaeView.image=[UIImage imageNamed:#"estimatecellbg.png" ];
}
[elementView addSubview:imaeView];
[imaeView release];
return cell;
}
Anyone's help will be much appreciated.
Thank you,
Monish.
Something along the lines of
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == (rowCount -1) && moreResults)
{
return 50;
}
return 80;
}