Adding autolayout constraint programmatically turns uiview to black - objective-c

I need a view controller without xib. There should be a webview with fully filled to the view. For that I've added the following code to loadView method.
- (void)loadView {
CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
UIView *view = [[UIView alloc] initWithFrame:applicationFrame];
view.translatesAutoresizingMaskIntoConstraints = NO;
[view setBackgroundColor:[UIColor greenColor]];
[self setView:view];
// //create webview
self.webview = [[UIWebView alloc] initWithFrame:CGRectZero];
self.webview.translatesAutoresizingMaskIntoConstraints = NO;
[view addSubview:self.webview];
[self.webview setBackgroundColor:[UIColor orangeColor]];
[self.webview setDelegate:self];
NSDictionary *viewBindings = NSDictionaryOfVariableBindings(view,_webview);
// //add constraints
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[_webview]|" options:0 metrics:nil views:viewBindings]];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[_webview]|" options:0 metrics:nil views:viewBindings]];
}
But this turns the entire view to black. If I coment [view addConstraints:... method calls its showing a green view. What's wrong with my code?

I believe that the problem is that the parent view should not set translatesAutoresizingMaskIntoConstraints to false. The only view that must set that attribute to false is the one you are applying autolayout to, in this case webView. If you set view.translatesAutoresizingMaskIntoConstraints to false then you have to add constraints to view.

You don't need to change the root view of the UIViewController manually, maybe that's why it does not work.
My suggestion would be to try this out:
- (void) viewDidLoad {
[super viewDidLoad];
self.webview = [[UIWebView alloc] init];
self.webview.translatesAutoresizingMaskIntoConstraints = NO;
[view addSubview:self.webview];
[self.webview setBackgroundColor:[UIColor orangeColor]];
[self.webview setDelegate:self];
NSDictionary *viewBindings = NSDictionaryOfVariableBindings(view,_webview);
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[_webview]-0-|" options:0 metrics:nil views:viewBindings]];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[_webview]-0-|" options:0 metrics:nil views:viewBindings]];
// put a breakpoint after this line to see the frame of your UIWebView.
// It should be the same as the view
[self.view layoutIfNeeded];
}
This should work and your UIWebView should be full screen. Good luck!

Related

How to make status bar translucent?

i need help in making status bar translucent. In some parts of app its working fine, and in other its not.
This is how status bar is coming if i show navugation bar.
this is how is showing when i remove the navigation bar.
I need to show the navigation bar but status bar should be translucent. The background image is pushed down with the navigation bar.I have set the background image programmatically making a base class.
-(void)addBackGroundImage{
self.backGroundImage=[[UIImageView alloc] init];
self.backGroundImage.translatesAutoresizingMaskIntoConstraints=NO;
[self.backGroundImage setImage:[UIImage imageNamed:#"background"]];
self.backGroundImage.contentMode=UIViewContentModeScaleAspectFill;
[self.view addSubview:self.backGroundImage];
[self.view sendSubviewToBack:self.backGroundImage];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"|[_backGroundImage]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_backGroundImage)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-(0)-[_backGroundImage]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_backGroundImage)]];
AppDelegate *objAppDelegate=[[UIApplication sharedApplication] delegate];
UIView *view=[[UIView alloc] initWithFrame:CGRectMake(0, 0,self.view.frame.size.width, 20)];
view.backgroundColor=[UIColor clearColor];
[view setAlpha:0.2];
}
-(void)updateBackgroundImage:(UIImage *)bgImage{
[self.backGroundImage setImage:bgImage];
}
It is actually what you need to completely remove default header background (statusBar + navigationBar) and set your own:
// ViewController.m
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
self.navigationController.navigationBar.tintColor = [UIColor yourColor]; // Set your tint color
self.navigationController.navigationBar.shadowImage = [UIImage new];
self.navigationController.navigationBar.translucent = YES;
self.navigationController.navigationBar.opaque = NO;
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 64)];
bgView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"Your_Background_Image"]];
[self.view addSubview:bgView];

How to use UIBezierPath in a auto layout view?

