47

My UIScrollView won't scroll down. I don't know why. I already followed Apple documentation regarding to this issue.

@IBOutlet weak var scroller: UIScrollView!

    override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.

}

override func viewDidLayoutSubviews() {
    scroller.scrollEnabled = true
    // Do any additional setup after loading the view
    scroller.contentSize = CGSizeMake(400, 2300)
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Nurdin
  • 23,382
  • 43
  • 130
  • 308
  • What is the frame of your scroll view? Add a println statement to viewDidLayoutSubviews to find out. – rdelmar Jan 26 '15 at 05:17
  • I've noticed a similar problem in the UIWebView. I believe you are currently running your tests on your PC. No matter what you do (up to my knowledge), you will not be able to make it scroll on the PC. If you upload the same app with the same code to a device, scrolling will function. Hope this helps! – Adishree Ghatare Jan 30 '16 at 18:40

14 Answers14

57

You need to set the frame of your UIScrollView so that it is less than the contentSize. Otherwise, it won't scroll.

Also, I would recommend that you add the following to your viewDidLoad method:

scroller.contentSize = CGSize(width: 400, height: 2300)
shim
  • 9,289
  • 12
  • 69
  • 108
Christian
  • 22,585
  • 9
  • 80
  • 106
  • 16
    Swift 3: `scroller.contentSize = CGSize(width: yourWidth, height: yourHeight)` – Amr Lotfy Mar 23 '17 at 12:03
  • If you are having the problem with swift 5.0+, you can go through https://www.freecodecamp.org/news/how-to-use-auto-layout-with-uiscrollview-for-ios-b94b8687a4cc/ article.. – Wimukthi Rajapaksha Feb 19 '20 at 12:11
  • Thanks. This was useful, despite me using Storyboard. I removed the offending restraint on the frame and it this solved my issue. – sprut Feb 16 '21 at 05:09
28

If you are using AutoLayout

Set content size in viewDidAppear which works for me.

override func viewDidAppear(_ animated: Bool) {
   scrollView.contentSize = CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height+300)
}
chedabob
  • 5,835
  • 2
  • 24
  • 44
satheesh
  • 2,770
  • 2
  • 14
  • 19
24

Alot of the time the code is correct if you have followed a tutorial but what many beginners do not know is that the scrollView is NOT going to scroll normally through the simulator. It is suppose to scroll only when you press down on the mousepad and simultaneously scroll. Many Experienced XCode/Swift/Obj-C users are so use to doing this and so they do not know how it could possibly be overlooked by beginners. Ciao :-)

@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
// Do any additional setup after the view
}

override func viewWillLayoutSubviews(){
super.viewWillLayoutSubviews()
scrollView.contentSize = CGSize(width: 375, height: 800)
}

This code will work perfectly fine as long as you do what I said up above

flo527
  • 343
  • 2
  • 11
16

Do not give fix height to scroll view and always give top of first subview to scrollview and bottom of last subview to scrollview. By this way scroll view will automatically grow as per the size of contained subviews. No need to give contentSize to the scrollview.It will work for small as well as large size iPhone.

Sheetal Shinde
  • 489
  • 5
  • 7
11

Swift 3.0 version

scroller.contentSize = CGSize(width: scroller.contentSize.width, height: 2000)
Fangming
  • 24,551
  • 6
  • 100
  • 90
10

If you are using autolayout, then the contentSize property stops working and it will try to infer the content size from the constraints. If that is the case, then your problem could be that you are not defining the necessary constraints to the content view so that the scrollview can infer the content size. You should define the constraints of your content view to the top and bottom edges of the scrollview.

Daniel Bickler
  • 1,119
  • 13
  • 29
Carlos Compean
  • 674
  • 6
  • 6
  • I'm note really understand what you talking about. Just link? No solution? – Nurdin Jan 26 '15 at 09:04
  • 1
    I did put a solution, which is to add a constraint for each edge of the content view to the corresponding edge of the scrollview, in the link it also comments about this solution and gives you more details and also a reference to apple's documentation about it, but this only applies in the case you are using autolayout, if not then the problem is something else – Carlos Compean Jan 26 '15 at 09:14
  • The link is not there anymore. I am having the same problem and I am using autoLayout. I made sure my content view (I guess you mean the chile view of the scroll view) is the same size as the scroll view. When the keyboard opens it covers half of the screen but I am not able to scroll. – Zvi Sep 24 '16 at 21:21
  • This was an absolute saviour. I think this is a common problem for beginers and should get more upvotes. – asreerama Jul 22 '20 at 20:01
7

If you are using Storyboard:

  1. Put your Content view inside the UIScrollView
  2. Add top, bottom, left and right constraints with the scroll view
  3. Add equal heights and widths constraints
  4. For a vertical scroll set the Equal Heights Constraint priority to 250. For a horizontal scroll set the Equal Widths Constraint priority to 250
5

In my case, I used UIStackView inside UIScrollView.

Added some views-elements from code to stackview. It won't scroll.

Fixed it by setting stackview's userInteractionEnabled to false.

Zaporozhchenko Oleksandr
  • 4,660
  • 3
  • 26
  • 48
2

The problem could be that your scrollView doesn't know its contentSize like stated above, but the fix is easier than what the above answers are. Like Carlos said but I will elaborate more. If you want your scrollView to scroll vertically(up & down), make your contentView which is in the hierarchy of the scrollView equal width to the ViewController and give it a height constraint that works for your project i.e. 700. For the opposite(horizontally) make the height equal to the ViewController and the width some big number that works for your project.

Jevon Charles
  • 644
  • 1
  • 7
  • 12
1

FWIW, I found that I needed to use sathish's solution from above, though it was insufficient to effect the intervention in viewDidAppear alone. I had to instead make the adjustment for every new content assignment:

func display(pattern: Pattern) {
    let text : NSAttributedString = pattern.body()
    patternTextView.attributedText = text

    // Set the size of the view. Autolayout seems to get in the way of
    // a correct size calculation
    patternTextView.contentSize = CGSize(width: 348, height: 620)
}

The manifest constants (yeah, I know, yuk, but it makes it easier to understand here) are from the autolayout spec.

Cope
  • 769
  • 7
  • 17
1

It worked for me. In Size Inspector Layout = Translates Mask into constraints. Autoresizing = all click.

enter image description here

user3480687
  • 69
  • 1
  • 2
  • 12
0

For Swift 5.6 and iOS 15:

let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
let subView: UIView = UILabel()
subView.text = String(repeating: "MMMMMMM ", count: 100)
NSLayoutConstraint.activate([
    subView.topAnchor.constraint(equalTo: scrollView.topAnchor),
    subView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
    subView.leftAnchor.constraint(equalTo: scrollView.leftAnchor),
    subView.rightAnchor.constraint(equalTo: scrollView.rightAnchor),
    // Constrain width so the label text wraps and we scroll vertically.
    subView.widthAnchor.constraint(lessThanOrEqualTo: scrollView.widthAnchor),
])
M. Leonhard
  • 1,332
  • 1
  • 18
  • 20
0

Increase the content Height work for me.

Tipu
  • 19
  • 4
-2

I do not know it is a good solution, but you can try to set headerview to empty UITableView.

let scrollView: UIView = UIView(frame: CGRectMake(0, 0, 400, 2300))

tableView.tableHeaderView = scrollView
gellezzz
  • 1,165
  • 2
  • 12
  • 21