Above is an example of the layout of how my program should look.
The screen should have a simple header view up top and the remaining space below it is used to display other content.
This other content is basically 3 pages of stuff.
The parent scrollview should display one page at a time but can scroll left or right using paging to get to the other ones.
The problem is that each of these pages is going to have different heights. Also, by using paging in the parent view, vertical scrolling also gets paged so I think I have to assign a scrollview for each individual page, each with paging disabled.
This process is fairly annoying for autolayout because I have to manually calculate and overide intrinsicContentSize for every single view and make a custom method in viewcontrollers to return the height based on the intrinsic content sizes of its children and constraints used on them. I then need to use this height to constrain the widths and heights of the views so that the container scrollviews are able to calculate their contentsizes using autolayout.
I can get stuff to show up using a mess of container uiviews and uiscrollviews but the only scrollview that receives events is the parent scroll view. Why are the child scroll views not responding?
I had similar issues with nesting UIScrollViews. I found this video from WWDC 2010 (link below) that really helped me to understand how to work with child UIScrollViews inside a paging UIScrollView, and I managed to fix the bugs I had by following the steps in this video and looking at the sample code.
Designing Apps with Scroll Views (WWDC 2010)
PhotoScroller sample code
Note: The PhotoScroller code has been updated since the video was recorded to support ARC, storyboards and UIPageViewController. I would suggest taking a look at the sample code first, and if you're not sure how it all works then watch the video.
Hope this helps!
Related
Hello Mobile developers!
I'm creating an app and I'm not being able to make it scrollable. I've inserted a ScrollView and inside a vertical StackView with 3 Views.
I am new to swift and I'm not really sure what to provide for you to help me, se here's a couple of screenshots that may help.
Running app
View Structure
Some constraints
ScrollView details
Any other comments regarding the structure or good practices are welcome.
UPDATE: The app is now scrolling, but for some reason I'm not being able to scroll the whole way down. It seems like it's grabbing the full hight of the device as height of the scroll, even though the content I'm inserting is dynamic.
I have a video in the following link so you can have a visual reference:
https://drive.google.com/file/d/1UmE9NEVTxbK_rFPJarhfohPFb8XD8HcA/view?usp=sharing
I think the problem is that you haven't add View inside your scrollview and also uncheck "Content Layout Guides" in Size inspector section for your scrollView. That view is your main content View. So your hierarchy will be like ScrollView -> View -> and then your main Stack View. Don't forget to give your main content view any fixed height so it will work perfectly. You can also dynamically handle main content view Height constraint.
You can also take a quick guide from following answer which work perfectly fine.
https://stackoverflow.com/a/59047168/12969732
I hope it will helps. Let me know if you have any query.
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'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.
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.
Within the pageViewController:viewControllerAfterViewController: method, just before the return statement, the view which is about to be returned as the next page has the correct view frame size.
However immediately after the pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted: method is called, I check the frame size of the newly introduced view controller ([pageViewController2.viewControllers objectAtIndex:0];) and I find it resized.
Note that, I have set [self.pageViewController.view setAutoresizesSubviews:NO] and the autoresizing mask to None for the newly created ViewController.
Any ideas in which step the new ViewController is being resized?
I think the problem is inherently related to the nature of UIPageViewController. It is built from UIScrollView. I don't exactly know why there is strange resizing behavior, but it seems to be particularly pronounced when the view controllers that make up your pages use auto layout. Seemingly, locking the constraints in your page view controllers to the superview makes the elements resize after the transition because the superview is itself getting resized after said transition.
This sucks because Apple is basically pushing all of us to adopt auto layout. Auto layout is awesome, and I recommend everyone use it from now on, but it really really sucks when you use it with a UIPageViewController. They really ought to either scrap that class or build something easier for developers, something that can be dragged into a storyboard outright.
A few things to consider.
1.) Don't lock anything to the "Top Layout Guide" or the "Bottom Layout Guide". Also make sure you have "Constrain To Margins" disabled on any view intended to hug the sides of the screen.
2.) If you are using a label in your individual page / content view controllers, make sure you bind/constrain it to something other than the superview. I wanted to place a label over a UIImageView, so I aligned the label to the leading and top edges of the image view (using AutoLayout constraints only), creating an offset to give the label some margins.
3.) The following would otherwise be a good tutorial. However, it is a bit outdated. I downloaded the project and basically modified it to get a UIPageViewController implementation that works. The only problem with this project is that it doesn't use AutoLayout. I'm currently writing a blog post that more clearly discusses how to use UIPageViewController and Autolayout together.
http://www.appcoda.com/uipageviewcontroller-storyboard-tutorial/