As far as I know, views displayed by constraints don't got a frame, so what should I do when I want to draw some lines in these views? Methods like moveToPoint do need a CGRect.
Here's my check: NSLog(#"%f,%f,%f,%f",self.contentView.frame.origin.x,self.contentView.frame.origin.y,self.contentView.frame.size.width,self.contentView.frame.size.height);
And the result is 0.000000,0.000000,0.000000,0.000000
For more details, here's my code:
-(void)loadView
{
self.view = [[UIView alloc]init];
self.titleView = [[UIView alloc]init];
self.placesHolder = [[UIView alloc]init];
self.contentView = [[UIView alloc]init];
self.titleView.translatesAutoresizingMaskIntoConstraints = NO;
self.placesHolder.translatesAutoresizingMaskIntoConstraints = NO;
self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
self.titleView.backgroundColor = [UIColor grayColor];
self.placesHolder.backgroundColor = [UIColor blueColor];
self.contentView.backgroundColor = [UIColor redColor];
[self.view addSubview:self.titleView];
[self.view addSubview:self.placesHolder];
[self.view addSubview:self.contentView];
NSDictionary *timeLineViewMap = #{#"titleView":self.titleView,
#"placesHolder":self.placesHolder,
#"contentView":self.contentView
};
NSArray *titleHorizon = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[titleView]|" options:0 metrics:nil views:timeLineViewMap];
NSArray *placesHolderHorizon = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|[placesHolder(==58)]-0-[contentView]|" options:0 metrics:nil views:timeLineViewMap];
NSArray *titleVertical = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|[titleView(==58)]-0-[placesHolder]|" options:0 metrics:nil views:timeLineViewMap];
NSArray *contentViewConstrain = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[titleView]-0-[contentView]|" options:0 metrics:nil views:timeLineViewMap];
[self.view addConstraints:titleHorizon];
[self.view addConstraints:placesHolderHorizon];
[self.view addConstraints:titleVertical];
[self.view addConstraints:contentViewConstrain];
}
Of course UIView does have a frame even with AutoLayout. You just don't set the values manually, AutoLayout is doing that for you. Methods like setFrame: are still called. Simply implement drawRect: like you always did.
Well, problem kind of solved, it seems that a frame of a view don't get a size until it's on the viewDidAppear move. Then I checked some other questions like iOS AutoLayout - get frame size width, which indicate that addConstraints should be put in the viewDidLayoutSubviews method, which is not in the viewController life cycle.

UIView not animating correctly when UILabel is added to it

I'm animating a custom view off screen using a constraint on view's top edge.
The view is:
#implementation MyView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setBackgroundColor:[UIColor yellowColor]];
_label = [UILabel new];
[_label setTranslatesAutoresizingMaskIntoConstraints:NO];
_label.text = #"text";
[self addSubview:_label];
[self updateConstraints];
}
return self;
}
- (void)updateConstraints
{
NSDictionary *views = NSDictionaryOfVariableBindings(_label);
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[_label]"
options:NSLayoutFormatAlignAllLeft
metrics:nil
views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[_label]"
options:NSLayoutFormatAlignAllCenterY
metrics:nil
views:views]];
[super updateConstraints];
}
#end
The constraint for animating myView on its parent view is:
_myViewTopConstraint = [NSLayoutConstraint constraintWithItem:_myView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-kMyViewVisibleHeight];
[self.view addConstraint:_myViewTopConstraint];
The animation on the top edge constraint is:
[UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.myViewTopConstraint.constant = kScreenHeight;
[self.myView layoutIfNeeded];
} completion:nil];
When the label and constraints in MyView is commented out, the animation works perfectly. But when the label and constraints are there, the animation is sped up significantly, maybe 5x or more.
Why does this happen? Anyone know how to fix it?
Figured it out. layoutIfNeeded must be called on myView's parent view in the animation block.
[self.myView layoutIfNeeded];
changed to
[self.view layoutIfNeeded];

UITableView header disappears under the UINavigationBar using a standard UITableViewController

