Collection view flickers when page sheet viewcontroller size changes - ios

I have a problem with the screen presented modally.
At some point of scroll offset, whenever I change the screen size, the scroll offset flickers with some cells being re-layout, but the delegate is not asked for the new cells at this time.
I hope that the below GIF illustrates it's quite good.
I guess it's due to a change in the collection view height, which Geoff Hackworth showed here.
I'll be glad for any suggestions.
Probably it is worth noticing that I use Compositional Layout and DiffableDataSource.
EDIT:
I've decided to check how the code sample from Implementing Modern Collection Views will work, when the screen will be presented modally. The result is the same.
It seems that this is a bug in UIKit. When the NSCollectionLayoutSize height is estimated, not absolute it forces the layout to calculate the view size, probably based on preferredLayoutAttributesFitting(layoutAttributes:). On change of the view container height, the view is asked to be layout again. At the beginning of the layout loop, UICollectionViewCompositionalLayout returns estimated, not the actual size of the views, which causes reusable views (both supplementary and cells) to jump across the screen. The overall result looks really weird.
Here it is:

Related

iOS: Programmatically capture screenshot of view larger than screen

I would like to take a screenshot of an entire UICollectionView (or at least the "top 10" cells). The view doesn't fit on screen.
How do I programmatically capture a snapshot of a view larger than the iPhone's screen?
The problem of capturing a scroll view's content including the offscreen part has been tackled here many times before, so please, search before asking. (See for example: Getting a screenshot of a UIScrollView, including offscreen parts)
But even that won't help you here, because in particular, a collection view's cells that are not shown on the screen do not even exist; that is what cell reuse is about. So there is in fact nothing in existence to take a screen shot of. The cells you can see are the only cells there are.
To put it another way; the collection view does fit on the screen. What's on the screen is the collection view. There isn't any more of it.
You could perhaps construct in code a drawing that looks somewhat like your collection view, but it could be quite a bit of work.

How to correctly animate change of size of a paged UICollectionView

I have an iPad app similar to the iPad Keynote with a narrow overview on the left and a paged UICollectionView of my "slides" on the right. The collection view is using the default FlowLayout. Some of these slides are standard PDFs and some are embedded UIViewControllers that have been scaled (with a CGAffineTransform) and embedded in the cell. I'd like to smoothly animate the overview sidebar offscreen and zoom the current page cell to fullscreen. The collection view should allow paged swiping at whatever size. I'm using storyboards and autolayout.
I think I need to simultaneously animate about three things:
The collection view constraints (to the sidebar) to enlarge/shrink it
The flow layout's sizeForItemAt: value
The CGAffineTransform on the embedded view controller.
I have some pieces working (a single embedded View Controller "slide" that scales correctly) but cannot get the collectionView/cell resize dance to work correctly. The cell resize animation is jerky, or ends up with the wrong offset, or works for the leftmost cell but not for other cells.
I've tried most of the suggestions in the answers to this question but with no convincing success. I can't believe it's impossible but at this point I'm considering the smoke and mirrors approach of animating a static slide and hiding it after the animation completes. The attached video - ignoring the glitches - illustrates the kind of effect I'm after:
It's worth noting, on close inspection, that Keynote cheats somewhat when it comes to swiping between slides in edit mode, and manually manages the next slide sliding onscreen, so probably doesn't use a UICollectionView.
Has anyone done anything similar, or have any suggestions for things to try?
I managed to solve this. There's a proof-of-concept GitHub repo here.
There are a few moving parts:
There are two pieces of UIView scaling code. I suspect these could be combined with suitable delegate references as the nested view controllers are embedded. The first piece scales (statically) correctly when the Collection View cell is created. The second is an animated scale/translate when the sidebar size is changed.
I added a FlowLayout subclass to remove flicker as the collection's layout is invalidated during scaling.
The sidebar-related transform in the top-level VC uses most of the tricks in the book - invalidateLayout(), performBatchUpdates(...), layoutIfNeeded() etc. as well as animating the contentOffset to the correct value. Some manual tracking of the correct page/slide is required.
There's still a slight flicker occasionally at the start of resizing. This may not be an issue with my particular colour-scheme which will be black on dark gray. Bonus points if anyone can suggest how to track this down or alleviate it.

Xcode embed all direct in scrollview without content view

