1. 程式人生 > >iOS: How To Make AutoLayout Work On A ScrollView

iOS: How To Make AutoLayout Work On A ScrollView

Ok, I’ll admit. I’ve been seriously struggling with AutoLayout ever since it’s been introduced. I understand the concept, and I LOVE the idea of it, but when I actually do it, it almost never behaves as it does in my head.

So when I had a chance to go talk to an actual Apple Engineer about AutoLayout last week at WWDC, I made sure to go. I thought of my most painful experience using AutoLayout recently – when I was making a login screen with username and password fields on a ScrollView (so it scrolls up when the keyboard comes up) – and had the Apple engineer walk me through the example.

Here is what we made:

ScrollView TextFields Autolayout ScrollView AutoLayout 5

This is just two input fields centered on a ScrollView. You can see the AutoLayout at work here – the two input fields are centered correctly both on a 4s and a 5s device.

This “simple” solution took the Apple Engineer 40 minutes to solve! However, several senior engineers I know said that they’ve never been able to get AutoLayout working quite right on a ScrollView, so 40 minutes is actually not bad!

Here are the key tricks to getting AutoLayout to work on a ScrollView:

One View

The ScrollView should have only ONE child view. This is forced in Android, so I should have made the connection, but I just didn’t think of it – it’s too easy to put the two input text fields right onto the ScrollView, especially in Interface Builder.

Here is what the View Hierarchy should actually look like:

scrollview hierarchy

Again, make sure to put all your fields and custom views inside the one child view of the ScrollView!

Equal Widths

I’m going to start with the constraints from the outside (on the main view) in (to the stuff inside the ContentView).

The obvious starting point is to bind the ScrollView to the View – just select the ScrollView from the view hierarchy, and add the following constraints:

constraints

The key to getting the constraints to work properly however, is adding anEqual Width constraint between the main View and the ContentView. The ScrollView adjusts to the size of the content inside of it, so setting the ContentView to the Width of the ScrollView leaves the width of the ContentView ambiguous.

To create the Equal Width Constraint between the ContentView and the View, select the ContentView on the view hierarchy and Control + Drag to the View – you should get a pop-up that gives you the “Equal Widths” option:

equal width option

Your constraints between the main View, ScrollView, and ContentView should look like this:

Equal Widths

Content Insets

The constraints between the ScrollView and the ContentView are surprisingly straight forward – just bind the ContentView to the ScrollView (make sure the constant to the bottom layout guide is 0):

constraints

The constraints between the ContentView and ScrollView are now as follows with all constants set at 0:

scrollview to contentview

If your storyboard is like mine, you might notice that the actual ContentView is not the full height of the main view or the ScrollView:

storyboard views

However, we do want to make sure the ContentView is centered when it’s rendered on a device. To do that we need to write some code to property set the Content Insets in the ViewController:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 // ViewController.swift import UIKit class ViewController: UIViewController { @IBOutlet var scrollView : UIScrollView @IBOutlet var contentView : UIView override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func viewDidLayoutSubviews() { let scrollViewBounds = scrollView.bounds let containerViewBounds = contentView.bounds var scrollViewInsets = UIEdgeInsetsZero scrollViewInsets.top = scrollViewBounds.size.height/2.0; scrollViewInsets.top -= contentView.bounds.size.height/2.0; scrollViewInsets.bottom = scrollViewBounds.size.height/2.0 scrollViewInsets.bottom -= contentView.bounds.size.height/2.0; scrollViewInsets.bottom += 1 scrollView.contentInset = scrollViewInsets } }

Once you add the proper constraints into the ContentView (see next step), your final result will look like this:

centered container view

The ugly colors are meant to differentiate the ScrollView (green) from the ContentView (red). Again, in the storyboard, the ContentView is at the top of the ScrollView, but with our content insets set in code, it now becomes centered.

Centering Multiple Views

The final step is to add AutoLayout to the ContentView. This is the same as adding layout normally to any view, so I won’t go into much detail here.

The one thing I did learn that I’d like to share (although now it seems obvious) is how to center the two text fields in the view. Previously, I put the two text fields into a container view, and centered the container view in the parent view. However, that is not necessary.

Instead, you can center each text field horizontally in container (so they’re now centered and on top of each other), and then add a constant of 25 to one (so it’s moved up 25 pixels from the center), and add a constant of -25 to the other (so it’s moved down 25 pixels from the center).