I have an UITableViewController inside an UINavigationController. I added a UISearchBar as the tableView.header:
UISearchBar *searchBar = [UISearchBar alloc] initWithFrame: CGRectMake(0,0,self.tableView.frame.size.width,44.0)];
self.tableView.tableHeaderView = searchBar;
The problem: When scrolling the tableHeader disappears under the navigationBar.
I already tried to set the navigationController.navigationBar.translucent = NO but it seems this trick doesn't work using a standard UITableViewController.
Is there a way to fix this problem using a standard UITableViewController? I want it to works exactly as it does in Contacts app. I target iOS7.
I gave up using the UITableViewController and I solved using a standard UIViewController with a UISearchBar on top and a UITableView under it. By setting self.edgesForExtendedLayout = UIRectEdgeNone the UISearchBar won't overlap the status bar when the search begins:
-(id) initWithTableViewStyle: (int) tableViewStyle
{
self = [super init];
if (self) {
//Set the UITableViewStyle
self.tableViewStyle = tableViewStyle;
//Be sure the searchBar won't overlap the status bar
self.edgesForExtendedLayout = UIRectEdgeNone;
//Add the subviews to the mainView
[self.view addSubview:self.searchBar];
[self.view addSubview:self.tableView];
//Autolayout
//Create the views dictionary
NSDictionary *viewsDictionary = #{#"searchBar":self.searchBar,
#"tableView": self.tableView};
//Create the constraints using the visual language format
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat: #"H:|[searchBar]|"
options:0
metrics:nil
views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat: #"H:|[tableView]|"
options:0
metrics:nil
views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:#"V:|[searchBar(==44)][tableView]|"
options:0
metrics:nil
views:viewsDictionary]];
}
return self;
}
-(UITableView*) tableView
{
if (!_tableView){
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0,0,0,0)
style:self.tableViewStyle];
_tableView.translatesAutoresizingMaskIntoConstraints=NO;
_tableView.delegate = self;
_tableView.dataSource=self;
}
return _tableView;
}
-(UISearchBar*) searchBar
{
if(!_searchBar){
_searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0,0,0,0)];
_searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
_searchBar.translatesAutoresizingMaskIntoConstraints=NO;
_searchBar.translucent = NO;
_searchBar.delegate = self;
}
return _searchBar;
}
The UIViewController should be made:
UIViewController <NSFetchedResultsControllerDelegate,
UISearchBarDelegate,
UISearchDisplayDelegate,
UITableViewDataSource,
UITableViewDelegate>

UIScrollView showing only part of UIView after rotation

