My app displays banner ads at the bottom of the screen.
Above these ads are several UIViews/UIImageViews etc.
If the user removes the ads, via IAP, there is an empty gap where the banner used to be, as expected.
However, I would like to move these views down vertically, so as to reduce the obvious gap in the screen.
The code I've been trying doesn't seem to be working -
UIView *moveView = [self.view viewWithTag:5];
CGRect frame = moveView.frame;
[moveView removeFromSuperview];
frame.origin.y = frame.origin.y + 25.0;
moveView.frame = frame;
[self.view addSubview:moveView];
The answer below suggested to remove autolayout, however I needed autolayout for my storyboard.
I simply needed to remove the autolayout for one UIView.
What I ended up using was
[moveView settranslatesautoresizingmaskintoconstraints:YES]
This simple line allowed me to move my view around without worrying about autolayout.
You can create an IBOutlet and connect it to a UIView in storyboard.
#property (nonatomic, retain) IBOutlet UIView *moveView;
then turn off auto layout in your storyboard.
Once that is done then try your code.
or try this
[moveView setFrame:CGRectMake(0,0,320,480)];
mmmbaileys is right.!!
Small Change:
[self.yourview setTranslatesAutoresizingMaskIntoConstraints:YES];
use this in viewDidLoad.
Related
I'm currently trying to put images in a UIScrollView.
I checked a lot for an answer, but none of the topics in stackoverflow works in my code. I guess I just forgot a detail in it, but can't figure it out.
So, I have in a ViewController.m this code:
- (void)initTransportData
{
_transportsData = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 654, 414, 82)];
CGRect viewSize = _transportsData.bounds;
UIImageView *imgView = [[UIImageView alloc] initWithFrame:viewSize];
[imgView setImage:[UIImage imageNamed:#"image.png"]];
[_transportsData addSubview:imgView];
}
My _transportData is defined in my ViewController.h like that:
#property (strong, nonatomic) IBOutlet UIScrollView *transportsData;
When i test it, the scrollView display a black color (i set it in my main.storyboard).
I also have a MapView above my scrollView (don't know if it can help to understand).
PS: I call my intTransportData function below [super viewDidLoad] in the viewDidLoad function.
Does anyone know what is wrong?
Thanks
You have set frame like (0, 654, 414, 82) that means your y position is 654 of scrollview. Then it is below the screen height.
So , set frame properly.
You need to add that scrollview to main view (self.view).
If you have given outlet then no need to set frame again.
You should use autolayout to manage this things easily.
Your scenario should be like, UIScrollview - UIView - UIImageView and you need to set proper constraint to every views. If you unaware of auto layout then search tutorials on google and first learn it.
Hope this will help :)
I have set a UIView in my storyboard and make it an outlet.
#property (nonatomic, weak) IBOutlet UIView *testView;
In the - (void)viewDidLoad method, I want to change its frame like this
CGRect frame = self.testView.frame;
frame.size.height = 2;
self.testView.frame = frame;
But it does not work. Anybody can tell me why?
You might enabled the autolayout in your project , if so the setFrame straightly won't work . Check here for more info
Solution :
Disable the autolayout, if you don't need any more
Check the above link using with the autolayout .
Look at the tiny circle to the left of the property. Is it filled in or hollow? If it's hollow, then it means that you have not connected this particular element of the storyboard to the file's owner.
If the circle is filled in, than the outlet IS connected to something on your storyboard. Just make sure it's connected to the right entity, namely the UIViewController (or subclass thereof) that you are declaring testView within.
Assuming its connected to your XIB do the following after changing the view -
[self.view setNeedsDisplay];
Trying changing the height to high number and see if that make a difference. I have created demo project for changing and reverting the height. Hope this helps.
https://github.com/rshankras/StackOverflowUIView
I have a UIViewController with a UICollectionView and a UIView at the bottom. The way I put it together is displayed in the image below
The yellow square is the UICollectionView and the red is the UIView. This works out just fine. But now I want to resize the UIView because it sometimes contains more info and needs to be bigger. So I tried this:
[self setFrame:CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height + 10)];
But this expands the UIView at the bottom and it is not visible. I guess this is because I do not have the correct constraints? I also tried to subtract the origin.y with the same amount and this works only the UICollectionView doesn't get resized with the new height. So how do I tackle this problem?
If you are using autolayout, you should not be setting the frame from your code. Instead you should modify the constant of a constraint that is causing your view to be the incorrect size. You can have an IBOutlet to that constraint and you can change it's constant property. Then call setNeedsLayout on your view controller's view
When setting constraints on your storyboard or in a xib file, animations perform animations on the constraints instead of the sizes and positions.
First create a outlet reference of the constraint which will change (in your case the top space of your UIView to the top layout guide) in the header file of your view controller.
When you want to animate a view, you now have to update its constraints and ask to layout the views.
For example :
[UIView animateWithDuration:0.2
animations:^{
viewYConstraint.constant -= 44;
[self.view layoutIfNeeded];
}
]
//Now don't forget to update constraints
[self.view updateConstraints];
I want to move a view from one postion to another, I can implement it using
self.view.center = CGPointMake(100, 200);
however, if the project is using Autolayout, then the view will be back to original position after running:
[self.view.superview setNeedsLayout];
then how to actually move a view to new position?
With AutoLayout enabled, we should FORGET FRAMES and only CONSIDER CONSTRAINTS.Yes, for animating also you can no longer change the frame or center, view's will revert back to their original position when layout is called.
Instead you should consider changing the constant value of the constraint to get the same effect.
Consider a User Interface like the image given below.I have a image view with a 20 points leading space from it's superview that means it has a horizontal space constraint with it's superview.Also I have three more constraints attached to that image view, top, width and height.
I will show you how we can animate the image from left to right as shown in the image.
Create IBOutlet's for the constraint's we need to animate.Here we are taking only horizontal space constraint, that is enough to move this view from the left to right.
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *horizontalSpaceConstraint;
Inside Go Away action, we need to update the constant value of this constraint.
- (IBAction)moveFrontAction:(id)sender {
self.horizontalSpaceConstraint.constant = 220;
[UIView animateWithDuration:0.5 animations:^{
[self.imageView layoutIfNeeded];
}];
}
Now the view should be moved to the right end.I'm just doing that inside a animation block so we will be able to see a nice animation from left to right and vice versa.In Production, we should not hard code the values like this.Just doing it here to make the concept clear.
Inside the Come Back action, we are again resetting the constant back to it's original value, so you can see the orange image animating back to the original location.
- (IBAction)moveBackAction:(id)sender {
self.horizontalSpaceConstraint.constant = 20;
[UIView animateWithDuration:0.5 animations:^{
[self.imageView layoutIfNeeded];
}];
}
You must change the constraints if you are using autoLayout. The way that is suggested is to make an outlet in your view controller of the constraint, then you change the constant of the constraint. If you have the time i would definitely recommend going here and watching "Auto Layout by Example" or "Best Practices for Mastering Auto Layout". They helped me out a lot. I guess the point to take away is that with autoLayout, you no longer think in terms of frames. So setting the center just doesnt work with auto layout. It's all about how views are related to each other.
I've never worked with autolayout constraints before. I have a small new app I'm working on and noticed that the NIB's views are defaulting to autolayout. So, I figured I'd take the opportunity to work with it and try to figure out where Apple is going with this.
First challenge:
I need to resize an MKMapView and I'd like to animate it to the new position. If I do this the way I'm used to:
[UIView animateWithDuration:1.2f
animations:^{
CGRect theFrame = worldView.frame;
CGRect newFrame = CGRectMake(theFrame.origin.x, theFrame.origin.y, theFrame.size.width, theFrame.size.height - 170);
worldView.frame = newFrame;
}];
...then the MKMapView will 'snap' back to its original height whenever a sibling view gets updated (in my case a UISegmentedControl's title is being updated [myUISegmentedControl setTitle:newTitle forSegmentAtIndex:0]).
So, what I think I want to do is change the constraints of the MKMapView from being equal to the parent view's hight to being relative to the top of the UISegmentedControl that it was covering: V:[MKMapView]-(16)-[UISegmentedControl]
What I want is for the MKMapView height to shorten so that some controls beneath the map view are revealed. To do so I think I need to change the constraint from a fixed full size view to one where the bottom is constrained to the top of a UISegmentedControl...and I'd like it to animate as view shrinks to new size.
How does one go about this?
Edit - this animation is not animating though the bottom of the view does move up 170 instantly:
[UIView animateWithDuration:1.2f
animations:^{
self.nibMapViewConstraint.constant = -170;
}];
and the nibMapViewConstraint is wired up in IB to the bottom Vertical Space constraint.
After updating your constraint:
[UIView animateWithDuration:0.5 animations:^{[self.view layoutIfNeeded];}];
Replace self.view with a reference to the containing view.
This works for me (Both iOS7 and iOS8+). Click on the auto layout constraint you would like to adjust (in interface builder e.g top constraint). Next make this an IBOutlet;
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *topConstraint;
Animate upwards;
self.topConstraint.constant = -100;
[self.viewToAnimate setNeedsUpdateConstraints];
[UIView animateWithDuration:1.5 animations:^{
[self.viewToAnimate layoutIfNeeded];
}];
Animate back to original place
self.topConstraint.constant = 0;
[self.viewToAnimate setNeedsUpdateConstraints];
[UIView animateWithDuration:1.5 animations:^{
[self.viewToAnimate layoutIfNeeded];
}];
There is a very good tutorial from apple itself that explain how to use animation with autolayout.
Follow this link and then find the video named "Auto layout by example"
It gives some interesting stuff about autolayout and the last part is about how to use animation.
I have made this small demo available. It shows how auto-layout constraints can be changed and animated in a very simple example. Simply take a look at the DemoViewController.m.
Most people use autolayout to layout items on their views and modify the layout constrains to create animations.
An easy way to do this without a lot of code is creating the UIView you want to animate in Storyboard and then creating a hidden UIView where you want the UIView to end. You can use the preview in xcode to make sure both UIViews are where you want them to be. After that, hide the ending UIView and swap the layout constraints.
There is a podfile for swapping layout constrains called SBP if you don't want to write it yourself.
Here's a tutorial.
No need to use more IBOutlet reference of the constraint instead of this you can directly access or update already applied constraint either applied by Programmatically or from Interface Builder on any view using the KVConstraintExtensionsMaster library. This library is also managing the Cumulative behavior of NSLayoutConstraint.
To add Height Constraint on containerView
CGFloat height = 200;
[self.containerView applyHeightConstrain:height];
To update Height Constraint of containerView with animation
[self.containerView accessAppliedConstraintByAttribute:NSLayoutAttributeHeight completion:^(NSLayoutConstraint *expectedConstraint){
if (expectedConstraint) {
expectedConstraint.constant = 100;
/* for the animation */
[self.containerView updateModifyConstraintsWithAnimation:NULL];
}
}];