iOS: label stops updating when user scrolls through table view - uitableview

On a view I got a label and a table view. The label gets updated every second through a timer which calls the function that updates the label's text. Now this works all fine. But as soon as a user swipes with his finger on the table view, the label's text stops updating.
Is there a way to prevent this behavior?

Your Label stops updating when you scroll tableview because both timer and tableView are on the same thread i.e main thread. You can try the below code
These two Methods are used to update the UILabel irrespective of tableView Scrolling
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
arrData = [NSMutableArray new];
for (int i = 0; i < 150; i ++) {
[arrData addObject:[NSString stringWithFormat:#"Row number %d",i]];
}
[self performCounterTask];
count = 10;
}
-(void)performCounterTask{
if (count == 0) {
count = 10;
}
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// Your code here
if (count >= 0) {
[lblTimer setText:[NSString stringWithFormat:#"%ld",(long)count]];
count--;
[self performCounterTask];
}
});
}
These are the TableView datasource methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return arrData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [arrData objectAtIndex:indexPath.row];
return cell;
}
So, basically you need to keep the Lable updation portion under dispatch queue.
Hope this solution will help you. Happy Coding :)

Related

iOS - UITableView Does Not Scroll To Last Row In Data Source

I'm working on a messaging component of an iOS application. Each message is a row on my UITableView _messageTable I tried the following code in viewDidLoad, viewWillAppear and in viewDidAppear (messages are coming in from a background thread):
dispatch_async(dispatch_get_main_queue(), ^{
[_messageTable reloadData];
});
dispatch_async(dispatch_get_main_queue(), ^{
[self scrollToBottomOfTable];
});
-(void)scrollToBottomOfTable {
NSInteger rowCount = [_messageTable numberOfRowsInSection:0];
if (rowCount > 0) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: rowCount-1 inSection: 0];
[_messageTable scrollToRowAtIndexPath: indexPath atScrollPosition: UITableViewScrollPositionBottom animated: YES];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _privateMessages.count;
}
This code works until there are about 20 or so rows. But when there are more messages, then it doesn't quite scroll all the way to the bottom. Is there some sort of limit? I'm ok with a view load delay if it means scrolling all the way to the bottom. Eventually I will implement some sort of message loading cap, but I would like to first understand and solve this issue.
EDIT
This is a table view within a view controller. I'm saving sent and received Message objects in a User object's array property (the person on the other end of the message conversation. app.hero is the user that is logged in, inheriting form the User object). The thing that doesn't make sense is that the code works perfectly for up to around 20 messages. Beyond that, it doesn't scroll all the way, but I can still manually scroll to the bottom as expected. The rest of the cell config code is :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
tableView.estimatedRowHeight = 20.0;
tableView.rowHeight = UITableViewAutomaticDimension;
Message *message = [_privateMessages objectAtIndex:indexPath.row];
static NSString *cellId = #"messageCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
cell.textLabel.numberOfLines=0;
}
return [self configureTableCell:cell forMessage:message];
}
- (UITableViewCell *)configureTableCell:(UITableViewCell *)cell forMessage:(Message *)message {
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (message.sender == app.hero) {
cell.backgroundColor = [UIColor whiteColor];
cell.textLabel.textAlignment = NSTextAlignmentRight;
} else {
cell.backgroundColor = [UIColor colorWithRed:0 green:1 blue:0.2 alpha:0.3];
cell.textLabel.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
cell.textLabel.textAlignment = NSTextAlignmentLeft;
}
cell.textLabel.text = message.content;
return cell;
}
I've determined that this issue has to do with cell height. By increasing tableView.estimatedRowHeight to 44.0, the table view scrolls flawlessly to the bottom. However, there remains an issue with when messages wrap beyond 1 line in a given cell. For each message longer than 1 line, the table scroll comes up a few more pixels short. Removing tableView.estimatedRowHeight altogether seems to result in similar behavior as setting it to say, 44.0. I want to say my original question is answered, but I'm still not sure how to make it scroll perfectly given the likelihood of multi-line cells.
EDIT - SOLUTION
The problem of incorrect scrolling is in fact solved by removing UITableViewAutomaticDimension and manually calculating the height in heightForRowAtIndexPath.
Here is a solution that works well with auto cell height sizing. It's quite a workaround, but this appears to be an Apple bug.
Set _manualScrolling=NO in viewDidLoad.
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
if (!decelerate) {
_manualScrolling = NO;
} else {
_manualScrolling = YES;
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
_manualScrolling = YES;
}
-(void)reloadTable {
dispatch_async(dispatch_get_main_queue(), ^{
[_messageTable reloadData];
});
dispatch_async(dispatch_get_main_queue(), ^{
[self scrollToBottomOfTable];
});
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (!_manualScrolling && ![self scrolledToBottom]) {
[self scrollToBottomOfTable];
}
}
-(BOOL)scrolledToBottom {
NSInteger rowCount = [_messageTable numberOfRowsInSection:0];
NSArray *visibleIndices = [_messageTable indexPathsForVisibleRows];
NSIndexPath *lastVisibleIndex = [visibleIndices lastObject];
NSIndexPath *lastIndex = [NSIndexPath indexPathForRow: rowCount-1 inSection: 0];
return lastVisibleIndex.row == lastIndex.row;
}
-(void)scrollToBottomOfTable {
NSInteger rowCount = [_messageTable numberOfRowsInSection:0];
if (!rowCount > 0) return;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: rowCount-1 inSection: 0];
[_messageTable scrollToRowAtIndexPath: indexPath atScrollPosition: UITableViewScrollPositionBottom animated: YES];
}

