I have a UIView ("myUIView") in my ViewController ("mainView") that has a UILabel ("myUILabel") inside, centered vertically with autolayout constraints. I'm animating this UIView to change its height.
Originally, I thought auto layout would keep track of the animation/change and keep the UILabel centered, but instead the UILabel acts as though it is constrained to the top of the UIView.
The UILabel isn't in the animation code itself. Code for reference:
UIView.animateWithDuration(currentAnimationTime, delay: 0.0, options: .CurveEaseOut, animations: {
self.myUIView.frame = CGRectMake(0, self.mainView.frame.height * 0.2, self.mainView.frame.width, self.mainView.frame.height * 0.6 )
}, completion: nil)
How can I increase the UIView's height and keep my UILabel entered vertically? Will I need to add something that directly affects the UILabel itself, or am I going about the resize itself (CGRectMake) all wrong?
I have had luck by calling layoutIfNeeded on the animated view inside the animation.
It would be preferable to create an outlet for the height constraint of the view and then set the constant of that constraint rather than constructing a CGRect. Change the constant outside the animation as demonstrated in this answer.
Related
I have a UIButton() in a textView.
let expanButtonHeight = bounds.size.height
expanButton.frame = CGRect(x: textView.bounds.size.width - expanButtonHeight, y: 0, width: expanButtonHeight, height: expanButtonHeight)
self.addSubview(expanButton)
self.layoutIfNeeded()
But when I type text in my textView the expanButton doesn't change. How do I keep the UIButton position fixed at right side of UITextView even when textView is growing in width?
This is the problem I'm facing:
I want the button to stay at end of textView:
With what you wish, I suggest you to have a UIView as a parent container of UITextView and UIButton. Your button should add to UIView instead of adding to UITextView. if the UITextView grow, make the parent container UIView grow as well and you can stick your UIButton at any place you want based on UIView.
I have an ViewController with a View called MasterView(it's the first UIView of the ViewController)
Inside the MasterView, I have a UIImageView, both views have a width of 320, take a look on the images below:
But when I try to get the image size programmatically, I use the following code:
/* imagemPrincipalCabeca is an IBOutlet connected to the UIImageView */
print("master uiview frame: \(view.frame.width)")
print("master uiview bounds: \(view.bounds.width)")
print("subview uiimageview frame: \(imagemPrincipalCabeca.frame.width)")
print("subview uiimageview bounds: \(imagemPrincipalCabeca.bounds.width)")
I got the following text on the console:
master uiview frame: 375.0
master uiview bounds: 375.0
subview uiimageview frame: 320.0
subview uiimageview bounds: 320.0
If the UIView width and the UIImageView on my code is 320. Why the view.frame.width results in 375 ?
I know the device screen in pixels is 375 and device points in screen is 320, but why I got different values when I use the code above?
Based on the #SWeeper comment.
I test the viewDidAppear method and viewDidLayoutSubviews method.
The viewDidAppear method didn't work for me,
but the viewDidLayoutSubviews method WORKED for me.
I use a ContainerView, maybe this is the reason why I need to use the viewDidLayoutSubviews method to make my code get the correct width of my view.
I have UITableview which has custom cells with UIImageViews. In the UITableview I am increasing the height of the cell using didSelectRowAtIndexPath method. Also i am adding method to increase cell height and revert to normal height.
When i tap on the cell the height is increasing , when i tap on the cell again (in order to make the tableviewcell return to default height) while in transition the image which is on tableviewcell is stays like its shown below and goes back to default height ..(i dont know how the image is being displayed while in transition)
-(void) zoomOutProperties
{
fruitImage.frame=CGRectMake(0.0, 46.0, 320.0, 83.5);
backgroundCellImage.frame=CGRectMake(0.0, 0.0, 320.0,129.5);
customCellView.frame=CGRectMake(0.0, 0.0, 320.0, 129.5); // UIView
}
Please note ::
[UIImage imageNamed:#""] caches the image. Instead use: [UIImage imageWithContentsOfFile:#""]
To make the image equal to the UIImageView size, you should use:
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
Refer: https://stackoverflow.com/a/9945160/667586
Your numbers for the frames don't add up very well. For instance, in zoomInProperties, you set fruitImage to have origin.y at 73.0, but its height is 82.5 (fractional pixels?) so it will end at 155.5, which is below the bottom of the customCellView which is 135.6. If the outer cell UIView is not set to clip, then the image will draw partly into the next cell.
Also, by setting the inner frames before setting the outer customCellView, you could have 2 changes to the sizes if they have autoResizeMask applied.
I am probably doing something extremely stupid but I cannot figure out why this does not work.
I am trying to perform a simple UIView block animation but have run into trouble. I have recreated in a test project.
I have a view on a View controller, when I press the button, I create a new view and set its frame to be out of the current view (above it). I want to animate the transition so that the view currently on the screen moves downwards out of the view as the new one above it comes down to take its place.
Here is the code which is hooked up to the button,
the original view is hooked up as self.view1
- (IBAction)buttonPressed:(id)sender {
UIView *view2 = [[UIView alloc] init];
view2.backgroundColor = [UIColor blueColor];
float offScreenY = 0 - self.view1.frame.size.height;
CGRect offScreenRect = CGRectMake(0, offScreenY, self.view1.frame.size.width, self.view1.frame.size.height);
view2.frame = offScreenRect;
[self.view addSubview:view2];
float oldY = self.view1.frame.origin.y + self.view1.frame.size.height;
CGRect oldRect = CGRectMake(0, oldY, self.view1.frame.size.width, self.view1.frame.size.height);
[UIView animateWithDuration:0.5 animations:^{
self.view1.frame = oldRect;
view2.frame = CGRectMake(0, 0, self.view1.frame.size.width, self.view1.frame.size.height);
}];
}
This just animates view2 down and does not animate view 1.
If I do not add view 2 as a subview and only put view1's frame change in the animation block then view1 animates correctly.
BUT they will not work together!
Why is this?
This is a classic symptom of having autolayout turned on. If you animate frame, it works, but as soon autolayout reapplies the constraints on the view, view1 will return to its original location. By adding view2, iOS automatically reapplies autolayout constraints immediately and your view1 therefore won't move.
Bottom line, don't use autolayout and try to animate frame properties directly. Two solutions:
The easy solution is to turn off autolayout. Go to IB, select the "File inspector" and uncheck the "Use Autolayout" button:
If you want to keep autolayout on, you shouldn't be animating by changing the frame properties directly. You would animate by change the layout constraint constants. This has been answered elsewhere on S.O., but if you need guidance on that approach, let me know.
The basic idea, though, is to create an IBOutlet for your top constraint for view1 called, say, view1TopConstraint, and then in your animation block you can say
self.view1TopConstraint.constant += self.view1.frame.size.height;
[self.view layoutIfNeeded];
For this to work, though, you'd have to be careful about your other constraints on view1 (e.g., have a height constraint, have no bottom constraint or if you have one, lower its priority, etc.). This can be a hassle the first time you do it, but you'll quickly get the hang of animating by changing constraints.
But, then again, if you're using constraints, you probably shouldn't be defining view2 by its frame, but probably defining constraints for that, too.
In this case it is better for you to have a container view.
Add view1 and view2 inside this container accordingly. Container's some part will be in the screen and container's frame size will be double of the size of a view. Animate the container, so the other two views will be animated accordingly..
I have a UIView with an alpha of 0.5 which I add as a subview to my primary view in order to gray-out everything else. I want to add an additional UIView to this gray UIView as a subview - the problem is that when I do this, my newly-added subview is also partially transparent.
Is there any way to make a subview "ignore" the alpha value of its superview and be itself fully opaque?
Set the UIView background color alpha not it's alpha directly.
Objective-C
UIView *view;
...
view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:.6];
It's not the same as:
view.backgroundColor = [UIColor blackColor];
view.alpha = .6;
Swift
view.backgroundColor = UIColor.black.withAlphaComponent(0.6)
No, not really. What you want is to take your overlay view, and make it just have a clear background color. As a subview of that new overlay place your view that will grey things out. And as a sibling view to that put your view you want to be opaque.
[OpaqueView] [DimmingView]
| |
[OverlayView]
Don't put it inside the semi-transparent view. Make it a sibling to semi-transparent view and put it over it using z-ordering.
This will only work if you have any image on the background.
Instead of reducing the alpha of UIView, add an UIImageView on that view and then reduce the alpha of the UIImageView.
now add your subviews on the UIView.
your subviews will not take the alpha property anymore.. :)
No, any view will inherit the opacity of its parent.