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!
Related
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.
So I'm trying to get a layout to work using Scroll View.
Correct me if I'm wrong but from what I've been reading around the internet, it looks like to properly use Scroll Views and make it work with AutoLayout you need to have your root view, then put the scroll view inside it with constraints binding it to take the whole size of the root view (left/right/top/bottom constraints to 0) and then adding a view inside the scroll view and once again binding it to take up the whole space.
Afterwards, any ui elements or subviews would go in the innermost view.
My problem is that often I have experienced issues while settings my constraints within the scroll view where for example setting a trailing constraint to 0 wouldn't actually set to the end and so on, the numbers just wouldn't add up. In this case when I'm trying to make the innermost view take the whole space,it ends up messing it up more than anything; see image below.
Any help would be appreciated.
I just created this layout using the follow:
To test it, I added an image view to the content view and put a humongous image in it. It scrolls around quite nicely including bounce etc.
Update: You need to select your ViewController and uptick "Adjust Scroll View Insets"
Hope this helps.
I don't know exactly why, but the scrollbar of my tableview never reaches the end.
This is the middle of the tableview, everything looks fine
But when I reach the end
The scrollbar doesn't reach the end...
I guess my constraints are ok (I'm using autolayout), because besides the scrollbar, the tableview is well displayed.
My view controller is a UIViewController and contains only a UITableView. Here is a screenshot that sums it up :
No constraint is added by code. Do you know how could I debug this?
Thanks in advance
Edit : I have tried to delete and recreate the view controller (by copy and pasting the UITableView) the problem is still here.
Edit2 : If I change the bottom constraint to "Bottom of the view" instead of "Bottom layout guide", this works well.
The problem is that my view doesn't have a correct height, because it is supposed to go under the tabbar.
Any ideas ?
I've fixed the problem by settings the property automaticallyAdjustsScrollViewInsets to NO.
More details could be found here:
https://stackoverflow.com/a/21302259/1295537
What could be happening is you have clipping disabled, and the frame for your tableView isn't the entire height of the view.
Or, you could have contentInsets set, which changes the size of the scroll indicator as well.
For those who the above solutions don't work, try this. It makes no sense tho, but it works (In my case I needed the UITableView to behind other views, so I just added a dummy view)
https://stackoverflow.com/a/23019724/1148910
Instead of using a normal View Controller and dragging in a tableview in a storyboard (which I assume you're doing), have you considered using a Table View Controller? You shouldn't have this problem in that case (I never have). You can easily embed the Table View Controller in the Tab Bar Controller.
Hope this helps!
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.
I'm using ECSlidingViewController. When the app starts, it opens a scroll view which is resized dynamically, since it contains both labels and a table view. Both the table and the scroll view containing it are resized.
Everything works as intended when the view is first loaded. However, if I open and close the menu view, or if I use it to go to any view which resizes itself, the resizing does not work. Instead, it displays the scroll view as if it has the height assigned to it in the storyboard.
I'm completely lost as to why this happens, and would greatly appreciate help. I can post code as well, of course, but I don't know what code might help, since I guess that the error is on ECSlidingViewController's part.
Are you using auto layout? If so, whenever something else happens that triggers the application of the constraints, all the frames will be reset to the values dictated by those constraints. Try turning off auto layout and see if that fixes it. Refer to your auto layout settings.
Alternatively, if you want to keep auto layout, I'd generally suggest changing the frames by programmatically changing the constant values of the constraints. But, I'm not familiar with ECSlidingViewController, so I don't know if that's a reasonable option in this particular case.