[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:indexPathsToBeInserted withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
if (section == someSection) {
UIView *footerView = [[UIView alloc] init];
footerView.backgroundColor = [UIColor someColor];
return footerView;
}
else {
return nil;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
if (section == someSection) {
return 10;
}
else {
return 0;
}
}
Nothing really special.
Just provide a footer view and trigger the insert rows method somehow, the footer view will be animated like dropping down every time, you can watch this easier by turning slow animations on in the simulator.
I don't know how to make the animation gone, it's really unwanted.
I've found a similar issue here - UITableView section footer view position after endUpdates
The solution is to change table view style to Grouped.
Related
I am working on a feature in an app where the user can tap on some attribute about a car (such as its color) and a list of different colors will be shown.
This is just part of the page. The whole page consists of different views and view controllers all wrapped together in a vertical stack view, but I do not think that is what is causing the animation issues here. This is the overall structure of the page:
UIScrollView
UIStackView
UIViewController
UIView
UITableViewController <-- this is the class being shown in this question
...
But for this question, I am just showing the section of the page where this table is.
So I am having an issue with the animation of the table as can be seen in the gifs later on. The way this section is structured is that it is a UITableViewController subclass that takes in a model (a title and a list of car colors) and it displays a different table section for each model element.
Each section has a section header, which is the part where the user taps. It shows the color and it shows a preview image. When that is tapped, a table row is added to the table for that section and that change is animated. The table view row that is added to the table contains a UICollectionView that lays out content horizontally. This idea came from the WWDC 2010 - Mastering Table Views video.
It is basically something like this. Each section header is the interactive part where you can tap on it. Then the row that is shown in the section has a collection view.
* SectionHeader
* SectionHeader
* Table row containing a UICollectionView
* SectionHeader
The problem I am having is that the animation is behaving in a strange manner, as can be seen in the following images.
The first image shows what happens if a row is expanded that has other rows below it. In this case, it appears as if the other two rows in the table are essentially floating above the content of the new row that is animating in. Additionally, at the bottom of the section, those two rows come in from the bottom as the previous two rows sort of get vertically squished until they are gone.
The second animation here shows the bottom row expanding. This one is closer to what I want, except that the row content still briefly shows at the top of the row above the divider (which is the section footer of the previous section).
Here is my code for the table view controller class.
MyAttributeTableViewController.h
#import <UIKit/UIKit.h>
#import "MyAttribute.h"
#import "MyAttributeTableViewCell.h"
NS_ASSUME_NONNULL_BEGIN
#interface MyAttributeTableViewController : UITableViewController<MyAttributeDelegate>
//this represents each section of the table. It contains a title (color, for example), a selected value (red),
//and a list of possible values that will be used to display the collection view when the section is expanded.
#property (strong, nonatomic) NSArray<MyAttribute *> *modelAttributes;
#end
NS_ASSUME_NONNULL_END
MyAttributeTableViewController.m
#import "MyAttributeTableViewController.h"
#import "MyAttributeTableHeaderView.h"
#import "MyAttributeTableViewCell.h"
#interface MyAttributeTableViewController ()
//this keeps track of which sections are expanded. Initially, all sections start out
//not expanded. Then, upon tap, a section's expanded status is toggled here. This is
//used by the table view's data source to know when to display a row in a section.
#property (strong, nonatomic) NSMutableArray<NSNumber *> *itemsExpanded;
#end
#implementation MyAttributeTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = UITableViewAutomaticDimension;
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionFooterHeight = CGFLOAT_MIN;
//this xib file only contains the UICollectionView that is shown upon expanding the section.
//There is nothing that interesting in this file, but I have some screenshots of the
//attribute inspector for this xib file after this code.
[self.tableView registerNib:[UINib nibWithNibName:#"MyAttributeTableViewCell" bundle:nil] forCellReuseIdentifier:#"MyAttributeTableViewCell"];
[self.tableView registerClass:[MyAttributeTableHeaderView class] forHeaderFooterViewReuseIdentifier:#"AttributeHeaderView"];
[self.tableView invalidateIntrinsicContentSize];
}
- (void)setAttributeOptions:(NSArray<MyAttribute *> *)modelAttributes {
self->_modelAttributes = modelAttributes;
self->_itemsExpanded = [NSMutableArray arrayWithCapacity:[self->_modelAttributes count]];
for (NSUInteger x=0; x<[self->_modelAttributes count]; x++) {
[self->_itemsExpanded addObject:#NO];
}
[self.tableView reloadData];
}
//TODO: is this necessary?
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.preferredContentSize = self.tableView.contentSize;
}
#pragma mark - MyAttributeDelegate
- (void)twister:(MyAttributeTableViewCell *)cell didSelectItemAtIndex:(NSInteger)index {
UITableViewHeaderFooterView *headerView = [self.tableView headerViewForSection:cell.sectionIndex];
if ([headerView isKindOfClass:[MyAttributeTableHeaderView class]]) {
MyAttributeTableHeaderView *twisterHeaderView = (MyAttributeTableHeaderView *)headerView;
twisterHeaderView.twister.selectedSwatchIndex = [NSNumber numberWithInteger:index];
[twisterHeaderView updateAttributeIfNeeded];
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.modelAttributes.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.itemsExpanded[section].boolValue ? 1 : 0;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
MyAttributeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyAttributeTableViewCell" forIndexPath:indexPath];
MyAttribute *twister = self.modelAttributes[indexPath.section];
cell.swatches = twister.swatches;
NSNumber *swatchCellHeight = cell.swatchCellHeight;
if (swatchCellHeight) {
return swatchCellHeight.floatValue + 20.0f; //TODO: need to get this from the collection view
}
return 352.0f;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
if (section == self.modelAttributes.count) {
return CGFLOAT_MIN;
}
return 1.0f;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyAttributeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyAttributeTableViewCell" forIndexPath:indexPath];
MyAttribute *twister = self.modelAttributes[indexPath.section];
cell.swatches = twister.swatches;
cell.sectionIndex = indexPath.section;
cell.delegate = self;
if ([twister isSwatchSelected]) {
NSInteger selectedIndex = twister.selectedSwatchIndex.integerValue;
[cell.collectionView selectItemAtIndexPath:[NSIndexPath indexPathForItem:selectedIndex inSection:0] animated:YES scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];
}
return cell;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
MyAttributeTableHeaderView *cell = (MyAttributeTableHeaderView *)[tableView dequeueReusableHeaderFooterViewWithIdentifier:#"AttributeHeaderView"];
if (cell.gestureRecognizers.count == 0) {
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(toggleSection:)];
[cell addGestureRecognizer:tapRecognizer];
}
cell.sectionIndex = section;
cell.expanded = self.itemsExpanded[section].boolValue;
cell.twister = self.modelAttributes[section];
return cell;
}
- (void)toggleSection:(UITapGestureRecognizer *)gesture {
MyAttributeTableHeaderView *destinationView = ((MyAttributeTableHeaderView *)gesture.view);
BOOL expanded = [destinationView toggleExpanded];
self.itemsExpanded[destinationView.sectionIndex] = [NSNumber numberWithBool:expanded];
UIView *viewToLayout = self.tableView;
while ([viewToLayout superview]) {
viewToLayout = viewToLayout.superview;
}
if (expanded) {
[UIView beginAnimations:#"expandTableAnimationId" context:nil];
[UIView setAnimationDuration:1.0f];
[CATransaction begin];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:0 inSection:destinationView.sectionIndex]] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
[viewToLayout layoutIfNeeded];
[CATransaction commit];
[UIView commitAnimations];
} else {
[UIView beginAnimations:#"collapseTableAnimationId" context:nil];
[UIView setAnimationDuration:1.0f];
[CATransaction begin];
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:0 inSection:destinationView.sectionIndex]] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
[viewToLayout layoutIfNeeded];
[CATransaction commit];
[UIView commitAnimations];
}
}
#end
MyAttributeTableViewCell
Does anyone know what I am doing wrong or how to get these animations to look correct (no doubling of rows and no collection view showing up above the row when it is animating in)? Or if you know a better way to handle this that might be less complicated, I am open to that as well. I am just trying to have a list of expandable sections, where each section has a collection view of selectable items.
my platform is ios8 and xcode 6.3.1
tableview's delegate like this:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
so, the delegate of heightForRowAtIndexPath: should be execute three times , but my code execute four, why ?
My code :
init tableView
- (void)setupTableView {
_selectTableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
_selectTableView.delegate = self;
_selectTableView.dataSource = self;
_selectTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:_selectTableView];
}
other delegate method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger section = indexPath.section;
static NSString *identified = #"selectCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identified];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identified];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
return [self cellWith:cell andSection:section];
}
- (UITableViewCell *)cellWith:(UITableViewCell *)cell andSection:(NSInteger)section {
....
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
CGFloat height = 0;
if (section != SVCellTypeHot) {
height = 5;
}
return height;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenSize.width, 5)];
[footerView setBackgroundColor:[UIColor lightGrayColor]];
return footerView;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat height = 0;
switch (indexPath.section) {
case SVCellTypeBanner:
{
height = kHeaderViewHeigth;
}
break;
case SVCellTypeRecommand:
{
height = kRecommandViewHeight;
}
break;
case SVCellTypeHot:
{
height = kHotViewHeight;
}
break;
default:
break;
}
return height;
}
heightForRowAtIndexPath allows the delegate to specify rows with varying heights. If this method is implemented, the value it returns overrides the value specified for the rowHeight property of UITableView for the given row. There is no guarentee that this method can only be called 'section count * item count' times in the UITableView. As you can tell from its name, it will calculate the height for the cells at IndexPath, so combining the re-using technique, this method will be called many times, as long as it needs to calculate the height for cell at IndexPath
So actually, it is a system behaviour to decide how many times it should be called and when. In your comment, it seems like something changed in indexPath {1-0} so heightForRowAtIndexPath is called twice for {1-0}. You might need to check have you changed any content that cause iOS to re-calculate the cell's height.
Without knowing more details, this is the best we can do to provide you some clues to debug. However, you should not rely on how many times it calls heightForRowAtIndexPath, again, this can be called at any time, as long as you scroll or change any frame inside that cell
heightForRowAtIndexPath: will execute as many times as it needs to. If you are scrolling, for example, it will execute as offscreen cells are about to come onscreen. That method should always be able to provide the correct height and you normally shouldn't be concerned with how often it's called. cellForRowAtIndexPath: executes 3 times as it should.
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.
I have a table view of custom cells and some buttons in each cell.Clicking on any of the button inside the cell will reveal another custom view below that cell.Next click on the same button will collapse the view and need this same for all cells.I tried with insertrow method on the button click but in vain.How can i do this with using only the table view delegates.
This is what i tried:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"CustomCell_For_Dashboard";
CustomCellFor_Dashboard *customCell = (CustomCellFor_Dashboard *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (customCell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCellFor_Dashboard" owner:self options:nil];
customCell = [nib objectAtIndex:0];
}
[customCell.howyoulfeelBtn addTarget:self action:#selector(buttonclicked:) forControlEvents:UIControlEventTouchUpInside];
customCell.nameLabel.text = #"test";
customCell.imgView.image = [UIImage imageNamed:#"Default.png"];
// customCell.prepTimeLabel.text = [prepTime objectAtIndex:indexPath.row];
return customCell;
}
-(void)buttonclicked:(id)sender{
NSIndexPath *indexPath = [myTable indexPathForCell:sender];
[myTable beginUpdates];
NSIndexPath *insertPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
[myTable insertRowsAtIndexPaths:[NSArray arrayWithObject:insertPath] withRowAnimation:UITableViewRowAnimationTop];
}
can anyone help me?
I got the same task on one project with just one thing different: There were no buttons, just tapping on cell will expand or collapse it.
There are several things you should edit in your code. First, the button method code will look something like this:
- (void) collapseExpandButtonTap:(id) sender
{
UIButton* aButton = (UIButton*)sender; //It's actually a button
NSIndexPath* aPath = [self getIndexPathForCellWithButtonByMagic:aButton];
//expandedCells is a mutable set declared in your interface section or private class extensiont
if ([expandedCells containsObject:aPath])
{
[expandedCells removeObject:aPath];
}
else
{
[expandedCells addObject:aPath];
}
[myTableView beginEditing];
[myTableView endEditing]; //Yeah, that old trick to animate cell expand/collapse
}
Now the second thing is UITableViewDelegate method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([expandedCells containsObject:indexPath])
{
return kExpandedCellHeight; //It's not necessary a constant, though
}
else
{
return kNormalCellHeigh; //Again not necessary a constant
}
}
Key thing here is to determine if your cell should be expanded/collapsed and return right height in delegate method.
Going off of what #eagle.dan.1349 said, this is how to do it on the clicking of the cell. In storyboard, you also need to set the table cell to clip subviews, otherwise the content that would be hidden will show.
.h
#property (strong, nonatomic) NSMutableArray *expandedCells;
.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([self.expandedCells containsObject:indexPath])
{
[self.expandedCells removeObject:indexPath];
}
else
{
[self.expandedCells addObject:indexPath];
}
[tableView beginUpdates];
[tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat kExpandedCellHeight = 150;
CGFloat kNormalCellHeigh = 50;
if ([self.expandedCells containsObject:indexPath])
{
return kExpandedCellHeight; //It's not necessary a constant, though
}
else
{
return kNormalCellHeigh; //Again not necessary a constant
}
}
Saw this post and just wanted to give my 2 cents as my solution to this is very similar to the chosen answer (the tapping of a whole area).
Many people architect this by using just cells alone, but I believe there is a way to build this that might align better with what people are trying to achieve:
There are headers and there are cells. Headers should be tappable, and then cells underneath the headers would show or hide. This can be achieved by adding a gesture recognizer to the header, and when tapped, you just remove all of the cells underneath that header (the section), and viceversa (add cells). Of course, you have to maintain state of which headers are "open" and which headers are "closed."
This is nice for a couple of reasons:
The job of headers and cells are separated which makes code cleaner.
This method flows nicely with how table views are built (headers and cells) and, therefore, there isn't much magic - the code is simply removing or adding cells, and should be compatible with later versions of iOS.
I made a very simple library to achieve this. As long as your table view is set up with UITableView section headers and cells, all you have to do is subclass the tableview and the header.
Link: https://github.com/fuzz-productions/FZAccordionTableView
I also had a same situation and my solution was to put a button on top of the Section Title with viewForHeaderInSection method.
noOfRows defines how many rows are there in each section and button.tag keeps which button of section is pressed.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIButton *btnSection = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, tableView.frame.size.height)];
btnSection.tag = section;
[btnSection setTitle:[sectionArray objectAtIndex:section] forState:UIControlStateNormal];
[btnSection addTarget:self action:#selector(sectionButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
return btnSection;
}
- (void)sectionButtonTapped:(UIButton *)button {
sectionIndex = button.tag;
if (button.tag == 0) {
noOfRows = 3;
} else if (button.tag == 1) {
noOfRows = 1;
} else if (button.tag == 2) {
noOfRows = 2;
}
[self.tableView reloadData];
}
Hope this will help you..
I want to accomplish something like this :
see there's only one data but, background color continue until end.
I understand I can do inside tableview delegate of tableView:willDisplayCell:forRowAtIndexPath:. but then it doesn't go to empty cell, hence my empty cell always be white.
I used the following code to display cell alternative color even if cell is not initialized.I have done this work on scrollViewDidScroll as showing below:--
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
UIView *view=[[UIView alloc] initWithFrame:tblView.frame];
view.backgroundColor=[UIColor greenColor];
UIView *cellView;
int y=0;
int i=0;
for (UIView *view in tblView.subviews) {
if ([NSStringFromClass([view class]) isEqualToString:#"_UITableViewSeparatorView"]) {
cellView=[[UIView alloc] initWithFrame:CGRectMake(0, y, 320, 44)];
if (i%2==0) {
cellView.backgroundColor=[UIColor redColor];
}else{
cellView.backgroundColor=[UIColor greenColor];
}
[view addSubview:cellView];
i++;
}
}
tblView.backgroundView=view;
}
And got the correct result on scrolling table view. But the problem is it works when user scrolls the tableView atleast once a time.
If you will get success to fire event on tableView completes its reloading.Then it will be fine.
Here is output I got on scrolling tableView.
I also write this method to call didScrollMethod manually but doesn't seems to work perfectly.
[tblView.delegate scrollViewDidScroll:(UIScrollView*)tblView.superclass];
But calling method like code below absolutely works fine.
- (void)viewDidLoad
{
tblView=[[MyFirstView alloc] init];
tblView.delegate=self;
[tblView setFrame:self.view.frame];
[self.view addSubview:tblView];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)viewDidAppear:(BOOL)animated{
[tblView.delegate scrollViewDidScroll:(UIScrollView*)tblView.superclass];
}
Means after loading tableView in viewDidLoad call didScroll in viewDidAppear works fine.
Insert below code if fluctuates first row while scrolling.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view=[[UIView alloc] init];
return view;
}
You have to set the backgroundColor to the contentView of a UITableViewCell.
Sample as below:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"identifier"];
if (cell==nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"identifier"]autorelease];
cell.contentView.backgroundColor= [UIColor greenColor];
}
return cell;
}
To have alternate colors in your cells of tableView, you can do the following;
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"identifier"];
if (cell==nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"identifier"]autorelease];
}
if(indexPath.row % 2)
{
cell.contentView.backgroundColor= [UIColor greenColor];
}
else
{
cell.contentView.backgroundColor= [UIColor yellowColor];
}
return cell;
}
A table with plain style doesn't show rows below the last row so there is no way to produce the desired effect using table view cells. About your only option would be to create a view with the alternating pattern and make the view the table view's footer view.
This view would need to deal with being updated as the number of actual rows in the table changes to/from odd and even. And you need to make it tall enough so if the user scrolls the table up a bunch, the footer still reaches the bottom of the screen.
You can setup some placeholder cells in addition to your cell with 'Monthly meeting', something like:
return amount of rows as 1 + (rows to fill screen) in the tableView:numberOfRowsInSection:
In the tableView:cellForRowAtIndexPath: - check for index path of the cell, if its row = 0, then this is your action cell, otherwise, update cells background, do the same in the tableView:willDisplayCell:forRowAtIndexPath:. Make sure to remove selectionStyle for your placeholder cells.
Or, you can use 2 cells - first one - again, your 'Monthly meeting' cell, and second one - a cell with height enough to cover screen from first cell to the bottom with image of striped cells.
This is simple to do. Just have as many items in your data source array as you want to see rows, and have all but the first one be empty strings. In willDisplayCell:forRowAtIndexPath: apply a background color to all the odd numbered cells.
- (void)viewDidLoad {
[super viewDidLoad];
self.theData = #[#"Monthly Meeting",#"",#"",#"",#"",#"",#"",#"",#"",#""];
[self.tableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.theData.count;
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row % 2 == 1) {
cell.backgroundColor = [UIColor colorWithRed:232/255.0 green:238/255.0 blue:222/255.0 alpha:1];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = self.theData[indexPath.row];
return cell;
}
Set backgroundColor to the contentView of a UITableViewCell with the help of simple mathematics, Example:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"identifier"];
if (cell==nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"identifier"]autorelease];
if (i%2==0) {
cell.contentView.backgroundColor= [UIColor greenColor];
}else{
cell.contentView.backgroundColor= [UIColor redColor];
}
}
return cell;
}