I'm having a problem with my table view scrolling to bottom. I tried to search stack overflow for a solution but nothing could help.
Here is what I have:
I have a table view that I'm loading extra cells into each time the user scrolls to the bottom of it. I did it as follows:
- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == ([self.tableView numberOfRowsInSection:0] - 1))
//load more data..
}
after the data gets loaded successfully through an internet connection, I'm calling [self.tableView reloadData] to refresh the table and increase its size.
Now here comes the problem:
When the user selects a cell, a details view controller is presented. I noticed that before presenting the details view, the table is quickly resized to its original size showing only the initial number of cells inside.
When the details view is dismissed, the table view comes back to its original size (without fitting the data loaded on willDisplayCell: forRowAtIndexPath:) and there is no way it could be scrolled down till the end of all data.
I checked all these points, but nothing helps:
the data in table view is reloaded by calling [self.tableView reloadData] in viewWillAppear method.
the delegate and dataSource of the table view are set correctly to the container view controller.
checked calling tableView: numberOfRowsInSection: when the view appears again, and it is returning the exact number of all the data I have, but the problem is in the table not fitting its size to my total data.
I also tried to resize the table frame as follows:
CGRect frame = self.tableView.frame;
frame.size.height = self.tableView.contentSize.height;
self.tableView.frame = frame;
But nothing changes.
Any help please??
Update:
I'm doing nothing unusual in didSelectRowAtIndexPath. The code is simply:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailsViewController *vc=[[DetailsViewController alloc]initWithNibName:#"DetailsViewController" bundle:nil];
[self presentViewController:vc animated:YES completion:nil];
}
take object of uiscrollview in uiview
take object of uitableview in uiscrollview
set the property scrollenabled = flase of uitableview
write the delegate method of uiscrollview
- (void) scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView == scrollObj) {
CGFloat scrollPosition = scrollObj.contentSize.height - scrollObj.frame.size.height - scrollObj.contentOffset.y;
if (scrollPosition < 30) {
if ((!spinnerBottom.isAnimating) || intGetDataCallRunning == 0) {
//[spinnerBottom startAnimating];
//[self getLoginFollowingUserVideosCall];
//run WebService call and after that reload the table or if you have data exists then only reload the table
//and after reloading table follow step no 5.
}
}
}
}
after reload the table set height of table and scroll
tblVideo.frame = CGRectMake(0, 0, 320, tblVideo.contentSize.height);
scrollObj.contentSize = CGSizeMake(320,tblVideo.contentSize.height+60);
Related
I have used a UIScroll View. It has a contentView (of type UIView) which again has a questionView (UIView) and a _questionTableView (UITableView). I know this is not the right practice but the design required me to implement like this. Scroll is working perfectly fine.
I have a total of 8 cells and only 4 cells are visible when the screen is opened first. Upon tapping on any of these 4 cells
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
is called.
Upon scrolling down, rest of the cells become visible. But tapping on them doesn't trigger didSelectRowAtIndexPath
I read various stack overflow posts on this issue (to enable tapping on cells) where people suggested to increase the content view size/ scrollView's contentSize/ tableView's height. I tried all of them but no luck.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myCell"];
_scrollView.contentSize = CGSizeMake(_questionTableView.frame.size.width, 1000);
_contentView.frame = CGRectMake(0, 0, _questionTableView.frame.size.width * 2, 1000);
_questionTableView.frame = CGRectMake(0, 0, _qTableView.frame.size.width , 500);
self.scrollView.delegate = self;
return cell;
}
Is there nay way to make the cells tappable?
EDIT: I experimented some more and I realized that after several taps on the cell, the method - didSelectRowAtIndexPath is called. But those are some random taps 5-6 times. Couldn't identify a pattern.
Try to deselect property "Delays Content Touches" in your parent scroll view. It may help!
I'm currently updating an app to iOS8, and am replacing my own cell height calculations. I have a tableview with a bunch of custom cells. Each cell when selected will present/push a new view onto the navigationController. When the tableview is populated with these cells, and the user selects one near the bottom of the table, the tableview jumps to the top right before the new view is presented. This is very distracting to the user. I'm trying using self sizing cells introduced in iOS 8 here (in the viewDidLoad):
self.tableView.estimatedRowHeight = 60.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
Here's the code for when a cell is selected
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIViewController *selectedViewController = [[UIStoryboard storyboardWithName:#"Trip" bundle:nil] instantiateViewControllerWithIdentifier:#"TripDetail"];
DetailViewController *destViewController = (id)selectedViewController;
[destViewController setData:self.dataStore];
[self.navigationController pushViewController:selectedViewController animated:YES];
}
Does anyone know why this is happening? And how I can make it stop?
It's a known issue. The tableView is calling its delegate to get an estimated height for the rows, which is causing the table to scroll.
You can wait to see if it's fixed in the next update, or implement tableView:estimatedHeightForRowAtIndexPath: (as a workaround for now) and return a cached height. Since the estimate will be the actual height, the table won't jump.
This happen's when the table delegate was tapped "didSelectRowAtIndexPath:"
because the delegate method "numbersOfSectionsInTableView" && "numbersOfRowsInSection" will get called. its like reloading the table.
You can fix that jumping state with this method "heightForRowAtIndexPath:" however you'll have to disregard your auto sizing.
After quite a lot searching around Google, Stackoverflow and apples documentation, I have almost given up.
I am making an app to index costumers and because of a potentially very long list, I use section index to navigate faster. My problem is shown in the picture below.
When I drag an item to reveal the delete button, it is partially hidden below my section index bar.
I have no code setting tableview or tableviewcells width and the section index can't really be changed, as far as i am concerned.
EDIT:
The question is how I can have the tableview cells end before they get overlapped, so the delete button is fully visible.
EDIT 2:
I already tried setting the cell frame smaller without any luck.
cell.frame = CGRectMake(cell.frame.origin.x, cell.frame.origin.y, cell.frame.size.width-30, cell.frame.size.height);
I also tried the same with the tableview, but as it is in a UITableViewController it cannot be resized.
self.tableView.frame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y, self.tableView.frame.size.width-30, self.tableView.frame.size.height);
As a simple work-around we resolved the visual overlap of the index by setting the background color of the index to clearColor.
self.tableView.sectionIndexBackgroundColor = [UIColor clearColor];
* This looks visually better, but the index will still overlap your tableViewCell.
Another possible work-around would be to hide the index bar when entering edit mode:
// allow editing
[self.tableView setEditing:YES animated:YES];
// hides the index
self.tableView.sectionIndexMinimumDisplayRowCount = NSIntegerMax;
The inEditMode method should do the trick. Below I embed a complete code that hides the index while editing and shows it again when the editing is done.
-(void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath{
[self inEditMode:YES];
}
-(void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath{
[self inEditMode:NO];
}
//on self.editButtonItem click
-(void)setEditing:(BOOL)editing animated:(BOOL)animated{
[super setEditing:editing animated:animated];
[self inEditMode:editing];
}
-(void)inEditMode:(BOOL)inEditMode{
if (inEditMode) { //hide index while in edit mode
self.tableView.sectionIndexMinimumDisplayRowCount = NSIntegerMax;
}else{
self.tableView.sectionIndexMinimumDisplayRowCount = NSIntegerMin;
}
[self.tableView reloadSectionIndexTitles];
}
Just Use this code before allocating any subview in cellForRowAtIndexPath
for (id object in cell.contentView.subviews)
{
[object removeFromSuperview];
}
I have a tableview that auto scrolls only in iOS 8 when I open a new view using [self.navigationController pushViewController:newViewController animated:YES];
Detailed Problem :
Now I'm going to give a detail of how I'm getting the problem, it's particularly in iOS 8. Take any tableview having around 50 entries, scroll it down to make the 10th entry at the top of the tableview. Then select any item on the tableview. Use the below method to push a view controller on row selection in tableview.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Open the New View
NewViewController *newVC = [[NewViewController alloc] init];
[self.navigationController pushViewController:newVC animated:YES];
}
Now you will find that on coming back from NewViewController to the previous ViewController, the tableview autoscrolls some distance. The tableview doesn't stay at the place of scroll it always changes its position automatically.
I had the same problem. I was using the new iOS 8 feature dynamic cell heigh. I was setting:
self.tableView.estimatedRowHeight = 50.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
The problem was that some cells were much higher than 50. Solution was to provide delegate method estimatedHeightForRowAtIndexPath and return values that are closer to the actual cell height. For example:
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 1) {
return 300.0;
}
return 50;
}
Another solution is to calculate cell heigh using systemLayoutSizeFittingSize inside cellForRowAtIndexPath and cache that value. Inside estimatedHeightForRowAtIndexPath supply cached values but return default if the cell height wasn't cached yet.
Just remove self.tableView.estimatedRowHeight = xxx; It works for me . The problem happens in iOS8 and does not appear in iOS10
I've got this issue. I'm using a collection view as a subview of the main view of a UIViewController. The collection view is pinned to the superview size, thus it has 4 constraints for lead,trail, top and bottom with constants equal to 0.
The cell is a subclass to UICollectionViewCell and is composed by:
first header view
second header view
UITableView
The collection view cell is loaded from xib and the interface of the views is made for 4 inches devices.
The first header view is pinned at top, trail, lead with constant 0 and fixed height to its superview.
The second header view is constrained to first header view with vertical spacing equal to 0, fixed height, pinned trail, lead with constant 0 to its superview.
The table view is constrained to second header view with vertical spacing equal to 0 and pinned trail, lead and bottom with constant 0 to its superview.
On 4 inches screen everything is OK, but when I load on 3.5 I have some problems, the fact is that I want to create UITableViewCell with a dynamic height. The height should be the height of the UITableView dived by the number of rows, in this way they will appear on screen.
The table view delegate and datasource are valorized only when I set the data that need to be loaded and that happens after creating it, but before the collection view cell is returned from the data source method.
In the -layoutSubviews method of the UICollectionViewCell subclass I set the tableview row height, to the desired value that is
- (void) layoutSubviews {
[super layoutSubviews];
self.answerTableView.rowHeight = self.answerTableView.bounds.size.height / self.quizSection.answers.count;
}
The fact is that here the table view is stil not resized thus the resulting rowHeight is wrong, the value is the same I receive in 4 inches display. The superview (the contentView of the collection view cell) is ok, but the table view has a size that is not correct. When displayed the collection view is fine except for the fact that the table view's cells are wrong in size.
So I started to trace the cycle of the collection view cell.
In the initWithFrame methods the collection view cell has the same size of the original xib (4 inches screen)
In the view controller if I ask the size of the collection view cell right after dequeuing, if resized to the correct screen size, but the table view inside not
After loading the data and setting delegate and datasource, collection view is ok, but tableview not
In the -updateConstraints of the collection view cell the table view size is still wrong
In the -layoutSubviewsof the collection view cell the table view size is still wrong
The first call of the dtasource method of the table view returns a correct size
I've found the solution that is use the delegate methods - (float) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath, but I'm really curios why the other approach doesn't work can someone explain why?
THX
[CODE FOR HELP]
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) { // Initialization code
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil];
if ([arrayOfViews count] < 1) { return nil; }
if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[UICollectionViewCell class]]) { return nil; }
self = [arrayOfViews objectAtIndex:0];
[self.answerTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:AnswerCellIdentifier];
}
return self;
}
- (void) layoutSubviews {
[super layoutSubviews];
self.answerTableView.rowHeight = self.answerTableView.bounds.size.height / self.quizSection.answers.count; //WRONG
}
- (void) updateConstraints {
[super updateConstraints];
self.answerTableView.rowHeight = self.answerTableView.bounds.size.height / self.quizSection.answers.count; //WRONG
}
#pragma mark -
#pragma mark custom getter/setter
- (void) setQuizSection:(QuizSection *)quizSection {
if (_quizSection == quizSection) {
return;
}
_quizSection = quizSection;
//Set data
self.questionLabel.text = _quizSection.question[KEY_TEXT];
self.answerTableView.delegate = self;
self.answerTableView.dataSource = self;
}
#pragma mark -
#pragma mark TableViewDelegate TableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.quizSection.answers.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:AnswerCellIdentifier];
NSDictionary * answerDict = self.quizSection.answers[indexPath.row];
cell.textLabel.text = answerDict[KEY_TEXT];
return cell;
}