I have a view that is placed outside the screens bounds (beneath). When a button is pushed this view is animated up, so that it becomes visible. It sort of acts like a keyboard, although it isnĀ“t.
Inside this view I have a container view which is hooked up to a UICollectionViewController.
The problems occurs when I scroll its collectionView. As soon as cellForRowAtIndexPath is called, the entire super view is moved outside the screen again (without animation). If I push the button again it animates back up.
Does anyone know what is causing this behavior? I suspect that the frames of the reused cells are sort of pushing the super view back to where it was initialized. Any suggestions how I should resolve this?
When using autolayout, you should animate using constraints. I had this same issue before. Maybe viewDidLayoutSubviews is called multiple times while you are using the app, and hides your view again.
Related
So, I've got an UITableView with a Custom Cell
and this is my View Hierarchy:
So, the last view on the top is part of the Custom Cell.
Now I scroll (just touch up, or scroll a little bit), and I get this new View Hierarchy:
I'm getting a last UIView which is not letting me scroll anymore.
Any clue of what is it?
Thank you very much.
Ok, solved.
It was because of it was an instance of MMDrawerController.
I'm creating my views programmatically. I have a UITableView in my UIViewController subclass that I want to add a scrolling subview to that is not a cell. I want to add some text-based subview to the UITableView that scrolls with the table and starts out above y=0 so the user will only see it if he pushes the table down. That is, it should reside above the first section of my table. If it helps for visualization, I intend to make something similar to those "scroll down to refresh" features and want some indication to the user that scrolling down causes a refresh. Is there any way to do this without something messy like using another UITableViewCell to represent it or abusing the UITableView delegate methods to move a view around whenever the user scrolls?
Simply using [tableView addSubview:] in my viewWillLoad only makes it appear for a split-second then disappear once the table data is loaded. This seems weird to me because UITableView is a subclass of UIScrollView, which is meant to hold other views in it. Using [tableView.backgroundView addSubview] does nothing.
P.S. Why not use a UIRefreshControl for this? I'm still undecided but leaning towards not using one because I don't like how slow that spinning wheel "feels" when the refreshes are usually very very quick. I've been looking at other options like flashing the background subtly and only showing a wheel if it's taking a longer time than usual.
I You can implement pull to refresh with only a table view
To do this using the scroll view delegate, since tableview is a subclass of scroll view.
Set view controller to be the tableview delegate and implement
(void)scrollViewDidScroll:(UIScrollView *)scrollView
When scrollview content offset y value passed a point, add a label to the viewcontroller.view not tableview. When you scroll back or release, remove the view.
You might also be able to add label to the table view and set the frame origin to negative y value, so when you pull the label will move into view (Never tested this do might not work)
I have a UIScrollView and another UIView (view2) inside it. 'view2' scrolls fine when app launches. But, whenever I show and dismisses another VC (a UIImagePickerControler in this case) scrollView becomes non scrollable.
I have set the content size at viewDidAppear , so this must be something related to AutoLayout constraints. I've tested with all the constraints removed but still getting the same result.
Any idea why is this happening?
Not a complete answer, but make sure your viewDidAppear: method doesn't assume it's only called once. It will be called again when the second view controller is dismissed.
Here is the problem that I'm facing. I have UITableView inside main view. When user taps menu button, view is added to the view hierarchy of superview, and this view covers all screen, except the menu button. That is I call
[self.view insertSubview:self._menuView belowSubview:self._menuButton]
After user clicks the menu button again I call
[self._menuView removeFromSuperview]
However, after this, the UITableView stops scrolling, actually it scrolls, but just a little, couple of pixels, and then bounces back to the location on which it was before I inserted _menuView. I've monitored the menu hierarchy after inserting and removing the _menuView, it is actually removed, and also there is no view which covers the UITableVIew, so there is no chance that some other view steals touches from UITableView. What can be the problem? Any ideas?
EDIT 1: I've noticed besides not being able to scroll, another strange thing happens. When I show menuView, the tableView is scrolled to top, without animation. (the menuView is half opaque only, so I can see the tableView underneath it)
EDIT 2: I've monitored contentSize and contentOffset of tableView before and after inserting _menuView, the reason for not being able to scroll is that somehow contentSize is being changed.
TABLE VIEW BEFORE INSERTING MENU - contentSize:{Width=320, Height=10519} contentOffset:{X=0, Y=3980}
TABLE VIEW AFTER INSERTING MENU - contentSize:{Width=320, Height=44} contentOffset:{X=0, Y=0}
As You can see, the height is changed to 44 that's why I'm not able to scroll. And Also, as I've said in EDIT 1: tableView is scrolled to top - so as you can see contentOffset is also zeroed. Any ideas why content size changes automatically?
Thanks in advance.
i think there is problem with your tableview frame. right after removing subview, try to set frame of your tableview at its original frame.may this will solve your problem
Content in the UITableView organized automaically and designed only to show cells & header/footer elements. To proper working you should wrap your table into parentView and add your menu to that parentView rather than to the UITableView. You can also try to call reloadData method on table since it can restore the content size of the view.
My UITableView has a bunch of reusable cells, and when I tap on one of them, it takes me to another view controller (via push segue) showing the details of that cell (let's say it's an item, so it would show details about an item - name, price, image, etc...). When I pop that view controller (by tapping on the back button), the UITableView has a strange behavior:
a) if it's scrolled all the way to the bottom, it will scroll automatically tad up (around 50 points), leaving the last cell barely visible, so I have to scroll back down again. My cell all have 60 points for height.
b) the scrollbar always shows and then disappears, indicating that something is moving that UITableView (although if not scrolled to the bottom, the content will not move automatically).
This happens in multiple UITableView's I have in my app. I am not forcing a reload of the table view in viewWillAppear, so I don't understand what is happening. My content is static after loading from the server (unless the user changes it, and then the reload is executed). But simply showing details of an item and popping that VC doesn't change anything in the table view.
Edit: Okay, I've figured what the problem is: I'm hiding a UIToolbar when pushing that segue. If I keep it always visible (which I don't want), it still shows the scrollbars animating when popping in my table view but doesn't scroll the table view if on the last few rows.
Add the following to viewDidLoad.
self.automaticallyAdjustsScrollViewInsets = NO;
This solved my problem of table view moving down after navigating back to view controller.
I managed to fix the first issue. It seems like the tableview is not taking into account the 44 points of the UIToolbar.
Save the tableview offset in prepareForSegue: (save it in a CGPoint property)
self.tableViewScrollOffset = self.tableView.contentOffset;
Then, in viewWillAppear:, check if it has been modified. If so, restore it.
if(self.tableView.contentOffset.y != self.tableViewScrollOffset.y) {
[self.tableView setContentOffset:self.tableViewScrollOffset];
self.tableViewScrollOffset = CGPointZero;
}
This behavior is indeed a bug in iOS 8.x.
All answers given so far can not really solve the issue. The issue is, that iOS forgets (or doesn't) consider the previously calculated cell sizes, when a table is being redrawn for instance when the view is being pushed.
One approach to solve this can be found here: UITableView layout messing up on push segue and return. (iOS 8, Xcode beta 5, Swift) (so this question is even a duplicate to this one).
However, the solution provided there is overkill and there are certain situations why this caching will fail (for instance a UIContentSizeCategoryDidChangeNotification is not regarded)
But there is a quite simpler solution even though it is odd:
If you are using a manual performSequeWithIdentifier in didSelectRowAtIndexPath, just add a [self.tableView reloadData] just before.
If you are using a IB seque from the cell, just add [self.tableView reloadData] in your prepareForSeque code.
The reason, why this solves the issue is, that this will force iOS to re-estimate the visible cells and so it no longer scrolls the content to another location. Fortunately, tableView reloadData doesn't cost too much overhead here as only the visible cells will be re-estimated.
Just a hunch, have you got a rogue scrollToRowAtIndexPath:atScrollPosition:animated hanging around?
I was also facing this issue. I managed to find it out. The reason in my case is tableview header height was calculating based text and text height was negative due to which tableview was shifting down even though the contentinset and scrollinset are zero.
This was only occurring for first time. Next time it is calculating correct. One weired thing i found is that when Class A (having tableview) have pushed another Class B from init. When keyboard from Class B is opened viewDidLoad of Class A is called. and before Class B is unloaded from navigation controller. Tableview is reloaded for Class A.
Setting the automaticallyAdjustsScrollViewInsets as suggested above did not work neither did caching and setting the tableViewScrollOffset work.
Hence came up with an workaround which worked like a charm for me.
The workaround was to add an Dummy UIView which has height of 1px and width of 320px and place it between the "Top Layout Guide" and the UITableView. This view's background could be set to clear so that it is invisible.
Now using Autolayouts, fix the Dummy View's top to the Top. Now set the tableview's top constraint with respect to Dummy View. Found that this resolved the issue of the tableview's misplacement.
Screenshot of the Dummy View along with the autolayout constraints have been provided for easy reference. The Dummy View has been set to a larger height and red background colour for illustration purpose only.