OSX AVPlayerView resizing when play starts - macos

I have an AVPlayerView as the 2nd NSSplitViewItem in a NSSplitViewController. The 1st split item is a list of videos.
When I select a video, it plays in the AVPlayerView.
The problem is, after I call [self.videoView.player play]; my MediaViewController's view resizes depending on the size of the video being played.
I'm using StoryBoards and my MediaViewController on the canvas has the AVPlayerView Top/Bottom/Trailing/Leading set to hug the superview. This seems to work fine by letting the window be resized and the video adjusts size accordingly.
I don't understand at what point the view decides to resize itself and what to do to stop it.
I have set self.videoView.videoGravity = AVLayerVideoGravityResizeAspect;
What am I missing?
Thanks
EDIT ---------
It seems the problem is not with the video size, but an image overlay I have added to the videoPlayer contentOverlayView.
I add the overlay like this:
if (self.videoView.contentOverlayView.subviews.count == 0)
{
// Add an NSImageView subview to use for overlays
NSImageView *overlayIV = [[NSImageView alloc] initWithFrame:self.videoView.frame];
[overlayIV setTranslatesAutoresizingMaskIntoConstraints:NO];
[overlayIV setImageScaling:NSImageScaleProportionallyUpOrDown];
[self.videoView.contentOverlayView addSubview:overlayIV];
// Set constraints to hug parent
[self.videoView addConstraint:[NSLayoutConstraint constraintWithItem:overlayIV
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.videoView
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0]];
[self.videoView addConstraint:[NSLayoutConstraint constraintWithItem:overlayIV
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.videoView
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0.0]];
[self.videoView addConstraint:[NSLayoutConstraint constraintWithItem:overlayIV
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self.videoView
attribute:NSLayoutAttributeLeading
multiplier:1.0
constant:0.0]];
[self.videoView addConstraint:[NSLayoutConstraint constraintWithItem:overlayIV
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self.videoView
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:0.0]];
}
Then when I add a new image overlay it sometimes resizes the window:
NSImageView *overlayIV = [self.videoView.contentOverlayView.subviews firstObject];
if (overlayIV)
{
if (image)
{
overlayIV.image = image;
}
else
{
overlayIV.image = nil;
}
}

Related

Subview height resize

