Set auto layout dynamically to scroll view in iOS - ios

i am creating scroll view dynamically now i want to set auto layout for that
i implemented following code to set auto layout but its not working at all.
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title=#"Insta SMS Collection";
scrollView = [[UIScrollView alloc]initWithFrame:self.view.frame];
[self.view addSubview:scrollView];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *views = #{#"scrollView":scrollView};
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:
[scrollView]"
options:kNilOptions
metrics:nil
views:views;
[self.view addSubview:scrollView];
}

add horizontal and vertical autolayout.
[self.view addSubview:scrollView];
NSDictionary *dictScrollConst = NSDictionaryOfVariableBindings(scrlView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[scrlView]|" options:0 metrics:nil views:dictScrollConst]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[scrlView]|" options:0 metrics:nil views:dictScrollConst]];
Maybe this will help you.

Related

How to add two views on each other with constraints

I am trying to add 2 views with same X, Y. They have space from the edge using addConstraints:[NSLayoutConstraint constraintsWithVisualFormat...]
I tried the strings "H:|20-[A][B]-20-[C]-20-[D]-20|" and V:|20-[A][B]-20-[C]-20-[D]-20|, and centreX == CenterX and centerY==centerY, but they kept conflicting, thinking that A and B should be next to each other.
A is hidden, and on some button clicked, B is hidden and A is shown.
To add views with same centre X,Y You need to first place one of the view say bView (Bottom view), using constatins
NSArray * bVerticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"|-20-[bView]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(bView)];
NSArray * bHorizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-20-[bView]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(bView)];
This places the bView in the superview with 20 as edge offset.
Now place the tView (top View) with same centre as of bView. Here self is the superview of bView and tView
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[bView]-(<=1)-[tView]" options:NSLayoutFormatAlignAllCenterX metrics:nil views:NSDictionaryOfVariableBindings(bView,tView)]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[bView]-(<=1)-[tView]" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(bView,tView)]];
Then pin the edges of tView with desired offset say 40
NSArray * tVerticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"|-40-[tView]-40-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(tView)];
NSArray * tHorizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-40-[tView]-40-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(tView)];
EDIT :
Here is how do do it.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
bView = [UIView new];
bView.backgroundColor = [UIColor redColor];
bView.translatesAutoresizingMaskIntoConstraints = NO;
tView = [UIView new];
tView.backgroundColor = [UIColor blackColor];
tView.translatesAutoresizingMaskIntoConstraints = NO;
// Firdt bView is added then tView hence tView is exaclty above the bView.
[self.view addSubview:bView];
[self.view addSubview:tView];
// Edges Constrints for bView
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"|-20-[bView]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(bView)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-20-[bView]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(bView)]];
// Edges Constints for tView
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"|-20-[tView]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(tView)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-20-[tView]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(tView)]];
// Centring for bView and tView
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[bView]-(<=1)-[tView]" options:NSLayoutFormatAlignAllCenterX metrics:nil views:NSDictionaryOfVariableBindings(bView,tView)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:[bView]-(<=1)-[tView]" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(bView,tView)]];
}
-(IBAction)toggleViews:(id)sender {
NSArray * subViews = self.view.subviews;
[self.view exchangeSubviewAtIndex:[subViews indexOfObject:tView] withSubviewAtIndex:[subViews indexOfObject:bView]];
}

Adding a subview to a view controller messes up with a table view

I have a UIViewController that has a UITableView as a subview. I want to add a background view under the table view but when I add it, the controller's edgesForExtendedLayout seem to be messed up
This is correct:
This is not correct:
My viewDidLoad method looks like this. If I do not add the subview, all looks ok.
- (void)viewDidLoad
{
[super viewDidLoad];
// UITableView
self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
self.tableView.translatesAutoresizingMaskIntoConstraints = NO;
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:TAManeuvreCellId];
[self.view addSubview:self.tableView];
UIView *backgroundBlurView = [[UIView alloc] init];
// autolayout
backgroundBlurView.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *views = NSDictionaryOfVariableBindings(backgroundBlurView, _tableView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[_tableView]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[_tableView]|" options:0 metrics:nil views:views]];
// comment this and everything is ok
[self.view addSubview:backgroundBlurView];
[self.view sendSubviewToBack:backgroundBlurView];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[backgroundBlurView]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[backgroundBlurView]|" options:0 metrics:nil views:views]];
}
I think the fix for this is setting:
self.navigationController.navigationBar.translucent = FALSE;
self.edgesForExtendedLayout = UIRectEdgeNone;
See:
How to prevent UINavigationBar from covering top of view in iOS 7?
iOS 7 UIImagePickerController navigationbar overlap

UIScrollView does not scroll with AutoLayout

