UITableView frame change animation issue - iphone

I've googled about this problem a lot but there seems to be no answer. So I'm hoping some of you may know how to deal with this. I have a view controller that has a tableview, when I change the view frame with animation, everything goes well, except one particular case, when tableview has more items than it can fit to screen, and only when the tableview is scrolled to bottom. Then if I shrink the view height, my view animates correctly, but the tableview somehow jumps up a bit and only then animates to the bottom.
If I shrink the view, but tableview isn't scrolled to bottom (even if I can see the last cell, lets say a bit more than half of it) it does animate correctly.
I've tried couple of things, like setting autoresizing masks on and off and also animate from current state or something like that, but that didn't help :/
So any suggestions what could be the problem?
EDIT:
Code that i use to change frame
[UIView animateWithDuration:0.5
delay:0.0
options: UIViewAnimationCurveEaseOut
animations:^{
[_contView setFrame:CGRectMake(0, 0, 320, 420)];
}
completion:^(BOOL finished){
}];

I fought this same bug for awhile before realizing I couldn't figure out for the life of me why it was happening...until I found a very detailed explanation and solution.
Full write-up can be found here:
http://lists.apple.com/archives/cocoa-dev/2012/Apr/msg00341.html
Quick solution is to change contentInset instead of the table view frame. Just add the height of whatever you are showing (ie a keyboard or ad banner view) to the contentInset.bottom property. The scrolling area will be increased to account for the required resize.
In this example, I was showing an ad banner view on top of my tableview:
UIEdgeInsets insets = myTable.contentInset;
insets.bottom += 50; // 50px is the height of the ad banner view
myTable.contentInset = insets;

I used to have a similar problem and I implemented this workaround (Disclaimer: this is a hack to a currently-unresolved iOS bug):
// check if the table view is scrolled to the bottom
if (tableView.contentOffset.y + tableView.frame.size.height == tableView.contentSize.height) {
// if it is, shift the table view contents up one pixel
[tableView setContentOffset:CGPointMake(tableView.contentOffset.x, tableView.contentOffset.y - 1) animated:NO];
}
// call the animation block afterwards here
It's a hack, though not noticeable to the user since it's just a 1 pixel motion. UITableView has a few bugs (reported to Apple already, but not yet resolved) when it comes to animations from a scrolled-to-bottom position.

You should use autoresizing from xib which is right corner of xcode ... I think this may help you.

Try to add footer view to your table with non-zero height.

Related

iOS Scrolling Interface - FoodSpotting signup interface

I'm not sure if you guys have checked out the sign-in/sign-up interface for the iPhone app "FoodSpotting
, but it's pretty cool. Somehow they're able to move what seems to be a UITableView vertically downwards to create an entirely new view with a slick animation. It essentially looks like they're moving the entire screen down, but yet when you try and scroll back up to the original sign-in screen you can't.
Does anybody know how to get this kind of functionality with either a UITableView, ScrollView, or regular UIView? If you need more clarification on the kind of animation I'm talking about either download the app or I can try and post pictures...
Hey I actually built that page! It's pretty simple: It's just two UITableViews, and a simple Core Animation animation is used to "scroll" between the two. I suppose a similar effect can be achieved using only one tableview, although using two separate ones allows us to take advantage of the individual tableview's scrolling behavior to do things like move the form up when the keyboard appears.
EDIT:
I know this is SUUUPER late, but here's a quick explanation...
My controller is a UIViewController subclass, not a UITableViewController. In the viewcontroller's view, I set up two tableviews like this...
Black = Status Bar
Red = Screen Area
Blue = Top TableView
Green = Bottom TableView, positioned just offscreen
The code to transition between the two is pretty simple...
//transition to bottom tableview
[UIView animateWithDuration:ANIMATION_TIME animations:^{
bottomTableView.transform = CGAffineTransformMakeTranslation(0, -self.view.frame.size.height);
topTableView.transform = CGAffineTransformMakeTranslation(0, -self.view.frame.size.height);
}];
…
//and to return to original state…
[UIView animateWithDuration:ANIMATION_TIME animations:^{
bottomTableView.transform = CGAffineTransformIdentity;
topTableView.transform = CGAffineTransformIdentity;
}];
Yes you are right. It's a UIScrollView on UIView. By default scrollview is scrollable and on completing sign up View is animated.
So this will be easy to implement.

scrollRectToVisible doesn't work with keyboard and (next/previous)toolbar. Please see the picture

scrollRectToVisible doesn't work with keyboard and (next/previous/done)toolbar. Please see the picture.
[scrollview scrollRectToVisible: textFieldRect animated:YES];
The method scrollRectToVisible: is doing the correct thing. It's scrolling the view to the point where the CGRect specified is within the visible section of the view. But, here's the thing - you're positioning another view over the top of the scroll view, so a part of the scroll view's visible area is obscured. The scroll view doesn't know about this, it only knows about it's visible section independant of any other views.
A solution to this may be to offset your textFieldRect CGRect by a given amount, to get the scroll view to scroll a little further in a given direction. You could, for example, use the size of the onscreen keyboard to calculate this offset, or perhaps the size of the translucent view that can be seen in your screenshot?

