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.
Related
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.
I am building an app about meetings where I want to show a preview of the VIP participants in each meeting cell.
These participants are not clickable nor scrollable, the only purpose it's to quickly see them at a glance.
The problem is that the view is very dynamic:
VIP's appear with image or initials
The rest of the attendees is just a number
if >5 VIP's, the circles start going together overlapping (spacing goes smaller)
if 9 VIPs, big wrapping circle “All VIPs in Attendance"
This is how it will look:
What should I do?
CollectionView (seems over-kill as I am not interested in any kind of interaction with the images)?
StackView?
Images (and change constrains programmatically)?
NOTE:
These is just one kind of Table View Cell, but we have a lot more variations, so we are building the custom cells in xib files. Xcode doesn't allow me to add a Collection View Cell in to the Collection View within the xib.
Interesting task - I'm sure there are numerous approaches, but here is one using UIStackView plus some on-the-fly calculations.
The idea is to define a maximum gap between views; a maximum width for all views; calculate the actual gap needed, and then let UIStackview handle the actual positioning.
Certainly not every feature you need, but should get you going in the right direction.
You can see/download the source for this here: https://github.com/DonMag/ScratchPad
Look at the Swift3/SpreadingViews sub-project for this example.
The problem with scrollable views (UIScrollView based views as UICollectionView), is that you will have to deal with the scroll, or pre-compute the width of your content, which is not always easy. For this reason, if you don't want to have scrollable content, I'd not use a UICollectionView, neither any UIScrollView based view.
Then you have the option to go with an UIStackView. Stack views are great to "append" multiple views and create some kind of "pile" of views in a very easy way. However, if you don't control how many items you need, you will overpass the boundaries of your container view.
Therefore, this is what I'd do:
"Fixed container view width" case: If your container view (your cell) has a fixed width (that never changes), I'd manually add as many UIImageViews I want to support in the XIB itself, and then hide/unhide them depending on the number of items I want to display.
"Variable container view width" case: If your container view (your cell) has a variable width (that changes depending on the screen size or whatever other factor), then you will have to compute in any case (do the math!) the amount of items you are able to display within the width you have available. Then, you can choose between using an UIStackView or adding your views & constraints manually to your container view.
Does what I say make sense?
Thanks,
I have a UICollectionViewController setup. It shows something kind of like a gantt chart, with selectable bars, scrolling, etc. I want to have a "trash/delete" button that always floats in the bottom right of the screen, regardless of scroll. It will delete the current selection (if there's one) in the UICollectionView.
I see two basic approaches:
Use the Supplementary Views facility of my UICollectionView. What I dread about this, is that I'll have to muck with its layout in my layout (I'm using my own subclass of UICollectionViewLayout) to keep it positioned in the bottom right corner, regardless of scroll.
Just add a UIButton to the canvas and set it up there. Maybe this isn't even a real approach, because this is what I wanted to do. While my button may manipulate items found in the UICollectionView, it's not really a real member of the collection view. But I found when I tried to drag a UIButton onto my Controller in the storyboard, it wouldn't stick. It doesn't seem to want to add it. Do I have to change to use a UISingleViewController, and then have a top level view that I can add both my button and collection view into? And then repeat all of the handy delegate/property setup that I get for free from UICollectionViewController?
You:
drag a button on to the view
in storyboard/xib.
Then, in the hierarchy column on the left, ensure it is at the bottom. That means it will be in front of everything else.
So, if necessary move it so it is in front of (ie, below in hierarchy) the collection view.
Note that there is absolutely no problem, at all, with putting one control "in front of" the other (i.e., so that it "blocks" you from seeing all or part of the other one).
If you had a problem doing this, you've made a trivial mistake. For example you may have dragged the new button "into" the collection view, rather than as a "sibling of" the collection view. Hope it helps.
I am trying to create an iOS UI where I have a set of subviews arranged as a grid on the UI and on clicking any of them I would like to expand this subview to a larger size. I am able to do the animation to expand this subview but I would also like this functionality such that other subviews nearby are pushed away.
On dimissing, this expanded view it should contract to the original size and bring back the other views to its original location.
I am thinking of a variety of ways to implement this but there are many use cases, and hence I would like some pointers in the right direction?
Does iOS itself provide a functionality by which expanding a sibling view contracts/moves the neighboring one? If not, what other ways are there to implement this?
Toms
How do I build a freely scrollable view on iOS 5? I mean, I need to build a view which can scroll from left-right and top-down (any direction) and it will stay there. Inside this view, I need to place different kinds of objects.
(Imagine scrolling like a map. - I am using Storyboard.)
Yeah, UIScrollView.
And don't forget to set the content size !! (every noobs - including me - are always asking the same question, why my scrollView does not work?)
=> [scrollView setContentSize:CGSizeMake(1000, 2000)], for example.
EDIT :
I just saw your comment. I don't understand what you call "on top".
I made an app with custom maps, and I used an UIScrollView to make the job: it was pretty good at it.
You just have to add each scrollable element as subviews of your UIScrollView. And set the contentSize to fit to the subviews' frames, of course.