I have a UIView with 2 subviews. Only 1 subview is visible at a time, controlled by a segmented control. The subviews have different heights. How do I set the UIView height to be dependent on the visible subview?
EDIT -
The below code works for the initial back and forth segue of the segmented control but then stays at 30px. The debugger shows that there is an issue satisfying the constrains but I'm not sure how to correct it.
Error:
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
("<NSLayoutConstraint:0x7f84f84b3b80 V:[UIView:0x7f84f852bc60(60)]>",
"<NSLayoutConstraint:0x7f84f8494d20 V:[UIView:0x7f84f852bc60(30)]>")
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7f84f84b3b80 V:[UIView:0x7f84f852bc60(60)]>
Code:
- (IBAction)segmentValueChanged:(UISegmentedControl *)sender {
switch (sender.selectedSegmentIndex) {
case 0:
[_ParentView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_ParentView addConstraint:[NSLayoutConstraint
constraintWithItem:_ParentView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:30.0]];
self.1stView.hidden = NO;
self.2ndView.hidden = YES;
break;
case 1:
[_ParentView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_ParentView addConstraint:[NSLayoutConstraint
constraintWithItem:_ParentView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:60.0]];
self.1stView.hidden = YES;
self.2ndView.hidden = NO;
break;
default:
break;
}
}
Thanks
Okay I set this up in storyboard and got it to work.
So you have your three UIViews for the story board
in your .h file
#property (nonatomic, retain) IBOutlet UIView *parentView;
#property (nonatomic, retain) IBOutlet UIView *HDDView;
#property (nonatomic, retain) IBOutlet UIView *SSDView;
Then in your .m file
#synthesize parentView, HDDView, SSDView;
- (void)viewDidLoad {
//so here you can set which uiview is hidden when the view loads
//or you probably did it in your storyboard, either way works
self.SSDView.hidden = YES;
}
- (IBAction)segmentValueChanged:(UISegmentedControl *)sender {
switch (sender.selectedSegmentIndex) {
case 0:
self.HDDView.hidden = NO;
self.SSDView.hidden = YES;
CGRect newFrame = parentView.frame;
newFrame.size.height = HDDView.frame.size.height;
parentView.frame = newFrame;
break;
case 1:
self.HDDView.hidden = YES;
self.SSDView.hidden = NO;
CGRect otherFrame = parentView.frame;
otherFrame.size.height = SSDView.frame.size.height;
parentView.frame = otherFrame;
break;
default:
break;
}
}
Now in your storyboard add your SSDView and HDDView UIViews and hook them up to their IBOutlets. Then add your parentView UIView and hook it up too. Then drag SSDView and HDDView inside of the parentView UIView. **Make sure that you put SSDView and HDDView at the top of the parentView so that each UIView's top bounds are flush. Also make sure that you did not drag one of subviews into the other. And finally add some constraints to the parentView so that it is in the position that you will want. Then hook up your segmented controller and you are good to go.
All in all, I would suggest not to use Interface Builder for complex things like this. You can do this with code and it will be much more customizable and easier to adjust. I started out using IB but it is much better to do these things programmatically because you can have much more control. I hope this helps you out.
Its probably not the cleanest but I was able to get the below code to work. Thanks to #AJB for the help.
- (IBAction)segmentValueChanged:(UISegmentedControl *)sender {
switch (sender.selectedSegmentIndex) {
case 0:
self.1stView.hidden = NO;
self.2ndView.hidden = YES;
_1stconstraint = [NSLayoutConstraint
constraintWithItem:_ParentView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:30.0];
[_ParentView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_ParentView removeConstraint:_2ndconstraint];
[_ParentView addConstraint:_1stconstraint];
break;
case 1:
self.1stView.hidden = YES;
self.2ndView.hidden = NO;
_2ndconstraint = [NSLayoutConstraint
constraintWithItem:_ParentView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:60.0];
[_ParentView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_ParentView removeConstraint:_1stconstraint];
[_ParentView addConstraint:_2ndconstraint];
break;
default:
break;
}
}

How to place 2 NSTextView vertically aligned with a space in between, and make container view resize accordingly with auto layout

Hope the title is clear. Trying to have something below
--------------------
| [titleTextView] |
| | |
| [detailsTextView]|
--------------------
With the code that I tried, the container resized, but both titletextView and detailsTextView are placed together (overlapping each others). I know I init both at (16,0) but shouldn't the constrain place them correctly?
I also get the following error: Unable to simultaneously satisfy constraints:
("<NSLayoutConstraint:0x60000008fcd0 NSTextView:0x600000134be0.bottom == NSView:0x600000134c80.bottom + 20>",
"<NSAutoresizingMaskLayoutConstraint:0x608000093ce0 h=--& v=--& V:[NSTextView:0x600000134be0]-(0)-| (Names: '|':NSView:0x600000134c80 )>")
Code:
//title textView
self.titleTextView = [[NSTextView alloc] initWithFrame:NSMakeRect(16, 0, [self.view frame].size.width - 30, 0)];
[self.titleTextView setEditable:NO];
[self.titleTextView setBackgroundColor:[NSColor clearColor]];
[self.titleTextView setString:#"potentially long text."];
[self.titleTextView setHorizontallyResizable:NO];
[self.titleTextView sizeToFit];
//detail textView
self.detailsTextView = [[NSTextView alloc] initWithFrame:NSMakeRect(16, 0, [self.view frame].size.width - 30, 0)];
[self.detailsTextView setEditable:NO];
[self.detailsTextView setBackgroundColor:[NSColor clearColor]];
[self.detailsTextView setString:#"Very long text."];
[self.detailsTextView setHorizontallyResizable:NO];
[self.detailsTextView sizeToFit];
//Adding to self.view
[self.view addSubview: self.titleTextView];
[self.view addSubview: self.detailsTextView];
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:self.titleTextView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.detailsTextView
attribute:NSLayoutAttributeTop
multiplier:1
constant:20]];
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:self.titleTextView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTop
multiplier:1
constant:20]];
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:self.detailsTextView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1
constant:20]];
When working with autolayout, you don't want to think about the layout in terms of frames at all. The constraints will determine the frame of your views.
Also, if you're creating the layout in code, you have to call setTranslatesAutoresizingMaskIntoConstraints:NO for the views which you want the autolayout engine to apply to.
So, you'd want to do something like:
UIView* titleTextView = [[UIView alloc] init];
[titleTextView setTranslatesAutoresizingMaskIntoConstraints:NO];
UIView* detailsTextView = [[UIView alloc] init];
[detailsTextView setTranslatesAutoresizingMaskIntoConstraints:NO];
...additional setup stuff...
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"|-[titleTextView]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(titleTextView)]];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"|-[detailsTextView]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(detailsTextView)]];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[titleTextView][detailsTextView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(titleTextView, detailsTextView)]];
If working in code, I'd strongly recommend checking out the visual format language which will make setting up constraints much more efficient in code, but you can also do the same thing as above using individual constraints.
Forget all you've done earlier with rects and start thinking in relative positions.
Using my favorite category for autolayout:
https://github.com/jrturton/UIView-Autolayout
you can achieve what you want with these simple constraints (which I find MUCH more readable and intuitive than any of the official API solutions):
[self.titleTextView pinToSuperviewEdges:JRTViewPinLeftEdge|JRTViewPinTopEdge inset:20.0];
[self.detailsTextView pinToSuperviewEdges:JRTViewPinLeftEdge inset:20.0];
[self.detailsTextView pinEdge:NSLayoutAttributeTop toEdge:NSLayoutAttributeBottom ofView:self.titleTextView inset:20];
This will pin both textviews 20 pixels from the left, titleTextView 20 pixels from the top and detailsTextView 20 pixels below titleTextView. Also, the category will add the constraints to the correct view in each case.

