Subview visible but frame outside superview frame - ios

I have a parent VC that loads a child VC inside it. Code in parent VC is as follows:
self.draggerViewController = [[DraggerViewController alloc] initWithSuperView:self.view];
And the code of the child VC is as follows:
- (instancetype)initWithSuperView:(UIView*)superView {
self = [super init];
if (self) {
self.superView = superView;
[self.view setTranslatesAutoresizingMaskIntoConstraints:NO];
[superView addSubview:self.view];
[superView addConstraint:[NSLayoutConstraint constraintWithItem:superView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:0]];
[superView addConstraint:[NSLayoutConstraint constraintWithItem:superView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]];
self.constraintDraggerAttributeBottom = [NSLayoutConstraint constraintWithItem:superView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
[superView addConstraint:self.constraintDraggerAttributeBottom];
}
return self;
}
With this code, the subview is visible on its parent view and constraints are applied correctly so that it is placed at the bottom of the parent view with leading and trailing being 0. BUT, the real frame of the view is outside the parent view.
That is, I can see the subview at the bottom of the parent view but the frame of this subview is frame = (0 -315; 768 35).
If I set 'clipToBounds' to 'YES', the view is placed on the real frame but now constraints are not applied correctly.
How can I place this child VC inside the parent VC's view at the position I want using constraints?
Thank you!

OK, got it...
I was forgetting the height constraint of the view... What a shame...
[superView addConstraint:[NSLayoutConstraint constraintWithItem:superView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:1 constant:0]];
Thank you all!

Try this :
superView.insertSubview(self.view, at: self. superView.subviews.count)

Related

Center view inside another view

I have a view called profile which is taking (0,0,320,60) size in storyboard which is taking full width but 60 height, and i am trying to place another view called ranking inside it at the center and what ever the device is iPhone4s,5s,6s,6 it should just take my view and put it at the center.
Here is what i tried:
ranking.frame = CGRectMake(0, 0, 120, 60);
ranking.center = self.Profile.center;
The current code is not centering my view In all devices. what can i do to do it dynamically ?
You can use AutoLayout with the following method:
+ (void)centerView:(UIView *)view inContainerView:(UIView *)containerView withSuperView:(UIView *)superView
{
[superView addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:containerView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
[superView addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:containerView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
}
You can add the method above in your ViewController or in a helper class.
Remember to set the translatesAutoresizingMaskIntoConstraints property to false before using AutoLayout on your view.
So if ranking is your subview and self.Profile is your superView you can do the following.
UIView *ranking = [[UIView alloc] init];
ranking.translatesAutoresizingMaskIntoConstraints = false;
[self.Profile addSubview:ranking];
[[self class] centerView:ranking inContainerView:self.Profile withSuperView:self.Profile];
[self.Profile addConstraint:[NSLayoutConstraint constraintWithItem:ranking attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:120]];
[self.Profile addConstraint:[NSLayoutConstraint constraintWithItem:ranking attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:60]];

How to add layout for subview and subview button label step by step in ios?

How to add constraint for subview of view controller
explain briefly
// create a new view
self.containerView = [UIView new];
// before adding constraints always add respective view to superview
[self.view addSubview:self.containerView];
[self.containerView setTranslatesAutoresizingMaskIntoConstraints:false];
// add container on newly added view
NSLayoutConstraint *topConstraintContainer = [NSLayoutConstraint constraintWithItem:self.containerView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.topLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
NSLayoutConstraint *leadingConstraintContainer = [NSLayoutConstraint constraintWithItem:self.containerView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.containerView.superview attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0];
NSLayoutConstraint *trailingConstraintContainer = [NSLayoutConstraint constraintWithItem:self.containerView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.containerView.superview attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0];
NSLayoutConstraint *bottomConstraintContainer = [NSLayoutConstraint constraintWithItem:self.containerView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.bottomLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
// add constraint to superview of respective view
[self.view addConstraints:#[topConstraintContainer,leadingConstraintContainer,trailingConstraintContainer,bottomConstraintContainer]];
There are alot of possibilities, but this is the main flow
Also there are third party libraries available which makes adding constraints easier, like
PureLayout

Facebook Audience Network ios FBAdView width

I added a FBAdView to a UIView in the view controller.
(I set the view background to red)
the FBAdView was created with adSize of kFBAdSizeHeight50Banner.
The problem is that the FBAdView calculates its width when it is being added, but after rotating the device it doesn't calculate its width again
I tried using autolayout but it didn't work
code for adding the FBAdview (Adding to UILabel with red backgroud)
FBAdView *fbAdView = [[FBAdView alloc] initWithPlacementID:#"***************_***************"
adSize:kFBAdSizeHeight50Banner
rootViewController:self];
fbAdView.delegate = self;
[fbAdView loadAd];
[self.banner addSubview:fbAdView];
code for autolayout - doesn't work
// Width constraint, parent view width
[self.banner addConstraint:[NSLayoutConstraint constraintWithItem:fbAdView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.banner
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0]];
// Height constraint, parent view height
[self.banner addConstraint:[NSLayoutConstraint constraintWithItem:fbAdView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.banner
attribute:NSLayoutAttributeHeight
multiplier:1
constant:0]];
// Center horizontally
[self.banner addConstraint:[NSLayoutConstraint constraintWithItem:fbAdView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.banner
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
// Center vertically
[self.banner addConstraint:[NSLayoutConstraint constraintWithItem:fbAdView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.banner
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];
print screen
when the banner is added it fit the screen width
after rotating it doesn't change its width (like its parent red view)
I think you're missing some constraints.
Adding these lines (might need some minor changes) makes your code work:
self.banner.translatesAutoresizingMaskIntoConstraints = NO;
fbAdView.translatesAutoresizingMaskIntoConstraints = NO;
// Width constraint
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.banner
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0]];
// Height constraint
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[banner(==50)]"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(banner)]];
I've posted a sample project at https://github.com/overlordnyaldee/BannerAutoLayout

iOS: Autolayout: Lock new position after animating

I tried to write a category function for UIView that will get the constraints that will hold an given frame in place in its superview. I implemented it like so:
-(NSArray *)constraintsForLockingPositionInSuperview
{
NSLayoutConstraint *left=[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.superview
attribute:NSLayoutAttributeLeft multiplier:0 constant:self.frame.origin.x];
NSLayoutConstraint *height=[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:Nil
attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:self.frame.size.height];
NSLayoutConstraint *width=[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:Nil
attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:self.frame.size.width];
NSLayoutConstraint *top=[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.superview
attribute:NSLayoutAttributeTop multiplier:0 constant:self.frame.origin.y];
return #[left,height,width,top ];
}
And then after animating the view, apply to new constraints by doing the following in the view controller that contains the view in question. I remove the view then re-add it to remove the constraints that were on it, then reapply the new constraints. The hope was that this would hold the view in place if I add another subview or if something like an actionView comes in and the view has to layout itself out. The height and the width seem to be locking properly, but the view is jumping to the middle instead of locking in place:
NSArray *lockingConstraints = [someView constraintsForLockingPositionInSuperview];
[someView removeFromSuperview];
[self.view addSubview:someView;
[self.view addConstraints:lockingConstraints];
[self.view layoutSubviews];
From the documentation for layoutSubviews:
You should not call this method directly.
Call layoutIfNeeded instead.

Autolayout: Adding a view break my otherwise working resizing - ideas?

In my app, I have the following setup:
TextView (self.textView)
Toolbar
When the keyboard become visible, I add a constraint that pushes the bottom of the text view up with the required number of pixels.
spacer =[NSLayoutConstraint
constraintWithItem:self.textView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-height];
[self.view addConstraint:spacer];
When the keyboard disappears, I remove the constraint.
THIS WORKS FINE. However...
I want to add an imageview that lies on top of the text view. This seems straightforward. But now the "dismiss keyboard" resize is broken.
Here's the code I use to create the imageview, and pin it to the textview bounds.
self.overlay = [[UIImageView alloc] init];
[self.overlay setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:self.overlay];
[self.view addConstraint: [NSLayoutConstraint
constraintWithItem:self.overlay
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.textView
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0]];
[self.view addConstraint: [NSLayoutConstraint
constraintWithItem:self.overlay
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.textView
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0]];
[self.view addConstraint: [NSLayoutConstraint
constraintWithItem:self.overlay
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:self.textView
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:0]];
[self.view addConstraint: [NSLayoutConstraint
constraintWithItem:self.overlay
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:self.textView
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:0]];
[self.view layoutIfNeeded];
Here's how it should look:
Initial before keyboard showing
Keyboard showing
Keyboard removed. Layout should be back to initial state, but instead I get this
Solution: Set the content hugging priority for the tool bar to 1.000 to avoid that it gets all stretched out.

Resources