top 25 bottom -25

This will leave you with a space of 50 pixels between the two text fields, but the space exactly in between them will be the center of the view.

Do you have any other AutoLayout tips? I’m always looking to learn more and improve, so please let me know in the comments!

Enjoy the article? Join over 8,500+ Swift developers and enthusiasts who get my weekly updates.

相關推薦

iOS: How To Make AutoLayout Work On A ScrollView

Posted on June 11th, 2014 Ok, I’ll admit. I’ve been seriously struggling with AutoLayout ever since it’s been introduced. I understand the concept, and

[iOS] How to make a Global function in Swift

You can create a custom class with the method you need like this: class MyScene: SKScene { func CheckMusicMute() { if InGameMusicOnOff == tr

[iOS] How to round the corners of a button

如何做出圓角的按鈕?比我想像中的簡單,其實一行指令(buyButton.layer.cornerRadius)就完成了。 實作出來的效果,我是用 cornerRadius = 5 You can manipulate the CALayer of your button to do this pre

How to Promote Your Bot on a Budget

How to Promote Your Bot on a BudgetChatbots are taking over the business world. Every month, people send more than a billion messages to businesses and org

How to make unit test on Android with Kotlin (KAD 22)

Of course, Kotlin also allows us to do unit tests in a very simple way, and very similar to what we’re used in Java. There are some small complicatio

How to make a GroupBox in website development by VS.NET2005

Sometimes we need to make a GroupBox on my webpage.Using the HTML object(fieldset ,legend)  we can make it out! source: <fieldset style

[iOS] How to detect touch on UIWebView Ask

class ViewController: UIViewController, UIGestureRecognizerDelegate, UIWebViewDelegate { @IBOutlet weak var webView: UIWebView! override func viewD

How to make your iOS apps more secure with SSL pinning

swift 和 obj-c 完成 ssl 的寫法如下: We can start by instantiating an NSURLSession object with the default session configuration. Swift self.urlSession = NSURLSes

[iOS] How to programmatically check if running on an iPhone or iPad device

In Swift: if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.Pad { In Objective-C: if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) To check if

Want to Work on A.I.? Study Philosophy or Communications, Execs Say

Science, technology, engineering, and mathematics--companies everywhere appear to be fighting for workers in the STEM fields to get a head start in buildin

How to Make a Profit in a Bear Market?

How to Make a Profit in a Bear Market?2018 has been a tough year for crypto investors. Bitcoin has declined by more than 60% and leading altcoins have lost

How to make the impossible possible in CSS with a little creativity

CSS Previous sibling selectors don’t exist, but that doesn’t mean we can’t use themIf you ever used CSS sibling selectors, you know there’s only two. The +

How to make form submissions secure on an API website

Implementing forms on a Vue.js website? Having a readonly website is a piece of cake. Easy to develop using headless CMS, easy to maintain, and zero worrie

How to make onActivityResult get called on Nested Fragment

One of the common problem we always meet in the world of Fragment is: although we could call startActivityForResult directly from Nested

Designing a dashboard: how to make sure it will show useful data

Find out moreSurvey & workshop idea to help you gather more insights:Initial survey — what information is important to your users?By now, you will have

How to Make a Computer Operating System

How to Make a Computer Operating System 如何製作一個作業系統(翻譯版) 原文地址:Github:How to Make a Computer Operating System 翻譯地址:Github:How to M

How To Make A Swipeable Table View Cell With Actions – Without Going Nuts With Scroll Views

Make a swipeable table view cell without going nuts with scroll views! Apple introduced a great new user interface scheme in the iOS 7 Mail app – sw

How to Make AI Count Your Calories: A Working Prototype in 5 Minutes

Whether you ate too much this Thanksgiving holiday, or just want to be more careful about what you eat in general, I'm here to show you a Clarifai visual r

How to fix yum errors on CentOS, RHEL or Fedora

http dsm list plain ... prop package cat cse Yum is a package management tool for installing, updating and removing rpm packages on Red

How-to Install VMware Tools on Debian Stretch 9 32/64bit Linux+GNU

網絡配置 bsp install com tutorial des linux 虛擬機 top 在虛擬機VMWARE上安裝debian9 安裝vmwaretools時候遇到問題 詢問我IFCONFIG安裝在哪裏? 新版的debian不知道是用戶權限問題還是使用了其他網絡