I can't make UIScrollView scroll vertically when using Autolayout, I've tried many suggestions. I've read Apple's technical note but even that doesn't seem to work with my pure auto layout approach.
Here is my simple code where I'm adding two UIView blocks1 & 2 in a container view. The container view itself is the only child of the UIScrollView as suggested by many references online. I set the heights of block 1 and 2 as 800 points each, but the scroll view won't scroll.
- (void)viewDidLoad {
[super viewDidLoad];
// Test UIScrollView with Autolayout, scrolling should word
UIView *mainView = self.view;
UIScrollView* scrollView = [UIScrollView new];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
scrollView.backgroundColor = [UIColor redColor];
[self.view addSubview:scrollView];
UIView* contentView = [UIView new];
contentView.translatesAutoresizingMaskIntoConstraints = NO;
contentView.backgroundColor = [UIColor greenColor];
[scrollView addSubview:contentView];
UIView* block1 = [[UIView alloc] init];
block1.translatesAutoresizingMaskIntoConstraints = NO;
[block1 setBackgroundColor:[UIColor blackColor]];
[contentView addSubview:block1];
UIView* block2 = [[UIView alloc] init];
block2.translatesAutoresizingMaskIntoConstraints = NO;
[block2 setBackgroundColor:[UIColor blackColor]];
[contentView addSubview:block2];
NSDictionary* viewDict = NSDictionaryOfVariableBindings(mainView,scrollView, contentView, block1, block2);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[scrollView]|" options:0 metrics:0 views:viewDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[scrollView]|" options:0 metrics:0 views:viewDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[contentView(==mainView)]|" options:0 metrics:0 views:viewDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[contentView(==mainView)]|" options:0 metrics:0 views:viewDict]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[block1(==300)]" options:0 metrics:0 views:viewDict]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[block1(==800)]" options:0 metrics:0 views:viewDict]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[block2(==300)]" options:0 metrics:0 views:viewDict]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-810-[block2(==800)]" options:0 metrics:0 views:viewDict]];
}
Looking to your code, It seems that the size of you content view will be of same size as UIView.
e.g. : IF Device screen height is 568 then your content view size will be 568, and you are set your block2 at y position = 180.
Your Code:
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[contentView(==mainView)]|" options:0 metrics:0 views:viewDict]];
change:
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[contentView(2000)]|” options:0 metrics:0 views:viewDict]];
Hope it solves your problem if any further query please let me know.
If all you want to do is make a scroll view work with auto layouts, you can try this.
http://natashatherobot.com/ios-autolayout-scrollview/
Do the following changes in your code
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[contentView]|" options:0 metrics:0 views:viewDict]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-810-[block2(==800)]|" options:0 metrics:0 views:viewDict]];
Hope this helps

Adding a background imageview programmatically with autolayout

I need to add a background image view for my views for a project I've done using storyboards + autolayout. I want to add this image programmatically using code. so basically it should be from top layoutguide to bottom layoutguide, without going under them. I've tried few ways which failed horribly.
one way I first adjust the VC'c view before adding like this
id topGuide = self.topLayoutGuide;
UIView *superView = self.view;
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings (superView, topGuide);
[self.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:#"V:[topGuide]-20-[superView]"
options:0
metrics:nil
views:viewsDictionary]
];
[self.view layoutSubviews];
but for some reason my imageview still goes under statusbar.
this is how I add the bg imageview
self.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Default"]];
self.backgroundView.contentMode = UIViewContentModeTop;
[self.view insertSubview:self.backgroundView atIndex:0];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[backgroundImageView]|" options:0 metrics:nil views:#{#"backgroundImageView":self.backgroundView}]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[backgroundImageView]|" options:0 metrics:nil views:#{#"backgroundImageView":self.backgroundView}]];
Adding the constraint related to the topLayoutGuide to self.view is useless. The view controller layout its root view (self.view) independently from AutoLayout, and will override the constraints effects (don't quote me on this, this is an observation more than a real understanding of the layout system).
Instead, add the first constraint (#"V:[topGuide]-20-[superView]") to self.backgroundView:
self.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Default"]];
self.backgroundView.contentMode = UIViewContentModeTop;
[self.view insertSubview:self.backgroundView atIndex:0];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[topGuide]-(20)-[backgroundImageView]|" options:0 metrics:nil views:#{#"backgroundImageView":self.backgroundView, #"topGuide": self.topLayoutGuide}]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[backgroundImageView]|" options:0 metrics:nil views:#{#"backgroundImageView":self.backgroundView}]];
[self.view layoutSubviews];

Autolayout issue with top & bottom layout guide

I have some problem to set NSLayoutconstraints programmatically from my view and controller.topLayoutGuide & controller.bottomLayoutGuide.
with this code in viewDidLoad:
_mainView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_mainView];
[self.view removeConstraints:self.view.constraints];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[_mainView]-0-|" options:NSLayoutFormatAlignAllBaseline metrics:nil views:NSDictionaryOfVariableBindings(_mainView)]];
id top = self.topLayoutGuide;
id bottom = self.bottomLayoutGuide;
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[top]-0-[_mainView]-0-[bottom]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(top, _mainView, bottom)]];
[self.view layoutSubviews];
the result is that:
(_mainView has dark gray background color)
if i set up the constraints relative to the superview it works:
_mainView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_mainView];
[self.view removeConstraints:self.view.constraints];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[_mainView]-0-|" options:NSLayoutFormatAlignAllBaseline metrics:nil views:NSDictionaryOfVariableBindings(_mainView)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[_mainView]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_mainView)]];
[self.view layoutSubviews];
where is my error?
the view controller hierarchy is uitabbarcontroller -> uinavigationController -> myViewController
SOLVED!
the error was:
[self.view removeConstraints:self.view.constraints];
I changed the code with
for(NSLayoutConstraint *c in self.view.constraints)
if(c.firstItem == _mainView || c.secondItem == _mainView)
[self.view removeConstraint:c];
and it worked.
thanks anyway! ;)
Check if self.topLayoutGuide and self.bottomLayoutGuide is not nil. You might have forgotten to set the outlet in Interface Builder.

Resources