UIView loses background when animated up

I am working on an iOS app and am having trouble with a really tall UIView (2400px tall). The UIView contains a really long form that's been broken down into 5 parts. As the user completes one part of the form, I would like to slide the UIView up to reveal the next part. I present the UIView modally.
The problem that I am having is that when I slide up the UIView, the background slides up along with the objects in the first section and the next section is left with a clear background. The code I use to slide the UIView is:
- (IBAction)slideUp {
// Slide the view up the screen to reveal the next section
CGRect frame = self.view.frame;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.75];
frame.origin.y = -480;
self.view.frame = frame;
[UIView commitAnimations];
}
All of the objects in the really tall UIView slide up fine, I'm just losing my background color. Any idea why?
Thanks!
Is your background being rendered by some sort of "background view" that's sized to fit the screen?
In any case, you should probably use a UIScrollView with scrolling disabled instead of a really long UIView. You can then simply animate the contentOffset property to scroll the controls up, but the scrollview itself can simply be screen-sized.
Instead of using self.view.frame, i would highly recommend you create an IBOutlet for the really long view so that the code looks like self.longView.frame.
This will help making it clear which views you are working with.
Right now i am betting that you are animating the wrong view.

Making UITableView scroll to right location when using custom keyboard

I have a UITableView and I need to use a custom keyboard with it and, for a few reasons, I can't use it as an inputView. So I am having a my keyboard view appear as a subview. Its height is 260. I want the table view to scroll so that the selected cell always has a y-position between 0 and 260. Is this possible? Here is what I am currently trying... (this is in the keyboard class)
-(void)showForCellAtIndexPath:(NSIndexPath*)indexPath{
[UIView beginAnimations:nil context:NULL];
self.view.frame = CGRectMake(0.0,220.0,320.0,260.0);
delegate.tableView.contentInset = UIEdgeInsetsMake(0.0,0.0,260.0,0.0);
delegate.tableView.scrollIndicatorInsets = delegate.tableView.contentInset;
delegate.view.frame = CGRectMake(0.0,-210.0, delegate.view.frame.size.width,delegate.view.frame.size.height);
[UIView commitAnimations];
[delegate.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
I would love your help. Thanks!
Alright...this solution is kind of a hack, but if someone searches and finds this, I don't want them to go thru the hell I did to figure it out.
What I did was modify the header height of the first section of the grouped table view to be large (300px was big enough for me). Then I changed the y-inset (in my case to -255), so that everything looked normal. When the user selects a section, I immediately eliminate the inset and do a scroll to bottom... Then, when the user hits done, I re-add the inset, so that the user doesn't have to go through extra scrolling.
I hope this helps anyone who has this same issue!

UIScrollView not showing scroll indicator

I have a UIScrollView which I create and size dynamically using...
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width , length);
I then add subviews to the UIScrollView.
I do have scrollView.showsVerticalScrollIndicator = YES;
When scrolling the scroll indicator never appears.
Even if I call [scrollView flashScrollIndicators] nothing happens.
Ideas?
Had the same problem and couldn't find the cause. The last answer gave the final hint: whenever I added new subviews I first removed all existing subviews from the scrollview (and apparently also the scroll indicators).
After checking in my loop, if the subview really was of the kind I wanted to be removed the scroll indicators showed up:
for (NSObject * subview in [[[scrollView subviews] copy] autorelease]) {
if ([subview isKindOfClass:[MySubView class]]) {
[(MySubView*)subview removeFromSuperview];
}
}
Update: changed code to Nikolai's suggestion
When I've dealt with this before, in my implementation of a grid, I would occasionally get some cells over the top of the scroll indicator. To fix this I am now inserting subviews at index 0 rather than adding them, which adds them to the top. So try something like this:
[scrollview insertSubview:subview atIndex:0];
For me, the horizontal indicator had mysteriously disappeared in my app on iOS 7. Later found out that for some strange reason, I had to enable both Shows Horizontal Indicator and Shows Vertical Indicator to make the horizontal one show up. If I set it to not show the vertical indicator, it would also not show horizontal indicator.
I fix this by adding this code after add new subview:
self.showsVerticalScrollIndicator = NO;
self.showsVerticalScrollIndicator = YES;
It will also happen (at least in the case of a UITableView) if the contentSize is too small for the table view to scroll. If you have enabled bouncing, then the tableview does not actually scroll and does not display the indicators therefore. Try fitting more content inside.
It can happen also if the parent of the scrollview is smaller horizontally than the scroll view itself :
The scroll bar is stuck to the right side of the ScrollView / TableView and this right side is not visible due to the parent bounds ( with a clipToBounds hidding it for instance).
I've seen this issue so I share it in case it can help.
Just check the width of your ScrollView's frame not to be bigger than the width of its parent view frame.
Two conditions,
If you are using a storyboard
If you are using a UITableView inside a UIViewController
Then, you should check your indicator insets are set to 0 (or any other number that is relevant to your autolayout):
Noticed this when the UIScrollView was a 48 px tall horizontal band, scrollable horizontally. Maybe Cocoa decides the area is too small for a scroll indicator...