Replicating ScrollView functionality in Passbook.app UI - ios

I'm trying to replicate the Passbook.app UI, and can't seem to figure out the basic structure of the interface.
When you just have one pass loaded, you can drag a pass up, and it snaps back in place. You can drag the pass down, and it snaps back in place.
I've created a UIScrollView and added a subview (representing a pass). I set the scrollView's contentSize to be greater than the device screen, but I don't get any snapping; the pass just scrolls off or on the screen. Anything less than the device screen and no scrolling occurs at all.
Any ideas how they are getting that effect? Possibly using multiple UIScrollViews?

Update: I've created a sample of how this can be achieved using UICollectionView, I hope it helps you to go in the right direction.
I've been digging into this. I used Reveal to explore the view hierarchy. Basically it uses a UIScrollView with many UIScrollViews inside each of them connected to a UIDynamicAnimator.
Look for the headers here.

Related

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.

How to pin an image/view inside a UIScrollView when scrolling

I've been searching for a way to pin views/images to the top of a UIScrollView when scrolling. However the posts/articles I came across are not in swift 3. I'm not sure if I'm typing my question in the web correctly. So my question is how can we achieve the same behavior as a UITableView or UICollectionView. When you scroll, a section will stick to the top until another section pushes it up. I'm wondering would we be able to use views/image and pin them at the top of the UIScrollView. Down below is a screenshot of a UIScrollView that has 4 views.
So when scrolling I would like to pin the first view/image to the top until another view/image pushes it. Also would it be possible to determine which view sticks to the top. So lets say I only want the red views to stick until another red view pushes it. Been looking for a way to achieve this type of behavior for a while now.
Please help, would really appreciate any help provided at this point. Thanks.
A few ways to do this, but you can use the scrollView delegate’s scrollViewDidScroll to capture the contentOffset and use a combination of the target view’s origin/center/transform properties to keep the view where you want it.
There’s a neat video explaining how to do this that Apple released during WWDC 2010, called something like “Advanced Scroll View Behavior”, if I remember correctly. It’s definitely worth a watch.

Custom Collection View Layout like Chanel app

I'm trying to do a custom layout like the Chanel app you can find the app in the Appstore.
https://itunes.apple.com/us/app/chanel-fashion/id409934435?mt=8
I know they are using an UICollectionView, but no clue how to start.
The interaction feels like a tableview mixed with a paginated scroll. When you scroll the elements grow, and the first element position itself at the top.
Start with dragging & positioning just one UIView. See UIGestureRecognizer docs and look for existing examples of movable views. You'll need an UIPanGestureRecognizer to move the view.
Resize the view depending on its Y position.
Create & position an image inside that view depending on the view size using a couple autolayout constraints.
Note that Chanel app has different constants for these constraints. With a minimum view height, one image's top is 80% height, for another image it's 90% height. Make sure you can manipulate constraints from code (I think it's a good idea to create everything from code there, XIBs are not very flexible).
Make the view "anchoring" to certain points (e.g. top = -75%, 0%, 75%, 90% from what I see in the Chanel app) when you stop moving it. Just find the nearest one and animate the view to it.
Once you did it with 1 view, move all your work to an NSView subclass (if it's not yet there) and create a collection of these views.
You can create UICollectionView, but I'd rather do it with a simple NSArray: I actually don't see a reason to use UICollectionView here; it's a very simple structure. Anyway, you write your own gesture recognizer (don't you? I can't see another way) - so what's the point to use UICollectionView? If you want to expand the app functionality some day, UICollectionView will unlikely help you with that. Well, it's my hypothetical approach, you can find another one while working on that.
Position other views while you're moving an "active" view. Do it by hand, without any UIScrollViews.
Write a function that reflects the Y position of the "neighbor" views while you moving one. It should "slow down" to the bottom of screen.

Embedded scrollview in tabbar item using storyboards won't scroll

For my current project I wanted to use storyboards and autolayout instead of coding everything by hand. It has gone well so far, but my design has a section of the app where there is a tab bar and one of those tab needs to show four views. The design is to swipe between the four and so I thought to use a scroll view. After some trial and error I found that embedding a Container View in the tab allowed me to easily set up a scroll view and put a couple of view inside it, carefully aligning them using positioning to put them side by side so that each page is one child view. I'm not sure how that plays with the autolayout, and in fact I have the problem that the scroll view won't scroll past the first page position. I can drag about 1/3 of the second page into view, but it never brings that page entirely in view.
I've checked the content size and offset and all of the view positions and it all seems correct. And when I use Spark Inspector to change the scroll offset to the position of the second view/page, the app shows the right page/view and I can even scroll back to the first page. I'm a bit perplexed as to what is causing it to not scroll properly. I don't have any code to show as this is all done in storyboards, but I am wondering if anyone has any ideas as to what is wrong?
Alternately, does anyone have an idea for how to use autolayout and storyboards to set up swiping four adjacent views in a tab? I suspect there are ways to do it. I can think of ways to do it in code, but I'm trying to avoid doing it that way.
EDIT: I set the scroll view delegate to the view controller around it and checked the values of contentSize on scrollViewWillBeginDragging and scrollViewDidScroll. It is always set to {0,0} even after I force set it on viewDidLoad. So I tried setting it every time scrollViewWillBeginDragging is called, which seems work, but I don't understand why this happens and it doesn't smell right. Is there some autolayout constraint that might account for this? Does something cause contentSize get set to {0,0} during the layout process?
For lack of any other answer, I'll use my unsatisfying solution as an answer in the hopes that helps someone else in the future:
I set the scroll view delegate to the view controller around it and checked the values of contentSize on scrollViewWillBeginDragging and scrollViewDidScroll. It is always set to {0,0} even after I force set it on viewDidLoad. So I tried setting it every time scrollViewWillBeginDragging is called, which seems to work.
I'd love to know why the contentSize is being reset if anyone finds out!

Fluid full screen view transitions on iOS

I have a simple app that has a set of coloured views, one red, one green and one blue.
I am trying to make it so that when a swipe gesture is made the current view will switch to the next one in the list in a fluid manner, it looks like moving a long piece of paper with different colours on it.
Is there a way to do this (CoreAnimation)?
You could first look into UIScrollView. It seems to me that what you are trying to accomplish is the same you have, say, in Mobile Safari on an iPhone, when you show all your current pages and can go from one to the next by scrolling. This tutorial is particularly close to what you describe.
If you are looking into more advanced kind of transformations, than Core Animation would be the option.
Actually, nothing prevents using both approaches, UIScrollView to handle the swipe, Core Animation to add more animation to the pack...
You could use a UIScrollView to accomplish this. Add all of your colored views as subviews to the scroll view. Make sure your contentSize is setup appropriately and optionally setup paging to make the scrolling always snap to a certain border. See the scroll view programming guide for more info Scroll View Programming Guide

Resources