Problems animating an NSImageView/NSView with or without constraints

I'm trying to do some very simple view animation in a window (xib) that is using AutoLayout and I'm getting some very unpredictable results. Obviously the auto layout engine is doing some things under the hood and I don't know how to fix it.
To start with, my window has a grid of 3x3 NSImageViews that are set to NSImageScaleProportionallyUpOrDown. After setting the content compression to 10, the views do the right thing when the window is resized...everything stays in the right place and in the correct proportions. A nice 3x3 grid of images.
When the user clicks on a view, I want the view to takeover the entire window and fade out the other views. Then, when touched again, animate back to it's original position.
To keep things something simple, constraint-wise, I decided to leave all the NSImageViews in place and create another one on top of the touched view and use it to animate. That's the problem one.
I've tried animating that view 2 ways: by animating the constraints, and by not using constraints on that view and just animate it's frame. Either way, I get crazy results.
Here's the code:
Using Constraints
- (void) moveToFullView:(NSInteger)which
{
self.soloIndex = which;
NSImageView *tmpView = self.imageviews[which];
// create a view directly on top of the touched view
self.soloView = [[NSImageView alloc] initWithFrame:tmpView.frame];
[self.soloView.translatesAutoresizingMaskIntoConstraints = NO;
self.soloView.image = tmpView.image;
self.soloView.imageScaling = NSImageScaleProportionallyUpOrDown;
// without this, the window changes size in moveBackFromFullView
[self.soloView setContentCompressionResistancePriority:10 forOrientation:NSLayoutConstraintOrientationHorizontal];
[self.soloView setContentCompressionResistancePriority:10 forOrientation:NSLayoutConstraintOrientationVertical];
[self.view addSubview:self.soloView];
// create constraints with animatable constants
CGFloat leftSpace = tmpView.frame.origin.x;
CGFloat topSpace = tmpView.frame.origin.y;
CGFloat width = tmpView.frame.size.width - self.view.bounds.size.width;
CGFloat height = tmpView.frame.size.height - self.view.bounds.size.height;
self.soloView.leftConstraint = [NSLayoutConstraint constraintWithItem:self.soloView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:leftSpace];
self.soloView.topConstraint = [NSLayoutConstraint constraintWithItem:self.soloView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:topSpace];
self.soloView.widthConstraint = [NSLayoutConstraint constraintWithItem:self.soloView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:width];
self.soloView.heightConstraint = [NSLayoutConstraint constraintWithItem:self.soloView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant:height];
[self.view addConstraint:self.soloView.leftConstraint];
[self.view addConstraint:self.soloView.topConstraint];
[self.view addConstraint:self.soloView.widthConstraint];
[self.view addConstraint:self.soloView.heightConstraint];
[self.view layoutSubtreeIfNeeded];
// animate the view to occupy the entire self.view
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
context.allowsImplicitAnimation = YES;
context.duration = 0.75;
// fade out the other views for now
for(NSImageView *p in self.imageviews){
p.alphaValue = 0;
}
// these values should make the soloView in the same place and size as the self.view
self.soloView.leftConstraint.constant = 0;
self.soloView.topConstraint.constant = 0;
self.soloView.widthConstraint.constant = 0;
self.soloView.heightConstraint.constant = 0;
[self.view layoutSubtreeIfNeeded];
} completionHandler:nil];
}
- (void) moveBackFromFullView
{
// this is where the solo view should animate back to
NSRect destR = [self.imageviews[self.soloIndex] frame];
CGFloat leftSpace = destR.origin.x;
CGFloat topSpace = destR.origin.y;
CGFloat width = destR.size.width - self.view.bounds.size.width;
CGFloat height = destR.size.height - self.view.bounds.size.height;
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
context.allowsImplicitAnimation = YES;
context.duration = 0.75;
for(NSImageView *p in self.imageviews){
p.alphaValue = 1.00;
}
self.soloView.leftConstraint.constant = leftSpace;
self.soloView.topConstraint.constant = topSpace;
self.soloView.widthConstraint.constant = width;
self.soloView.heightConstraint.constant = height;
[self.view layoutSubtreeIfNeeded];
} completionHandler:^{
[self.soloView removeFromSuperview];
self.soloView = nil;
}];
}
Using the above constraint-based code, the soloView's left and top move correctly to full view and back, but when going to full view, the soloView's width and height don't animate and seem to just stay at the destination size. But...it goes back correctly...width and height too.
Using Frames
- (void) moveToFullView:(NSInteger)which
{
self.soloIndex = which;
NSImageView *tmpView = self.imageviews[which];
self.soloView = [[NSImageView alloc] initWithFrame:tmpView.frame];
[self.soloView.translatesAutoresizingMaskIntoConstraints = NO;
self.soloView.imageScaling = NSImageScaleProportionallyUpOrDown;
self.soloView.image = tmpView.image;
self.soloView.autoresizingMask = NSViewHeightSizable | NSViewWidthSizable;
[self.view addSubview:self.soloView];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
context.allowsImplicitAnimation = YES;
context.duration = 0.75;
for(NSImageView *p in self.imageviews){
p.alphaValue = 0;
}
self.soloView.frame = NSMakeRect(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
} completionHandler:nil];
}
- (void) moveBackFromFullView
{
NSRect destR = [self.imageviews[self.soloIndex] frame];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
context.allowsImplicitAnimation = YES;
context.duration = 0.95;
for(NSImageView *p in self.imageviews){
p.alphaValue = 1.00;
}
self.soloView.frame = destR;
} completionHandler:^{
[self.soloView removeFromSuperview];
self.soloView = nil;
}];
}
Using the above frame-based code, the soloView animates properly to and from full view, with the correct width and height. But there's something VERY strange when going back...there's another ghost view that animates from the origin to the same destination. I have NO idea how there's another animating view. I even checked the number of subviews of self.view and it's 10, but I see 11....the 9 grid views, the soloview and this ghost view. And yes, I have self.view.wantsLayer = YES when the main view is created.
I must be going crazy. Neither code works. I hate working with constraints for such a simple task. I'd rather use the frame based code...it's day and night much simpler, but I have no idea why there's another view moving back.
I have more experience with UIView animation than NSView animation, so maybe I'm missing something fundamental.
ANY help would be very much appreciated.