This is my first post to Stack Overflow, and I'm a iOS beginner, so please bear with me!
I have an example app where I have three UIViews (headerView, scrollViewContainer, and bodyView) in a parent UIView (topView), and all of these views are created in code. The topView is added to a UIScrollView (pageScrollView) created in storyboard.
pageScrollView is filling the full screen of an iPhone, and I used Autolayout. The app only contains the ViewController.h and companioning .m-file seen below, plus Appdelegate.x. I think I used the single view application template to start with. I'm using iOS 6 and Xcode 4.6, but I also tried 4.5.
I've tried to remove as much as possible of other code that's irrelevant to this problem.
The problem:
When the app starts it shows all its views correctly, and the scrollView allows to view all three views as intended. But after rotating to landscape, the scrollView somehow offsets the content. For example: Stay at top and rotate = content looks OK, but scroll down a bit and rotate makes the top of the content not to show.
What I have tried: I've searched the net for help, but I haven't found anything that seemed to help me. I've added logging of various data like origin, and contentSize, and also tried to set some of them but without any success. I also used 'po [[UIWindow keyWindow] _autolayoutTrace]' to ensure that the constraints are OK.
I can't see what I'm doing wrong. Are there any obvious things missing in my code?
Thanks in advance!
Here's the ViewController.m:
#import "ViewController.h"
#interface ViewController ()
{
UIView *topView;
UIView *headerView;
UIView *bodyView;
UIView *scrollViewContainer;
UIInterfaceOrientation newOrientation;
CGFloat bodyViewHeight;
CGSize newBounds;
float pictureScrollHeight;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
newBounds = [self sizeInOrientation:[UIApplication sharedApplication].statusBarOrientation];
newOrientation = [UIApplication sharedApplication].statusBarOrientation;
bodyViewHeight = 1200; // The height of the body view varies in size depending on orientation
self.pageScrollView.translatesAutoresizingMaskIntoConstraints = NO;
topView = [[UIView alloc] init];
[topView setBackgroundColor:[UIColor clearColor]];
topView.translatesAutoresizingMaskIntoConstraints = NO;
[self.pageScrollView addSubview:topView];
headerView = [[UIView alloc] init];
[headerView setBackgroundColor:[UIColor redColor]];
headerView.translatesAutoresizingMaskIntoConstraints = NO;
[topView addSubview:headerView];
scrollViewContainer = [[UIView alloc] init];
[scrollViewContainer setBackgroundColor:[UIColor blueColor]];
scrollViewContainer.translatesAutoresizingMaskIntoConstraints = NO;
[topView addSubview:scrollViewContainer];
bodyView = [[UIView alloc] init];
[bodyView setBackgroundColor:[UIColor greenColor]];
bodyView.translatesAutoresizingMaskIntoConstraints = NO;
[topView addSubview:bodyView];
[self updateViewConstraints];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)updateViewConstraints
{
[super updateViewConstraints];
// Remove old constraints
[self.view removeConstraints:self.view.constraints];
[self.pageScrollView removeConstraints:self.pageScrollView.constraints];
[topView removeConstraints:topView.constraints];
[scrollViewContainer removeConstraints:scrollViewContainer.constraints];
if ((newOrientation == UIDeviceOrientationLandscapeLeft) || (newOrientation == UIDeviceOrientationLandscapeRight)) {
pictureScrollHeight = 300;
} else {
pictureScrollHeight = 203;
}
[headerView setNeedsDisplay];
[bodyView setNeedsDisplay];
CGFloat topViewHeight = bodyViewHeight + 55 + pictureScrollHeight;
//self.pageScrollView = _pageScrollView
NSDictionary *viewsDict = NSDictionaryOfVariableBindings(_pageScrollView, topView, headerView, bodyView, scrollViewContainer);
NSDictionary *metricsDict = #{#"topViewHeight": [NSNumber numberWithFloat:topViewHeight],
#"newBoundsWidth": [NSNumber numberWithFloat:newBounds.width],
#"pictureScrollHeight": [NSNumber numberWithFloat:pictureScrollHeight],
#"bodyViewHeight": [NSNumber numberWithFloat:bodyViewHeight]};
// pageScrollView - child to self.view
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[_pageScrollView]-0-|" options:0 metrics:nil views:viewsDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[_pageScrollView]-0-|" options:0 metrics:nil views:viewsDict]];
// topView - child to pageScrollView
[self.pageScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[topView(newBoundsWidth)]-0-|" options:0 metrics:metricsDict views:viewsDict]];
[self.pageScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[topView(topViewHeight)]-0-|" options:0 metrics:metricsDict views:viewsDict]];
// headerView - child to topView
[topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[headerView]-0-|" options:0 metrics:nil views:viewsDict]];
[topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[headerView(55.0)]" options:0 metrics:nil views:viewsDict]];
// scrollViewContainer - child to topView
[topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[scrollViewContainer]-0-|" options:0 metrics:nil views:viewsDict]];
[topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[headerView]-0-[scrollViewContainer(pictureScrollHeight)]" options:0 metrics:metricsDict views:viewsDict]];
// bodyView - child to topView
[topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[bodyView]-0-|" options:0 metrics:nil views:viewsDict]];
[topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[scrollViewContainer]-0-[bodyView(bodyViewHeight)]-0-|" options:0 metrics:metricsDict views:viewsDict]];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
newOrientation = toInterfaceOrientation;
newBounds = [self sizeInOrientation:toInterfaceOrientation];
}
-(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation
{
CGSize size = [UIScreen mainScreen].bounds.size;
UIApplication *application = [UIApplication sharedApplication];
if (UIInterfaceOrientationIsLandscape(orientation))
{
size = CGSizeMake(size.height, size.width);
}
if (application.statusBarHidden == NO)
{
size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height);
}
return size;
}
#end
First of all you do not need to recreate all constraints in -updateViewConstraints method. You need to just update them in this place.
To achieve your aim do the following:
Create your constraints only once. For example in method -setupConstraints. And keep reference to those that need to be updated. See code below.
In method -updateViewConstraints just update topView height and width constraints and height for scrollViewContainer.
Here's the ViewController.m should look like:
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) IBOutlet UIScrollView* pageScrollView;
#property (nonatomic, strong) NSLayoutConstraint* pictureHeightConstraint;
#property (nonatomic, strong) NSLayoutConstraint* topViewWidthConstraint;
#property (nonatomic, strong) NSLayoutConstraint* topViewHeightConstraint;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
newBounds = [self sizeInOrientation:[UIApplication sharedApplication].statusBarOrientation];
newOrientation = [UIApplication sharedApplication].statusBarOrientation;
bodyViewHeight = 1200; // The height of the body view varies in size depending on orientation
self.pageScrollView.translatesAutoresizingMaskIntoConstraints = NO;
topView = [[UIView alloc] init];
[topView setBackgroundColor:[UIColor clearColor]];
topView.translatesAutoresizingMaskIntoConstraints = NO;
[self.pageScrollView addSubview:topView];
headerView = [[UIView alloc] init];
[headerView setBackgroundColor:[UIColor redColor]];
headerView.translatesAutoresizingMaskIntoConstraints = NO;
[topView addSubview:headerView];
scrollViewContainer = [[UIView alloc] init];
[scrollViewContainer setBackgroundColor:[UIColor blueColor]];
scrollViewContainer.translatesAutoresizingMaskIntoConstraints = NO;
[topView addSubview:scrollViewContainer];
bodyView = [[UIView alloc] init];
[bodyView setBackgroundColor:[UIColor greenColor]];
bodyView.translatesAutoresizingMaskIntoConstraints = NO;
[topView addSubview:bodyView];
[self setupConstraints];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)setupConstraints {
// Remove old constraints
[self.view removeConstraints:self.view.constraints];
[self.pageScrollView removeConstraints:self.pageScrollView.constraints];
[topView removeConstraints:topView.constraints];
[scrollViewContainer removeConstraints:scrollViewContainer.constraints];
if ((newOrientation == UIDeviceOrientationLandscapeLeft) || (newOrientation == UIDeviceOrientationLandscapeRight)) {
pictureScrollHeight = 300;
} else {
pictureScrollHeight = 203;
}
[headerView setNeedsDisplay];
[bodyView setNeedsDisplay];
CGFloat topViewHeight = bodyViewHeight + 55 + pictureScrollHeight;
//self.pageScrollView = _pageScrollView
NSDictionary *viewsDict = NSDictionaryOfVariableBindings(_pageScrollView, topView, headerView, bodyView, scrollViewContainer);
// pageScrollView - child to self.view
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[_pageScrollView]-0-|" options:0 metrics:nil views:viewsDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0- [_pageScrollView]-0-|" options:0 metrics:nil views:viewsDict]];
// topView - child to pageScrollView
[self.pageScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[topView]-0-|" options:0 metrics:nil views:viewsDict]];
[self.pageScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[topView]-0-|" options:0 metrics:nil views:viewsDict]];
NSLayoutConstraint* topViewWidthConstraint = [NSLayoutConstraint constraintWithItem:topView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:newBounds.width];
self.topViewWidthConstraint = topViewWidthConstraint;
[topView addConstraint:self.topViewWidthConstraint];
NSLayoutConstraint* topViewHeightConstraint = [NSLayoutConstraint constraintWithItem:topView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:topViewHeight];
self.topViewHeightConstraint = topViewHeightConstraint;
[topView addConstraint:self.topViewHeightConstraint];
// headerView - child to topView
[topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[headerView]-0-|" options:0 metrics:nil views:viewsDict]];
[topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[headerView(55.0)]" options:0 metrics:nil views:viewsDict]];
// scrollViewContainer - child to topView
[topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[scrollViewContainer]-0-|" options:0 metrics:nil views:viewsDict]];
[topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[headerView]-0-[scrollViewContainer]" options:0 metrics:nil views:viewsDict]];
NSLayoutConstraint* pictureHeightConstraint = [NSLayoutConstraint constraintWithItem:scrollViewContainer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:pictureScrollHeight];
self.pictureHeightConstraint = pictureHeightConstraint;
[scrollViewContainer addConstraint:self.pictureHeightConstraint];
// bodyView - child to topView
[topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[bodyView]-0-|" options:0 metrics:nil views:viewsDict]];
[topView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V: [scrollViewContainer]-0-[bodyView]-0-|" options:0 metrics:nil views:viewsDict]];
}
- (void)updateViewConstraints
{
[super updateViewConstraints];
if ((newOrientation == UIDeviceOrientationLandscapeLeft) || (newOrientation == UIDeviceOrientationLandscapeRight)) {
pictureScrollHeight = 300;
} else {
pictureScrollHeight = 203;
}
CGFloat topViewHeight = bodyViewHeight + 55 + pictureScrollHeight;
self.pictureHeightConstraint.constant = pictureScrollHeight;
self.topViewHeightConstraint.constant = topViewHeight;
self.topViewWidthConstraint.constant = newBounds.width;
[self.pageScrollView setNeedsUpdateConstraints];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
newBounds = [self sizeInOrientation:toInterfaceOrientation];
}
-(CGSize)sizeInOrientation:(UIInterfaceOrientation)orientation
{
CGSize size = [UIScreen mainScreen].bounds.size;
UIApplication *application = [UIApplication sharedApplication];
if (UIInterfaceOrientationIsLandscape(orientation))
{
size = CGSizeMake(size.height, size.width);
}
if (application.statusBarHidden == NO)
{
size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height);
}
return size;
}
#end
ScrollView calculates its content size automatically depending on subviews constraints added into it. Off course it works only in autolayout enviroument.
Check the auto-resizing masks.
[self.pageScrollView setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
It looks like that you are NOT doing anything with the newBounds in willRotateToInterfaceOrientation. Shouldn't you call your updateView method after getting the new bounds.