I'm using Xcode 6.4 and I'm struggling with a large page with a bunch of various labels and text fields etc., that has to be scrollable. I looked at various tutorials some of which are obviously outdated and I had all my elements at first in a view that is inside of a scroll view. But that was a big pain with getting all the elements aligned properly using Auto Layout, in addition to not getting it to scroll either.
Now I see one person recommend using the following directly on the elements, without having a content view at all just a scroll view:
Editor -> Embed In -> Scroll View
I like it for the fact that nothing seems out of proportion, all the elements are shown on the iPhone exactly as I have it on the Storyboard without having to set any constraints, however I'm not able to get it to scroll.
This is my class
class ResNotFoundViewController: UIViewController, UIScrollViewDelegate
and I also try to set the height of the scrollview in the code as so:
#IBOutlet weak var scrollviewoutlet: UIScrollView!
and then this in the viewDidLoad as so:
scrollviewoutlet.contentSize = CGSizeMake(375, 840)
.
But I'm not able to get it to scroll at all, it will stay exactly like it opens up with From: Label being the last visible elements.
What am I doing wrong?
You've located the problem, thanks to your logging. (Don't worry about the double call - how many times and when viewDidLayoutSubviews gets called is uninteresting.)
The problem is that you've set the scroll view itself to be taller than the window. In particular, it is 375x809. But so is its contentSize. Thus there is nothing to scroll. A scroll view can only scroll if its contentSize is bigger (in one or two dimensions) than the scroll view. (Moreover, a scroll view bigger than the screen is usually somewhat pointless, since there will be parts of its content that the user will never see - even scrolled all the way, that content will be offscreen.)
So, fix the size of the scroll view itself and you'll be fine. The best way is to assign it constraints that pin its boundaries to its superview, since the superview will have different sizes on different devices.

UIScrollView Odd Scrolling

Im getting this very odd behaviour with my scroll view. Its a paging scroll view set up in iOS 8 using auto layout. The screen so far is very simple, just some labels and a scroll view. There are three pages.
The set up is a 'container view' in which a scroll view sits. The scroll view contains a content view which gets it size from the container and its width is 3 times the size of the container view, giving a scroll view with 3 pages of content the size of the container view.
Bounce is off, paging is on.
The scrolling doesn't seem "choppy" - I've experienced this with UITableView before and I know what scrolling looks like when the phone is struggling to produce a good frame rate, I don't think its like that.
Its almost like the whole scroll view is stuck in treacle. Or as if someone added some UIDynamics or some kind of spring behaviour to the scroll view at the ends of the scrolling as its about to page its unusually slow, no matter the intensity of 'flick' to scroll.
Ive attached a video to show you what I mean. Ive reproduced this on all devices on the simulator and on the iP6+/iP5s devices.
Video: http://tinypic.com/player.php?v=v5jy4p%3E&s=8#.VJljyr0CkA
Is that scrolling abnormal? What do you think the problem is?
The problem was that I was using a Freeform UIViewController of 1800 x 600 - so I could layout my content in interface builder (3 pages). Reverting back to 600 x 600 restores the normal scrolling. I don't know why this should happen since the whole point of autolayout is to not be affected to these changes in size and my view controller is totally adaptive...but there we are.
This is the approach I'm using: UIScrollView Paging Autolayout & Storyboard - its very useful, but be aware to restore your view controllers to a reasonable size before you compile otherwise you get odd scrolling!

UICollectionView not able to scroll to see the entire last row

I have a UICollectionView with size: 768x1024 with a navbar on top. My custom UICollectionViewCells are of size 200x200. The problem is that when I keep adding cells and I reach the bottom row, I can only see part of the 200x200 cell. It won't let me scroll further before it bounces back up. Any ideas on what the problem could be?
EDIT:
I add cells via:
insertItemsAtIndexPaths:
The issue was just adding AutoLayout constraints to the View Controller which housed the UICollectionView. To do this, select the View Controller in Storyboards and click on "Editor" on the top. Then, "Resolve Autolayout Issues" > "Reset to Suggested Constraints..."
Check whether you have changed the minimum spacing attribute of collection view in size inspector of collection view. Setting it back to default values(10) was the solution for me.
The problem has to do with your UICollectionViewLayout, since it is the job of the layout to state how large the actual scrollable content is, and to ask for a refresh of that information when necessary. But unfortunately your question reveals nothing about how you are doing layout or how you "keep adding cells", so no specific answer is possible.
EDIT (after your edit): It is not enough to call insertItemsAtIndexPaths:; you must also add the items to your model (the data source). Otherwise, the layout doesn't know about them and doesn't make the scrollable content bigger (and lots of other bad things happen too).
i think you use the collection view in an unsual way, but if the content area of the scrollview of the collection view extend the frame size of the collection view you have to set the virtual size with the property 'contentSize' :
self.collectionView.contentSize = CGSizeMake(768,900);
I had a similar problem but due a gradient that it was at the bottom of the collection view and the user was not able to see the last rows of the collection view.
The way I've found to solve it is in the Size Inspector, set the Height of the Footer Size to a number that works for issue.
I know that maybe, it's not the best solution. But it works for my problem and it's really easy to use it.
Collection View that doesn't show the last row:
Collection View after setting the Footer Size Height to 40:

Resources