Button above NSScrollView using autoLayout

I have a Cocoa project using Autolayout, and I want to put a button (actually an NSPathControl) over a NSScrollView so that it stays in the same place on the screen even when the scrollView is scrolled.
Whenever I add the button to the scrollView's parent, it ends up behind the scrollView (even if I explicitly use addSubview:positioned:relativeTo:. How do I get it to float above the scrollView?
My fallback is to put it inside of the scrollView, turn on translatesAutoresizingMaskIntoConstraints and update the frame as the scrollView is scrolled. I would strongly prefer to use autolayout if possible though...
Edit: Here is the layout code for the button (the layout for content in the scrollView is quite complex):
NSButton *button = [[NSButton alloc]initWithFrame:NSZeroRect];
button.translatesAutoresizingMaskIntoConstraints = NO;
button.wantsLayer = YES;//Added incase this affects ordering (it doesn't seem to make a difference)
[self.superview addSubview:button positioned:NSWindowAbove relativeTo:self];
[self.superview addConstraint:[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:20]];
[self.superview addConstraint:[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:20]];
Solved by setting wantsLayer to YES on the scrollView itself.

UIScrollView doesn't scroll - even with valid content size and scroll enabled

In my viewDidAppear method (in which i call to the super method) I have the following code:
UIScrollView *navbar = [[UIScrollView alloc] init];
[navbar setScrollEnabled:YES];
[navbar setBackgroundColor:[UIColor redColor]];
[navbar setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:navbar];
NSDictionary *viewsDictionary2 = NSDictionaryOfVariableBindings(navbar);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"|[navbar]|"
options:0
metrics:nil
views:viewsDictionary2]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[navbar]|"
options:0
metrics:nil
views:viewsDictionary2]];
NSArray *categories = #[#"nav1", #"nav2", #"nav3", #"nav4", #"nav5", #"nav6", #"nav7", #"nav8", #"nav9", #"nav10", #"nav11", #"nav12", #"nav13"];
NSMutableArray *tempCategoryImages = [NSMutableArray array];
for (NSInteger i = 0; i < categories.count; i++)
{
[tempCategoryImages insertObject:[UIImage imageNamed:categories[i]] atIndex:i];
}
NSArray *categoryImages = [tempCategoryImages copy];
// Add subviews.
//
CGFloat xPadding = 25.0f;
UIView *previousImageView = NULL;
for (NSInteger i = 0; i < categoryImages.count; i++)
{
UIImageView *imageView = [[UIImageView alloc] initWithImage:categoryImages[i]];
[imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
[navbar addSubview:imageView];
if (i == 0) {
//
// First category.
//
[navbar addConstraint:[NSLayoutConstraint constraintWithItem:imageView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:imageView.superview
attribute:NSLayoutAttributeLeft
multiplier:1
constant:0]];
} else {
//
// End categories.
//
[navbar addConstraint:[NSLayoutConstraint constraintWithItem:imageView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:previousImageView
attribute:NSLayoutAttributeRight
multiplier:1
constant:xPadding]];
}
[navbar addConstraint:[NSLayoutConstraint constraintWithItem:imageView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:imageView.superview
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0]];
previousImageView = imageView;
}
// Set content size.
//
CGSize scrollContentSize = CGSizeZero;
for (NSInteger i = 0; i < categories.count; i++)
{
UIImage *tempImage = [UIImage imageNamed:categories[i]];
// Width.
//
scrollContentSize.width += tempImage.size.width;
// Height.
//
if (tempImage.size.height > scrollContentSize.height) {
scrollContentSize.height = tempImage.size.height;
}
}
navbar.contentSize = scrollContentSize;
Which when i log the scrollviews properties, it has the subviews, a large enough content size and scrolling enabled.
Even when I add the UIScrollView to IB and link it to the same code it then works? (I comment out the NSAutoLayout code.
This leads me to believe that for the UIScrollView to work, I cannot use Auto layout.
Am I missing something?
Thanks
EDIT
The code also doesn't work programatically, when I try initWithFrame:frame with setTranslatesAutoresizingMaskIntoConstraints:YES
Check the attributes inspector for your scrollview in IB. Make sure that bounce vertically is checked.
Fixed this problem for me.

Resources