Tapping status bar doesn't scroll table view to top - ios

Ok, I've read almost every single post about this issue, and they all say the same thing:
In the whole view hierarchy, only one scroll view (or subclass) should have scrollsToTop set to YES and the rest should be NO. When my view loads, I recursively iterate the whole view hierarchy just as many answers suggest, setting scrollsToTop to NO, then I only set my table view's scrollsToTop to YES, but still, it doesn't scroll when I tap the status bar. I've overridden:
-(BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView{
return YES;
}
But it's not even called even though my view controller is the scroll view delegate of my table view.
I do have cells with text views, and when the container cell awakes from nib, I also set their scrollsToTop property to NO immediately, and there are no other views deriving from scroll view.
Why would it not work?

For what it's worth, I've never set scrollsToTop on any table view controller I've ever used, and they all do this by default. Maybe all this recursive view hierarchy stuff is what is actually causing the problem. I just looked at all the apps I've written, and all of them work fine without ever touching scrollsToTop, and many of them have embedded scrollViews/textViews/etc in them. Perhaps try commenting out all that scrollsToTop code and trying it then?
Otherwise, how are you building this tableview? Is it with a nib or is this a normal UITableViewController?

Related

automaticallyAdjustsScrollViewInsets doesn't work in embedded UITableViewController with UITableView

When you have a UITableView inside a UIViewController, you have to turn off the automaticallyAdjustsScrollViewInsets flag (either in code or storyboard editor) to get the top space to not avoid the top bar. I now have a child UIViewController using an "embed" seque inside of a child view which contains a UITableView. I am seeing the "space" (the yellow area) yet I cleared all the flags in the embedded UIViewController and even cleared the flag manually in prepareForSeque, yet the space remains. Is there something else one has to do, or is this a bug?
Had this issue this morning.
Turns out, you need to uncheck automaticallyAdjustsScrollViewInsets property from parentViewController instead of child when you are using embedded view controller mode like you did.
Here is my UI structure:
ParentViewController has a container view which point to ChildViewController (subclass of UITableViewController).
Uncheck automaticallyAdjustsScrollViewInsets in ChildViewController: doesn't work
Uncheck automaticallyAdjustsScrollViewInsets in ParentViewController: works!
I have been struggling with this for hours until I realized that the answer by #user3188985 was what was happening, though the solution did not work for me.
This is because I have two contained view controllers that each contain scrollViews, and I want one to adjust, and one not, what to do?
Well if you turn off auto adjustment in the parent controller, then you must manually adjust the one scrollView that you need, e.g. setting contentInset on appropriate cases.
If you leave on auto adjustment in the parent, I have found that a dummy scrollView, with a zero frame, hidden, all scroll properties set to NO, and if it is before your visible/enabled scrollView in the child view controller view hierarchy, then it will receive the auto adjustment, and leave your visible scrollView view alone.
Alternatively, you can just have your contained view controller's top most view be a scrollView with scrolling disabled, and have it contain another scrollView with scrolling enabled, this will achieve the same thing as the "dummy" approach.
What you can see here, is that the auto adjustment flag of only the parent view controller is taken into account, but it's own view controller hierarchy is traversed to find scrollViews to adjust in each contained controller. This is simply unwanted UIKit behavior. It would be nice each child controller's auto adjust setting was checked before deciding to mess with it :/

Why content insets of a UITableView inside a UIPageViewController get messy right after an interaction?

I've created a Page-Based Application and hacked it a bit for some experiments; my simple aim is to have a UIPageViewController whose pages will contain a UIViewController holding a UITableView (after further inspection, the outcome of my experiment is the same if I use a UITableViewController instead).
To do this I've simply edited the project template, and added the UIPageViewController as an embedded view of the RootViewController using Storyboard's ContainerView object, as you can see in this screenshot:
Every controller is configured via storyboard to automatically adjust scroll view's content inset, and if I start the project with this configuration everything looks fine, and the DataViewController's tableview has its content insets properly adjusted right under the navigation bar as expected; however, as the user makes an interaction with the tableview, the content insets break and the tableview underlaps the navigation bar:
I have been able to fix this by manually setting the content insets in DataViewController's viewDidLayoutSubview method, and by disabling Adjusts Scroll View Insets on any controller, so I don't need this as an answer to solve my problem.
My question is why the content insets are properly set right after the first controller gets loaded from the storyboard the first time, and why they break after any kind of user interaction.
If you need to test it directly, here's a link to the project
I'm not 100% sure it's what you're running into, but here's some explanation regarding your setup:
By default, UIViewControllers tend to be configured to extend their content behind non-opaque bars, and to adjust scroll view insets. In your setup above this means that the container VC:
Extends its content so as to appear behind the navigation bar
Sets its scrollview's .contentInset and .scrollIndicatorInsets to be the same height as the navigation bar
"But, ah!" I hear you say, "that container view controller doesn't have a scroll view". Well this is the tricky bit:
It seems UIViewController's definition of "my scroll view" is rather simplistically, "the first scroll view I come to when searching down through my view hierarchy".
UIPageViewController happens to be implemented using a scroll view. So the container VC finds that scroll view, and adjusts its top insets. This is not really what you want; it confuses the page controller, and tends to upset layout at some point.
The simple solution there is simply to turn off .automaticallyAdjustsScrollViewInsets for the container view controller.
You then need to solve the next problem of your table view needing some kind of top insets to account for the navigation bar. So far it seems to me the best way to do this is manually either in the storyboard, or code.
Found an elegant solution:
From your storyboard, select your UIPageViewController
In the Attributes inspector, uncheck the option ViewController => Extend Edges => Under Top Bars
That's all, no weird UI hacks
Have you tried fixing the Auto Layout constraint in the container view of the Root view controller in the Storyboard (that is, the top space constraint should be set related to the Top Layout Guide and not the Superview, with constant = 0)?
You will only lose the effect of the Table View scrolling under the Navigation Bar

Embed UITableView in Scrollview

I know Apple don't recommend to Embed UITableView in UIScrollview.
So this is what I am trying to do:
I have a registration form with fields embedded in UIScrollview,
for some fields I create a drop menu by presenting UITableView, the problem is when the UITableView appears with my object the didSelectRowAtIndexPath not responding.
If there is another way it I will happy to hear, if not how can I fix it in the Current situation , thanks.
Don't add the table as a subview of the scroll view, add it as a subview of the superview of the scroll view (and, consider adding it into a container view which detects touches outside the table to dismiss it from the screen without any selection being made).
If your 'root' view for the controller is the scroll view, change your view hierarchy to use a plain view as the root and have the scroll view as a subview of that.
You may also want to use bringSubviewToFront: to ensure that the presentation is correct.

UITableView not rendering without autolayout

So I have a TableView that sits inside a scroll view. I have autolayout turned off so I can scroll. However, the table view does not render when autolayout is turned off(the cellForIndexAtPath method is not called).
I need the table view to be scrolled to -
UITableView not rendering
has all the code.
Thanks
To check if the table and scroll view are added in the nib file, you can try assigning different background colours to them temporarily. If the components are visible, check if you have connected their delegate and datasource connections to file owner.
Hope this helps.

iOS prevent subview of tableview from scrolling with tableview

I have added a subview to my tableview and when ever the user scrolls the tableview, the subview scrolls with it. How do I prevent this? I know it's probably along the lines of not adding the view to the tableview's subviews, but I have no knowledge of any other ways to do this. Thanks.
If you want to make a view a subview of the table view, then you can make it floating (non-scrolling) by changing its origin.y value in the scrollViewDidScroll method.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
self.iv.frame = CGRectMake(self.ivOrigin.x, self.ivOrigin.y + self.tableView.bounds.origin.y, self.iv.frame.size.width, self.iv.frame.size.height);
}
In this example, "iv" is a property for an image view, and "ivOrigin" is a property for the initial origin of the image view (defined when I created the image view and its frame in viewDidLoad).
The UITableView is built and intended to be a view of things that scroll.
So, you can either fight that, which as you're discovering is quite hard since everything about the component is built and focused around scrolling and fast display of a subset of the full list data... Or, you can not fight it and put your static item on top of the table as a fixed-position item.
If there's a reason you can't add the table view and your animate-out item in your main view, you can always add a custom UIView class that contains both the table view and your animated view. Have your custom view class expose the contained table view as a .table property, and the container you're putting things in can be tweaked to use "mycontainerObject.tableview" instead of just "tableview" where needed.
Yes, it's a little more work to write the custom UIView subclass and give it a couple properties to hold the UITableView and whatever UIView you're animating out.. but it's likely a lot safer in the long run than trying to "hack" into the UITableView's methods and view hierarchy to try to give it a "fixed in place" behavior.

Resources