ios8 UITableView scrolling jumps back when scrolling up

I have an odd situation with my UItableView.
I am loading images from the internet and presenting them in a uitableviewcell in an asynchronous manner. When I scroll down (i.e. row 1 to 6) the scroll scrolls down smoothly just as I expect it to.
However, then I scroll up (i.g. row 6 to 1) the scroll jumps back. for example if I scroll from row 6 to row 5, it will jump back to row 6. The second time I try to scroll up it lets me go up to row 4, but then it scrolls me back to row 5 or 6 but usually just 5.
What I don't understand is why this is happening in only one direction.
It seems to be effecting ios 8 but not ios 7.
Therefore it is an implementation difference in how ios8 and 7 handle the uitableview.
How can I fix this?
Here is some code to give you some context
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CVFullImageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
CVComicRecord *comicRecord = self.comicRecords[indexPath.row];
[cell.loaderGear stopAnimating];
[cell.text setText:comicRecord.title];
NSString *UUID = comicRecord.fullImagePageURL.absoluteString;
[cell setUUID:UUID];
//Check if image is in the cache
UIImage *fullImage = [self.contentViewCache objectForKey:UUID];
[cell setComicFullImage:fullImage];
if (fullImage) {
return cell;
}
[cell.loaderGear startAnimating];
[self requestImageForIndexPath:indexPath];
return cell;
}
- (void)requestImageForIndexPath:(NSIndexPath *)indexPath {
CVComicRecord *comicRecord = self.comicRecords[indexPath.row];
NSString *UUID = comicRecord.fullImagePageURL.absoluteString;
if ([self.contentViewCache objectForKey:UUID]) {
//if it is already cached, I do not need to make a request.
return;
}
id fd = CVPendingOperations.sharedInstance.fullDownloadersInProgress[UUID];
if (fd) {
//if it is in the queue you do no need to make a request
return;
}
comicRecord.failedFull = NO;
CVFullImageDownloader *downloader = [[CVFullImageDownloader alloc] initWithComicRecord:comicRecord withUUID:UUID];
[CVPendingOperations.sharedInstance.fullDownloaderOperationQueue addOperation:downloader];
//when operation completes it will post a notification that will trigger an observer to call fullImageDidFinishDownloading
}
- (void)fullImageDidFinishDownloading:(NSNotification *)notification {
CVComicRecord *comicRecord = notification.userInfo[#"comicRecord"];
NSString *UUID = notification.userInfo[#"UUID"];
UIImage *fullImage = notification.userInfo[#"fullImage"];
comicRecord.failedFull = NO;
[self.contentViewCache setObject:fullImage forKey:UUID];
dispatch_async(dispatch_get_main_queue(), ^{
for (NSIndexPath *indexPath in [self.tableView indexPathsForVisibleRows]) {
CVFullImageTableViewCell *cell = (id)[self.tableView cellForRowAtIndexPath:indexPath];
if (cell) {
if ([cell.UUID isEqualToString:UUID]) {
[cell.loaderGear stopAnimating];
[cell setComicFullImage:fullImage];
[cell layoutIfNeeded];
}
}
}
});
}
#pragma mark - Scroll
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
static int oldOffset = 0;
int newOffset = scrollView.contentOffset.y;
int dy = newOffset- oldOffset;
if (dy > 0) {
[self hideNavigationbar:YES animationDuration:0.5];
} else if (dy < 0) {
[self hideNavigationbar:NO animationDuration:0.5];
}
oldOffset = newOffset;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if (decelerate == NO) {
[self prioritizeVisisbleCells];
//currentPage is a property that stores that last row that the user has seen
[self setCurrentPage:[self currentlyViewedComicIndexPath].row];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[self prioritizeVisisbleCells];
//currentPage is a property that stores that last row that the user has seen
[self setCurrentPage:[self currentlyViewedComicIndexPath].row];
}
- (void)prioritizeVisisbleCells {
NSArray *ips = [self.tableView indexPathsForVisibleRows];
NSArray *activeIndexPaths = [CVPendingOperations.sharedInstance.fullDownloadersInProgress allKeys];
//add visible cells to queue first
NSSet *visible = [NSSet setWithArray:ips];
NSMutableSet *invisible = [NSMutableSet setWithArray:activeIndexPaths];
[invisible minusSet:visible];
for (NSIndexPath *ip in invisible) {
NSOperation *op = CVPendingOperations.sharedInstance.fullDownloadersInProgress[ip];
[op setQueuePriority:NSOperationQueuePriorityNormal];
}
for (NSIndexPath *ip in visible) {
NSOperation *op = CVPendingOperations.sharedInstance.fullDownloadersInProgress[ip];
[op setQueuePriority:NSOperationQueuePriorityHigh];
}
}
I found the answer in this post very helpful: Table View Cells jump when selected on iOS 8
Try to implement the tableView:estimatedHeightForRowAtIndexPath: in the UITableViewDelegate protocol. It works for me.
Implement the self-sizing and correct view constraints in your storyboard.
in your code put this together
tableView.rowHeight = UITableViewAutomaticDimension;
tableView.estimatedRowHeight = CGFloat value (the initial value)
This exact problem was happening to me while I was using the UITableViewAutomaticDimension and the estimatedRowHeight, as #nferocious76 suggested.
The issue was that my estimatedRowHeight was 400.0 while the actual row height was more like 80.0 (I copy/pasted it from another table view in my app with large cells). I never bothered to change it because I had read somewhere that the estimatedRowHeight didn't really matter as long as it was greater than the actual row height, but apparently this is not the case.
You should calculate your row height yourself and you should remove everything about estimated row height in your code.

Make Change in TableViewCell

I'm working on the TableView, and I have used the label on the TableViewCell and on the button click I want to hide the label from all cells in my table,
In the label I have set the tag:
label.tag = indexPath.row+1;
And on the button click I am using the code like this:
for (int i = 0; i < Array.count; i++)
{
[[self.view viewWithTag:i+1] setHidden:YES];
}
But from my code the label is hiding only from the last cell not all the others.
You can simply do this with another way.
First you need to declare a BOOL in your class
#property(assign,nonatomic) BOOL hideLabels;
Next in your button action handler method, set this YES
In your cellForRowAtIndexPath, check whether hideLabels is YES, if yes, the hide labels using code.
cell.yourLabel.hidden = hideLabels;
Now reload the table after setting hideLabels as YES
[self.tableView reloadData];
for(id object in tableView.subviews)
{
if([object isKindOfClass:[UILabel class]])
{
UILabel *label = (UILabel *) object;
[[label setHidden:YES];
}
}
In your ViewController.h
BOOL isLabelHidden;
in ViewController.m
- (void)viewDidLoad
{
isLabelHidden = FALSE;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"TableCell";
UILabel *lbl;
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = nil;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if(isLabelHidden)
[lbl setHidden:YES];
else
[lbl setHidden:NO];
}
in you button clicked method
- (void)buttonClicked
{
isLabelHidden = TRUE;
[tableView reloadData];
}
You should first get the reference to the UITableViewCell and then you can remove the labels in them.
First of all get the reference to all the cells in your tableview as follows:
NSMutableArray *cells = [[NSMutableArray alloc] init];
for (NSInteger j = 0; j < [tableView numberOfSections]; ++j)
{
for (NSInteger i = 0; i < [tableView numberOfRowsInSection:j]; ++i)
{
[cells addObject:[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]]];
}
}
And now iterate through those cells in cells Array to hide the label view,
for (int i = 0; i < cells.count; i++)
{
[[[cells objectAtIndex:i] viewWithTag:i+1] setHidden:YES];
}
Source:How can I loop through UITableView's cells?

UILabel upon a few UITableViewCells

Am I able to create a UILabel that is layouted upon many UITableViewCells?
I'm trying to make something like (that is just one section of my UITableView, each section can have one or more rows):
---------------------------------------------
| Multi-lined label | row1 values |
| with some useless | row2 values |
| text | row3 values |
---------------------------------------------
I managed to create a UILabel (in the first row of a section) that is multi-lined and is not clipping to bounds. That works really well (it was a bit tricky to count each sections row heights, but doable) besides one case: when I'm scrolling UITableView from bottom to top - UITableView renders last row (without UILabel) so it has "no evidence" of having UILabel (because it is maintained in the first row of section). Can I force some kind of relayouting first cell in section? I tried reloadRowsAtIndexPaths:withRowAnimation: with first row in each section whenever I layouted not first cell in section but it gave me layouting errors that I really do not understand. Or maybe there is another idea to do so?
-- EDITED
To be clear: I have a custom UITableViewCell with an IB view, it has a few labels that each row consist of and a label named labelName that I want to be "multi-lined" along rows in that section. LabelName.text is empty for each row besides first one in each section.
I am adding somescreenshots:
Good screenshot - when I am scrolling to bottom I'm getting proper effect:
Bad screenshot - when I am scrolling up, UITableView renders last row of section firstly, and afterwards renders upper rows - that gives effect of cut label (because multi-line label is in the first row)
I am not sure if code here will add anything to question - it is rather simple and almost whole logic is in tableView:heightForRowAtIndexPath. I can only present how do I create custom UITableViewCell:
CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[CustomTableViewCell reuseIdentifier]];
if (cell == nil) {
cell = [[CustomTableViewCell alloc] initWithOwner:self];
cell.clipsToBounds = NO;
cell.labelName.clipsToBounds = NO;
cell.contentView.superview.clipsToBounds = NO;
}
-- EDIT 2
Here is most of the code:
- (void) reloadData
{
NSUInteger index = 0;
for (NSDictionary *object in self.list) {
CGFloat height = [[object objectForKey:#"name"] sizeWithFont:self.labelFont constrainedToSize:self.labelSize].height;
[self.labelHeights addObject:NSNumberFloat(ceilf(height))];
index++;
}
[self.tableView reloadData];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *object = [self.list objectAtIndex:indexPath.section];
CGFloat height = [[self.labelHeights objectAtIndex:indexPath.section] floatValue];
NSUInteger count = [[object objectForKey:#"list"] count];
CGFloat cellHeight = 30.f;
if((indexPath.row + 1) == count){
cellHeight = MAX(8.f + height - 30.f * indexPath.row, 30.f);
}
return cellHeight;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.list count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[[self.list objectAtIndex:section] objectForKey:#"list"] count];
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *person = [self.list objectAtIndex:indexPath.section];
NSDictionary *object = [[person objectForKey:#"list"] objectAtIndex:indexPath.row];
CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[CustomTableViewCell reuseIdentifier]];
if (cell == nil) {
cell = [[CustomTableViewCell alloc] initWithOwner:self];
cell.backgroundColor = [UIColor clearColor];
cell.userInteractionEnabled = NO;
cell.clipsToBounds = NO;
cell.labelName.clipsToBounds = NO;
[cell.contentView.superview setClipsToBounds:NO];
}
if(indexPath.row == 0){
cell.labelName.text = [person objectForKey:#"name"];
CGFloat height = [[self.labelHeights objectAtIndex:indexPath.section] floatValue];
cell.labelName.numberOfLines = (int)(height / self.fontSizeHeight);
cell.labelName.frame = CGRectChangeHeight(cell.labelName.frame, height);
}
else{
cell.labelName.text = #"";
}
CGFloat cellHeight = [self tableView:self.tableView heightForRowAtIndexPath:indexPath];
cell.borderTop.hidden = YES;
cell.borderBottom.hidden = YES;
cell.borderBottomSmall.hidden = NO;
if(indexPath.row == 0){
cell.borderTop.hidden = NO;
}
if(indexPath.row + 1 == [[person objectForKey:#"list"] count]){
cell.borderBottom.hidden = NO;
cell.borderBottom.frame = CGRectChangeY(cell.borderBottom.frame, cellHeight - 1.f);
cell.borderBottomSmall.hidden = YES;
}
cell.labelDate.text = [object objectForKey:#"date"];
cell.labelPremium.text = [[object objectForKey:#"premium"];
return cell;
}
-- PARTIAL ANSWER
I managed to create a hack, that makes multi-line UILabel visibile when scrolling bottom to up at some point:
- (void) scrollViewDidScroll:(UIScrollView *)scrollView
{
NSArray *cells = [self.tableView visibleCells];
UITableViewCell *cell = [cells objectAtIndex:0];
[cell.superview bringSubviewToFront:cell];
}
I noticed that the part of the UILabel is covered by a row thats below of the UILabels row and that hack makes it would be properly displayed. But it has a drawback, when scrolling slowly from bottom to top it generates a flicker when label is created (part of it should be visible before real creation of UILabel).
Up mentioned answers are not solutions, but "hacks".
In the cell == nil block should be only the initialization.
You should not add any subviews in cell in cellForRowAtIndexPath.
The reason is simple: I will reuse a cell with some labels already added and add a new label.
Either use the default cell.textLabel, either create a subclass for UITableViewCell, with a
-(void)setData:(dictionary or string)object;
and in implementation just set the proper data to proper UI controls.
Add/create controls either in init method in the subclass, or in IB/Storyboard.
Call the dictionary or string should be picked in correspondence to indexPath, so you will always get proper data for proper cell at proper indexPath.
Try This
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellId = #"cellId";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (cell==nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
}
for (UIView *subview in [cell.contentView subviews]) {
[subview removeFromSuperview];
}
/// your UI on cell goes here
return cell;
}

UITableView in UIView in UIScrollview : On tap in UITableView data gets cleared

For work purposes I need to create a UIScrollView which embeds a UIView which in his turn embeds an UITableView via the container feature in Xcode.
My UIScrollView is a full page scrollview with Paging enabled.
My UIView is filled with a UIImage, some UIButton's and a container linking to a UITableView.
On initial launch, the data is loaded perfectly, meaning the UITableView is filled with the data, the UIImage is filled, and the Buttons are placed correctly.
But for some strange reason the when I try to tap or scroll in the UITableView in the container all the data from my UITableView gets cleared.
I'm posting this question here, as I have not found any other similar issue on StackOverFlow or any other website.
UITableViewCode:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.productTable setBackgroundView:nil];
self.productTable.backgroundColor = [UIColor clearColor];
self.productTable.delegate = self;
self.productTable.dataSource = self;
}
- (void) viewDidAppear:(BOOL)animated {
/*CGSize tmp = self.productTable.contentSize;
self.productTable.frame = CGRectMake(0, 0, tmp.width, tmp.height * 3);*/
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
NSLog(#"section count : %i", [self.Products count]);
return [self.Products count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
xcsSectionInfo *sectionInfo = [self.Products objectAtIndex:section];
if (sectionInfo.isOpen == NO) {
return 1;
} else {
return 3;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
xcsSectionInfo *sectionInfo = [self.Products objectAtIndex:indexPath.section];
if (indexPath.row == 0) {
static NSString *CellIdentifier = #"Header";
xcsProductHeaderCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.articleNumber.text = sectionInfo.product.articleNumber;
cell.articleColor.text = sectionInfo.product.articleColor;
cell.backgroundColor = [UIColor grayColor];
if (sectionInfo.isOpen == YES && sectionInfo == self.currentSectionInfo) {
cell.expandImage.image = [UIImage imageNamed:#"arrow_down.png"];
} else if (sectionInfo.isOpen == NO) {
cell.expandImage.image = [UIImage imageNamed:#"arrow_up.png"];
}
return cell;
} else if (indexPath.row == 1) {
static NSString *CellIdentifier = #"ProductHeader";
xcsProductTitleCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.colorTempHeader.text = #"Color Temperature";
cell.sourceQualityHeader.text = #"Source Quality";
cell.sourceTypeHeader.text = #"Source Type";
cell.luminaireFluxHeader.text = #"Luminaire Flux";
cell.powerConsumptionHeader.text = #"Power Consumption";
cell.luminaireEfficacyHeader.text = #"Luminaire Efficacy";
cell.backgroundColor = [UIColor grayColor];
return cell;
} else if (indexPath.row == 2) {
static NSString *CellIdentifier = #"Product";
xcsProductCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.colorTemp.text = sectionInfo.product.colorTemperature;
cell.sourceQuality.text = sectionInfo.product.sourceQuality;
cell.sourceType.text = sectionInfo.product.sourceType;
cell.luminaireFlux.text = sectionInfo.product.luminaireFlux;
cell.powerConsumption.text = sectionInfo.product.powerConsumption;
cell.luminaireEfficacy.text = sectionInfo.product.luminaireEfficacy;
cell.backgroundColor = [UIColor grayColor];
return cell;
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
xcsSectionInfo *sectionInfo = [self.Products objectAtIndex:indexPath.section];
NSIndexPath *path0 = [NSIndexPath indexPathForRow:[indexPath row]+1 inSection:[indexPath section]];
NSIndexPath *path1 = [NSIndexPath indexPathForRow:[indexPath row]+2 inSection:[indexPath section]];
NSArray *indexPathArray = [NSArray arrayWithObjects: path0, path1, nil];
if (sectionInfo.isOpen == NO) {
sectionInfo.isOpen = YES;
[tableView insertRowsAtIndexPaths:indexPathArray withRowAnimation:NO];
} else {
sectionInfo.isOpen = NO;
[tableView deleteRowsAtIndexPaths:indexPathArray withRowAnimation:NO];
}
[self.Products replaceObjectAtIndex:indexPath.section withObject:sectionInfo];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
self.currentSectionInfo = sectionInfo;
[tableView reloadData];
}
Btw.: I'm using storyboards
Regards and thanks in advance.
UPDATE 2:
I think a UIPageViewController would be more appropriate (link‌​). It looks like it accomplishes what you are trying to achieve. And probably much more simple than managing scroll views embedded in other scroll views.
UPDATE:
It looks like what you are trying to achieve is made possible in the UIPageViewController (link). If this works, it would be better than trying to manage scroll views embedded in other views.
Embedding a UITableView is specifically NOT recommended by Apple. Conflicts arise when the system is trying to figure out where to send events:
Important: You should not embed UIWebView or UITableView objects in
UIScrollView objects. If you do so, unexpected behavior can result
because touch events for the two objects can be mixed up and wrongly
handled.
(source)
But here is the stupid part, when you go to the source link, you will notice that appears in the docs for the UIWebView. Apple forgot to include it in the docs for UITableView.

Resources