UITableView can't scroll bottom after didselectRowAtIndexPath - ipad

I have a UITableViewController in iPAD, when I first load the tableview, I can scroll to the bottom, but if select one cell with didSelectRowAtIndexPath, I can't scroll anymore to the bottom, the tableView keep bouncing back, it is a really weird behaviour.I've put some logs to get all the frame/bounds/contentSize/contentInset/contentOffset.
At every click the table height keeps growing, I can't understand how to fix this problem.
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
if ([self.navigationController.parentViewController isKindOfClass:[UISplitViewController class]]) {
// iPad split view controller support
UISplitViewController *split = (UISplitViewController *)self.navigationController.parentViewController;
NSMutableArray *allControllers = [[NSMutableArray alloc] initWithArray:split.viewControllers];
NSArray *allControllersCopy = [allControllers copy];
for(int i = 0;i < allControllersCopy.count;i++)
{
UIViewController *s = [allControllersCopy objectAtIndex:i];
if ([s isKindOfClass:[UINavigationController class]]) {
NSLog(#"UINavigationController at index : %d",i);
}
NSLog(#"custom split : %#", s.title);
}
UINavigationController *nav = [split.viewControllers objectAtIndex:1];
allControllers = [[NSMutableArray alloc] initWithArray:nav.viewControllers];
for(int i = 0;i < allControllers.count;i++)
{
UIViewController *s = [allControllers objectAtIndex:i];
if(![s isKindOfClass:[MVPTaskViewController class]])
{
[nav popViewControllerAnimated:NO];
}
}
self.nTaskViewController = [nav.viewControllers objectAtIndex:0];
self.nTaskViewController.selectedTask = selectedTask;
[self.nTaskViewController updateTask:self.nTaskViewController.selectedTask];
NSIndexPath *cellAtIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
[self.tableView scrollToRowAtIndexPath:cellAtIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
NSLog(#"tableView frame height %f",self.tableView.frame.size.height);
NSLog(#"tableView frame width %f",self.tableView.frame.size.width);
NSLog(#"tableView contentSize height %f",self.tableView.contentSize.height);
NSLog(#"tableView contentSize width %f",self.tableView.contentSize.width);
NSLog(#"tableView content offset x %f - y %f",self.tableView.contentOffset.x, self.tableView.contentOffset.y);
}
This are the logs I get :
2013-12-12 12:33:47.854 moveplanner[7604:70b] view will appear
2013-12-12 12:33:47.854 moveplanner[7604:70b] tableView frame height 648.000000
2013-12-12 12:33:47.854 moveplanner[7604:70b] tableView frame width 320.000000
2013-12-12 12:33:47.855 moveplanner[7604:70b] tableView contentSize height 2313.058105
2013-12-12 12:33:47.856 moveplanner[7604:70b] tableView contentSize width 320.000000
2013-12-12 12:33:47.856 moveplanner[7604:70b] tableView content offset x 0.000000 - y 0.000000
2013-12-12 12:33:47.934 moveplanner[7604:70b] viewDidAppear details
2013-12-12 12:33:55.470 moveplanner[7604:70b] UPDATE TASK
2013-12-12 12:33:55.471 moveplanner[7604:70b] SELECTED TASK : Switch home insurance
2013-12-12 12:33:55.494 moveplanner[7604:70b] tableView frame height 808.000000
2013-12-12 12:33:55.495 moveplanner[7604:70b] tableView frame width 320.000000
2013-12-12 12:33:55.496 moveplanner[7604:70b] tableView contentSize height 2313.058105
2013-12-12 12:33:55.496 moveplanner[7604:70b] tableView contentSize width 320.000000
2013-12-12 12:33:55.496 moveplanner[7604:70b] tableView content offset x 0.000000 - y 0.000000
First click on a cell
2013-12-12 12:33:57.546 moveplanner[7604:70b] UPDATE TASK
2013-12-12 12:33:57.546 moveplanner[7604:70b] SELECTED TASK : Recycle unwanted items
2013-12-12 12:33:57.547 moveplanner[7604:70b] tableView frame height 968.000000
2013-12-12 12:33:57.548 moveplanner[7604:70b] tableView frame width 320.000000
2013-12-12 12:33:57.549 moveplanner[7604:70b] tableView contentSize height 2313.058105
2013-12-12 12:33:57.549 moveplanner[7604:70b] tableView contentSize width 320.000000
2013-12-12 12:33:57.549 moveplanner[7604:70b] tableView content offset x 0.000000 - y 317.000000
Second click on a cell
2013-12-12 12:34:00.448 moveplanner[7604:70b] UPDATE TASK
2013-12-12 12:34:00.448 moveplanner[7604:70b] SELECTED TASK : Gas boiler service
2013-12-12 12:34:00.449 moveplanner[7604:70b] tableView frame height 1128.000000
2013-12-12 12:34:00.450 moveplanner[7604:70b] tableView frame width 320.000000
2013-12-12 12:34:00.451 moveplanner[7604:70b] tableView contentSize height 2313.058105
2013-12-12 12:34:00.451 moveplanner[7604:70b] tableView contentSize width 320.000000
2013-12-12 12:34:00.451 moveplanner[7604:70b] tableView content offset x -0.000000 - y 1185.000000
Third click on a cell
2013-12-12 12:34:09.852 moveplanner[7604:70b] UPDATE TASK
2013-12-12 12:34:09.852 moveplanner[7604:70b] SELECTED TASK : Change the locks
2013-12-12 12:34:09.853 moveplanner[7604:70b] tableView frame height 1288.000000
2013-12-12 12:34:09.854 moveplanner[7604:70b] tableView frame width 320.000000
2013-12-12 12:34:09.854 moveplanner[7604:70b] tableView contentSize height 2313.058105
2013-12-12 12:34:09.855 moveplanner[7604:70b] tableView contentSize width 320.000000
2013-12-12 12:34:09.855 moveplanner[7604:70b] tableView content offset x -0.000000 - y 1025.000000

[self.tableView scrollToRowAtIndexPath:cellAtIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
might be the culprit.

I have found a solution.I don't know if it is the right way to fix the problem, but it works.
I have added in didSelectRowAtIndexPath after NSIndexPath *cellAtIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];[self.tableView scrollToRowAtIndexPath:cellAtIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
CGRect tbFrame = [self.tableView frame];
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
{
tbFrame.size.height = 910; }
else {
tbFrame.size.height = 655;
}
[self.tableView setFrame:tbFrame];
Hope to help someonelse

Related

UITableview reloadData is not resetting frame for iPhone 5

I'm adding new cells to a table view using a pull to add function. When you pull down on the table view past a threshold a placeholder cell is added. Then, I call reloadData and becomeFirstResponder on the placeholder cell.
The problem is reloadData doesn't appear to be resetting the tableview frame for iPhone 5 and lower. This causes the placeholder cell to be out of visible range. The table offset should be 0.
Add Placeholder
-(void)todoPlaceHolderAdded {
NSLog(#"todoPlaceHolderAdded");
// create the new item
TodoItem *newItem = [[TodoItem alloc] initWithText:#""];
[_todoList insertObject:newItem atIndex:0];
// refresh the table
[self.tableView reloadData];
// find new cell
ToDoCell* editCell;
for (ToDoCell* cell in _tableView.visibleCells) {
if (cell.todoItem == newItem) {
editCell = cell;
editCell.todoItem = newItem;
_cellInEdit = cell;
editCell.textField.placeholder = #"Enter task";
break;
}
}
// enter edit mode
[editCell.textField becomeFirstResponder];
}
Edit Cell
-(void)cellDidBeginEditing:(ToDoCell *)editingCell {
NSLog(#"cellDidBeginEditing");
_tableView.scrollEnabled = NO;
_tableView.bounces = NO;
_superViewHorizontalScroll.scrollEnabled = NO;
_cellInEdit = editingCell;
//Set offset to current editing cell
_editingOffset = _tableView.contentOffset.y - editingCell.frame.origin.y;
NSLog(#"Table Offset: %f", _tableView.contentOffset.y);
NSLog(#"Frame y: %f", editingCell.frame.origin.y);
NSLog(#"Offset: %f", _editingOffset);
//Slide rows to editing cell
for(ToDoCell* cell in [_tableView visibleCells]) {
//Add flag for cells that edit is in progress
cell.isEditing = YES;
[UIView animateWithDuration:0.3
animations:^{
//Set new frame for cell
cell.frame = CGRectOffset(cell.frame, 0, _editingOffset);
//Reduce alpha for non editing cells
if (cell != _cellInEdit) {
cell.alpha = 0.2;
}
}];
}
}
iPhone 5 and Lower
2015-04-25 23:09:39.093 QuickScrollTest[7996:320879] todoPlaceHolderAdded
2015-04-25 23:09:39.093 QuickScrollTest[7996:320879] cellDidBeginEditing
2015-04-25 23:09:39.093 QuickScrollTest[7996:320879] Table Offset: -136.000000
2015-04-25 23:09:39.093 QuickScrollTest[7996:320879] Frame y: 0.000000
2015-04-25 23:09:39.093 QuickScrollTest[7996:320879] Offset: -136.000000
iPhone 6
2015-04-25 23:11:01.071 QuickScrollTest[8179:323067] todoPlaceHolderAdded
2015-04-25 23:11:01.078 QuickScrollTest[8179:323067] cellDidBeginEditing
2015-04-25 23:11:01.078 QuickScrollTest[8179:323067] Table Offset: 0.000000
2015-04-25 23:11:01.078 QuickScrollTest[8179:323067] Frame y: 0.000000
2015-04-25 23:11:01.078 QuickScrollTest[8179:323067] Offset: 0.000000

Get UICollectionView cell position after scrollToItemAtIndexPath

I would like to get a UICollectionViewCell's position after programattically scrolling to a cell. I'm setting the scroll position like this.
[self.collectionView scrollToItemAtIndexPath:indexPath
atScrollPosition:UICollectionViewScrollPositionCenteredVertically
animated:NO];
I would then like to get the frame of the cell I have scrolled to as I need to position another UIView near it.
This code returns the rect of the cell with the scrollview, but I need the position within the visible rect.
UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];
CGRect cellRect = attributes.frame;
The frame of a cell doesn't change, it's the content offset of the enclosing scroll view. Subtract the contentOffset from the frame's origin to get the on-screen position, or use one of the convertRect: methods to get the coordinates in a related view.
Here is the cell X and Center values
UICollectionViewLayoutAttributes *attributes = [collectionView layoutAttributesForItemAtIndexPath:indexPath];
CGPoint cellCenterPoint = attributes.center;
CGPoint contentOffset = [collectionView contentOffset];
NSLog(#"%f , %f",-1*contentOffset.x , cellCenterPoint.x);
int relativeCellCenter = (-1*contentOffset.x) + cellCenterPoint.x +collectionView.frame.origin.x;
int relativeX = (-1*contentOffset.x) +collectionView.frame.origin.x;

All my UIView frames have height and width of 0

I have a storyboard with a view, but all my UIViews (actually UIViewTable and UIScrollView) appear to have a frame.width and frame.height of 0.
I can clearly see them in the simulator.
- (void) viewDidAppear:(BOOL)animated{
// check frame size of tableView
NSLog(#"Frame width = %f, height = %f", self.tableView.frame.size.width, self.tableView.frame.size.height);
// check contentSize of tableView
NSLog(#"contentSize width = %f, height = %f", self.tableView.contentSize.width, self.tableView.contentSize.height);
// check frame size of scrollView
NSLog(#"scrollView size - width = %f, height = %f", self.scrollView.frame.size.width, self.scrollView.frame.size.height);
[super viewDidAppear:animated];
}
All these logs show 0 for the height and the width.

Resize UIScrollView with setcontentsize

I am trying to resize UIScrollView inside a UICOllectionViewCell but it doesn't resize it.
-(int)resizeScrollView:(int)height{
NSLog(#"Before Scroll height %f",self.scrollView.frame.size.height);
float currentHeight=self.scrollView.frame.size.height+height+200;
NSLog(#"height %f",currentHeight);
CGSize size=CGSizeMake(self.scrollView.frame.size.width ,
currentHeight + 10 );
[self.scrollView setContentSize:size];
self.scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
NSLog(#"After Scroll height %f",self.scrollView.frame.size.height);
return currentHeight;
}
Setting the contentSize adjusts the amount of logical space that the scroll view scrolls over. You need to set the frame or the bounds to adjust the size of the scrollview in its parent view.
CGRect scrollFrame = self.scrollView.frame;
scrollFrame.size.height += height + 210;
self.scrollView.frame = scrollFrame;

UIScrollView behave strange

I set UIScrollView's subview's height to 768,and UIScrollView's contentSize is 1024*768 .But when I swipe up or swipe down,the subview(UIImageView) will scroll up or down a little.I don't know why.
here is my code
-(void)viewDidLoad
{
[super viewDidLoad];
// scrollView is an outlet of UIScrollView
[scrollView setBackgroundColor:[UIColor blackColor]];
[scrollView setCanCancelContentTouches:NO];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
scrollView.scrollEnabled = YES;
// pagingEnabled property default is NO, if set the scroller will stop or snap at each photo
// if you want free-flowing scroll, don't set this property.
scrollView.pagingEnabled = YES;
// load all the images from our bundle and add them to the scroll view
NSUInteger i;
imageCount=3;
for (i = 1; i <= imageCount; i++)
{
NSString *imageName = [NSString stringWithFormat:#"tu%d_s.png", i];
UIImage *image = [UIImage imageNamed:imageName];
if(!image)
{
NSLog(#"%# is nil",imageName);
}
UIImageView *TempImageView = [[UIImageView alloc] initWithImage:image];
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = TempImageView.frame;
rect.size.height = 768;
rect.size.width = 1024;
TempImageView.frame = rect;
TempImageView.tag = i; // tag our images for later use when we place them in serial fashion
[scrollView addSubview:TempImageView];
NSLog(#"viewDidLoad TempImageView width %f,height %f,x %f,y %f",TempImageView.frame.size.width,TempImageView.frame.size.height,TempImageView.frame.origin.x,TempImageView.frame.origin.y);
}
[self layoutScrollImages]; // now place the photos in serial layout within the scrollview
}
- (void)layoutScrollImages
{
UIImageView *view = nil;
NSArray *subviews = [scrollView subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (1024);
}
NSLog(#"shang2 layoutScrollImages width %f,height %f,x %f,y %f",view.frame.size.width,view.frame.size.height,view.frame.origin.x,view.frame.origin.y);
}
// set the content size so it can be scrollable
[scrollView setContentSize:CGSizeMake((imageCount * 1024), 768)];
NSLog(#"shang2 content width %f,height %f,x %f,y %f",scrollView.contentSize.width,scrollView.contentSize.height,scrollView.frame.origin.x,scrollView.frame.origin.y);
}
here is Xcode log
2013-04-03 20:50:23.939 animation[1464:c07] viewDidLoad TempImageView width 1024.000000,height 768.000000,x 0.000000,y 0.000000
2013-04-03 20:50:23.952 animation[1464:c07] viewDidLoad TempImageView width 1024.000000,height 768.000000,x 0.000000,y 0.000000
2013-04-03 20:50:23.995 animation[1464:c07] viewDidLoad TempImageView width 1024.000000,height 768.000000,x 0.000000,y 0.000000
2013-04-03 20:50:23.995 animation[1464:c07] shang2 layoutScrollImages width 7.000000,height 5.000000,x 741.000000,y 1019.000000
2013-04-03 20:50:23.996 animation[1464:c07] shang2 layoutScrollImages width 1024.000000,height 768.000000,x 0.000000,y 0.000000
2013-04-03 20:50:23.996 animation[1464:c07] shang2 layoutScrollImages width 1024.000000,height 768.000000,x 1024.000000,y 0.000000
2013-04-03 20:50:23.996 animation[1464:c07] shang2 layoutScrollImages width 1024.000000,height 768.000000,x 2048.000000,y 0.000000
2013-04-03 20:50:23.996 animation[1464:c07] shang2 content width 3072.000000,height 768.000000,x 0.000000,y 0.000000
If your view controller containing the scrollview has either a UINavigationController or UITabBarController, the view will resize itself to fit the bounds which after the 44 pixels from the navigation controller would be 724, therefore the scrollview can scroll 44 pixels.

Resources