The ScrollViewController class has been around for a while—and it’s a great way to turn any UIViewController into a scrollable UIScrollView. Unfortunately, its implementation is pretty verbose, and requires a lot of setup. This Swift library aims to simplify things: it wraps the standard implementation, making it easier to add scrolling functionality to any UIViewController.
One of the most common features that mobile app developers want to add to their applications is the ability to scroll a view. This is a feature that Apple put into iOS quite a long time ago with the UIScrollView class. For a long time, this was the only option you had for scrolling a view, but now there is a new Swift library that was created to simplify the process of adding scrollable views to your applications. This library is called, appropriately enough, ScrollView.
Sometimes, you will want to scroll a UIViewController’s view independently of the scrolling of the rest of the UIScrollView. This can be done by making the UIViewController’s view an independent scrolling view. An example of this would be a map, where you want the map to scroll independently of the rest of the view, which would remain stable while the user is looking at the map. Goals for a Blog Post
Scrolling content view controller
With the ScrollingContentViewController, you can easily create a view controller with a single scrolling content display or convert an existing static view controller to a scrolling view controller. Most importantly, it fixes some undocumented issues with the keyboard, navigation controls, and device rotation.
Background
A common task of UIKit Auto-Layout is to create a view controller with a fixed layout that is too large for older, smaller or landscape devices, or an area of the screen that remains visible when a keyboard is displayed. The problem is exacerbated when Dynamic Type is used to support large fonts. For example, consider this signature screen that works for the iPhone Xs, but not for the iPhone SE with keyboard: This case can be handled by nesting the view in the scrolling view. You can do this manually in Interface Builder, as described in the Apple Working with Scroll Views documentation, but it requires many steps. If your view contains text fields, you must write code to adjust the view to compensate for the keyboard that is displayed, as described in Keyboard Management. However, reliable keyboard control is surprisingly difficult, especially if your application has a sequence of keyboard screens in the context of a navigation controller, or if support for device orientation is required. To simplify this task, the ScrollingContentViewController adds a scrolling view to the view hierarchy at runtime, along with all necessary automatic layout constraints. When the ScrollingContentViewController is used in a storyboard, it provides an output called contentView that you connect to the view you want to make scrollable. This can be the root view of the view controller or a nested view. Everything else happens automatically, including responding to the keyboard display and changing the position of the device. The ScrollingContentViewController can be configured using storyboards or completely in code. The easiest way to do this is to subclass the ScrollingContentViewController class instead of the UIViewController. However, if this is not possible, a helper class ScrollingContentViewManager can be used instead, which can be compiled with an existing view controller class.
Setting
The ScrollingContentViewController can be added as a dependency of the Swift package in Xcode. To install the ScrollingContentViewController with CocoaPods, add this line to your podfile: pod ‘ScrollingContentViewController To install it with Carthage, add it to your cart file: github drewolbrich/ScrollingContentViewController
Use
The subclasses of ScrollingContentViewController can be configured via storyboards or in the code. This library can be used without subclasses by creating a ScrollingContentViewManager helper class. See use without subdivision.
Storyteller
How to configure the ScrollingContentViewController in the storyboard :
- Create a subclass ScrollingContentViewController and add a new view controller with this class in the Interface Builder. Or, if you have an existing view controller that is a subclass of UIViewController, change your view controller to a subclass of ScrollingContentViewController.
Importing ScrollingContentViewController MyViewController class: ScrollingContentViewController { // … }
- In the Interface Builder’s Outline view, click a view controller and connect its contentView output to the view controller’s root view or to another nested view that you want to make scrollable.
- If your view controller defines a viewDidLoad method, call super.viewDidLoad if you haven’t already.
override func viewDidLoad() { super.viewDidLoad() // … }
- At runtime, the ContentViewController property of the ScrollingContentViewController now refers to the supervisor of the controls you placed in the interface generator. This top view is no longer referred to by the view property, which instead refers to the empty base view behind the scrolling content pane. If necessary, modify your code to reflect this change.
Your content view will now scroll, provided you have ensured that the content view’s auto-partitioning constraints are sufficiently precise and that the content view’s size is larger than the safe area.
Code
How to integrate the ScrollingContentViewController programmatically:
- Subclass of ScrollingContentViewController instead of UIViewController.
Importing ScrollingContentViewController MyViewController class: ScrollingContentViewController { // … }
- In the viewDidLoad method of your view controller, assign a new view to the contentView property. Add all controls to this view instead of pointing to the view property, so they can navigate freely. The view controller’s root view, referenced by its view property, now acts as the background view behind the scrolling content view.
override func viewDidLoad() { super.viewDidLoad() contentView = UIView() // Add all controls to the ContentView instead of the View. // … } You can also assign ContentView to a sub-view of the root view of your view controller, in which case only that sub-view will be made scrollable.
Reserves
Considerations for vehicle classification
For the ScrollingContentViewController to determine the height of the scrolling content, the content view must contain a continuous set of constraints and views extending from the top of the content view to its bottom. This also applies to the width of the content display. This corresponds to the procedure described in the Apple documentation Working with Scroll Views. If you do not set enough automatic formatting constraints, the ScrollingContentViewController cannot determine the size of your content display and it will not scroll as expected. If you want the content pane to be stretched to use the entire visible area of the browse window, relax the restrictions to allow this. Change z. For example, in the Interface Builder, set the Relationship property of one of your height constraints to Greater than or Equal to. To determine the size of the content of the scrolling view, the ScrollingContentViewController creates width and height constraints whose ratio is greater than or equal to the width and height of the safe area of the scrolling view. The priority of these restrictions is 500. So, if you create a continuous set of constraints with the priority defaultHigh (750) or required (1000), they will override the internal minimum width and height constraints of the ScrollingContentViewController, and your content display will not be stretched to fill the safe area of the scrolling display. If your view controller is intentionally very limited in size (for example, it consists only of constraints with the required priority and no constraints on the greaterThanOrEqual ratio), you may see automatic layout constraint errors in Interface Builder if the constraints do not match the size of the simulated view, for example. B. when switching from one simulated device size to another. The easiest way to solve this problem is to lower the priority of one of your constraints. A value of 240 is a good choice because it is lower than the default priority for content coverage (250) and therefore avoids undesirable behavior where text boxes and labels are stretched vertically without height restrictions.
Internal volume measure
If you prefer not to use automatic splitting, the size of the content display can be set with intrinsicContentSize instead of constraints. The default priority of the UIView content handle is defaultLow. Therefore, the internal size of the content view is usually overridden by the minimum size constraints assigned by the ScrollingContentViewController. If you want intrinsicContentSize to override these restrictions, set the content coverage priority in the content view to required.
Change background colour
The content display is placed in a protected scroll area. Therefore, the background color of the content view does not reach below the status bar, the main view, the navigation bar, or the toolbar. To set a background color that extends to the edges of the screen :
- Set the background color of the root view of the view controller to the desired color. This view will be visible behind the scroll view, which is transparent.
- Set the background color of the content view to zero, so that it is also transparent.
For example: view.backgroundColor = UIColor(red : 1, green : 0.949, blue : 0.788, alpha : 1) contentView.backgroundColor = null
Change the size of the content display
If you make changes to the content view that change its size, you must call the scrolling view’s setNeedsLayout method, otherwise the scrolling view’s content size will not update to reflect the size change and your view might not scroll correctly. For example, after updating the NSLayoutConstraint.constant properties of a view, you can animate the changes as follows: UIView.animate(withDuration : 0.5, delay : 0, usingSpringWithDamping : 1, initialSpringVelocity : 0, options : [], animations: { self.scrollView.setNeedsLayout() self.scrollView.layoutIfNeed() }, completion: nil)
Oversized control
In the Interface Builder, you can design a view controller that is intentionally larger than the screen height. To do this, change the simulated size of the view controller in Freeform and adjust the height. When used with the ScrollingContentViewController, the display controller’s oversized content view will scroll freely if constraints require it to be larger than the screen.
Use without sub-classification
If the ScrollingContentViewController subclass is not an option, you can instead use the ScrollingContentViewManager helper class assembled with your view controller: Importing ScrollingContentViewController MyViewController class: UIViewController { lazy var scrollingContentViewManager = ScrollingContentViewManager(hostViewController : self) @IBOutlet weak var contentView: UIView! override loadView() { // Load all controls and connect all outputs defined in the interface generator. super.loadView() scrollingContentViewManager.loadView(forContentView : contentView) } override func viewDidLoad() { super.viewDidLoad() // When ScrollingContentViewManager.contentView is first assigned, it has the side effect // of adding a scrolling view to a supervised content view and // of adding a content view to a scrolling view. scrollingContentViewManager.contentView = contentView // Set the background color of the content view to transparent, so that the main view is visible behind it //. contentView.backgroundColor = nil } // Message: This method is not mandatory, but will give a warning if the content size of the view is undefined. override func viewWillAppear(_ animated : Bool) { super.viewWillAppear(animated) scrollingContentViewManager.viewWillAppear(animated) } // Message: This is only necessary in applications that support changes in device alignment. override func viewWillTransition(up to : size : CGSize, with coordinator : UIViewControllerTransitionCoordinator) { super.viewWillTransition(up to : size, with : coordinator) scrollingContentViewManager.viewWillTransition(to: size, with: coordinator) } // Message: This is only needed in applications with navigation controllers used to push // sequences of view controllers with text fields that become the first // responder in `viewWillAppear`. override func viewSafeAreaInsetsDidChange() { super.viewSafeAreaInsetsDidChange() scrollingContentViewManager.viewSafeAreaInsetsDidChange() } } The ScrollingContentViewManager class supports the same properties and methods as ScrollingContentViewController. ScrollingContentViewManager can also be used to programmatically create a scrolling view controller: Importing ScrollingContentViewController MyViewController class: UIViewController { lazy var scrollingContentViewManager = ScrollingContentViewManager(hostViewController : self) let contentView = UIView() override func viewDidLoad() { super.viewDidLoad() // Fill in the content representation here. // … // When ScrollingContentViewManager.contentView is first assigned, it has the side effect // of adding a scrolling view to the view controller root view and // of adding a content view to the scrolling view. scrollingContentViewManager.contentView = contentView } // Message: This method is not mandatory, but will give a warning if the content size of the view is undefined. override func viewWillAppear(_ animated : Bool) { super.viewWillAppear(animated) scrollingContentViewManager.viewWillAppear(animated) } // Message: This is only necessary in applications that support changes in device alignment. override func viewWillTransition(up to : size : CGSize, with coordinator : UIViewControllerTransitionCoordinator) { super.viewWillTransition(up to : size, with : coordinator) scrollingContentViewManager.viewWillTransition(to: size, with: coordinator) } // Message: This is only needed in applications with navigation controllers used to push // sequences of view controllers with text fields that become the first // responder in `viewWillAppear`. override func viewSafeAreaInsetsDidChange() { super.viewSafeAreaInsetsDidChange() scrollingContentViewManager.viewSafeAreaInsetsDidChange() } }
GitHub
https://github.com/drewolbrich/ScrollingContentViewControllerWhen using UIScrollView to manage a view controller’s view’s content, it is common practice to use Auto Layout to specifiy the size of that content. In such scenarios, it is often necessary to make that content scrollable. While you could re-compute the size of the content whenever the size of the view changes using the size of the view controller’s view, there is a much simpler way: just make the UIScrollView’s contentSize the size of the view controller’s view.. Read more about swift uiscrollview programmatically and let us know what you think.
Related Tags:
swift infinite scrollviewmxscrollscrollview github swiftinfinite scroll swiftuiscrollview-infinitescrolluiscrollview,People also search for,Privacy settings,How Search works,uiscrollview,make view controller scrollable swift,make uiview scrollable swift,swift uiscrollview programmatically,swift infinite scrollview,swift scrollable child view controller,ios horizontal scroll view github,horizontal scroll view swift