Try to animate the width of a UIView like this. But it does not do anything. Why? The commented part changes alpha of the view, and that works.
UIView.animate(withDuration: 1, delay: 0, options: [.curveEaseInOut], animations: {
self.constraintLookupWidth.constant = 300
self.viewLookup.setNeedsLayout()
//self.viewLookup.alpha = 0.2
}, completion: {complete in
self.constraintLookupWidth.constant = 200
self.viewLookup.setNeedsLayout()
//self.viewLookup.alpha = 1.0
})
I guess that you need to integrate the call with a layoutIfNeeded(), this ask auto layout to force the layout right now.
Related
I'm trying to achieve some kind of "parallax" effect.
Let's say i have an image at the top of the screen, with height: 180 and a scrollview under it.
The initial state is:
state initial
When i scroll up more than 32 px, the image should "dock" up, like making his height 45px, and doing this animated.
The final state should be:
state final
In scrollViewDidEndDragging, i want to dock the image up, animated. I used the following code:
self.imageConstraint?.constant = 45.0
UIView.animate(withDuration: 1.0,
delay: 0,
options: [.beginFromCurrentState,
.allowAnimatedContent,
.allowUserInteraction],
animations: {
self.superview?.layoutIfNeeded()
}, completion: { _ in
completion()
})
The problem is that the image is set to 45 height, but only the image, and a blank space remains ( the initial height-final height ) and that space is animated.
Basically, with no deceleration, when scrollDidEndDragging i want to animate the height of the image and this does not work as expected.
Looks like this:
during animation
What i am doing wrong ?
Write your code in this way it will work hopefully,
UIView.animate(withDuration: 0.5)
{
self. self.imageConstraint.constant = 45.0
self.view.layoutIfNeeded();
}
Do let me if it doesn't. Thanks
I have code that animate a view (change constraints)
UIView .animate(withDuration: TimeInterval(duration), delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseInOut, animations: {
self.topConstraint!.constant = self.yPositioOfOpenPanel
self.superview?.layoutIfNeeded()
}
The strange behaviour is that on iPhone X layoutSubviews is called but on other simulators and real devices is not. (And I think it should be)
Same behaviour is when I change constraint manually
if let constraint = topConstraint {
constraint.constant = self.superview!.frame.height - recogniser.location(in: self.superview).y + yPositionOfBeginTouchInPanel
}
EDIT:
As suggested I am adding some new information.
Animations works very well, everything is animating as it should.
The problem is that I would like to trigger some new events, while animation is in place. (I would use topConstraint.constant to calculate something while animations is in place, or when I change topConstraint manually) That's why I would like to set some trigger on method layoutSubviews. This method should be triggered when animations changes subviews.
I think that this works prior iOS 11 (but I can't be 100% sure, because this functionality is new in my program, but as I can remember I use this in other programs and it worked). It is still working for iPhone X (Simulator) but not for other simulators or real devices (obviously the real iPhone X is not out yet).
I think you should slightly change the animation code:
// update constraints before you call animate
self.topConstraint!.constant = self.yPositioOfOpenPanel
// tell superview that the layout will need to be updated
self.superview?.setNeedsLayout()
UIView.animate(withDuration: TimeInterval(duration), delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseInOut, animations: {
// here you tell it to update the layout according to new constraints
self.superview?.layoutIfNeeded()
}
It turns out that I need to do is:
UIView .animate(withDuration: TimeInterval(duration), delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseInOut, animations: {
self.topConstraint!.constant = self.originalConstraintConstant
self.superview?.layoutIfNeeded()
self.layoutIfNeeded()
}
This triggered layoutIfNeeded inside this view.
But I still don't know why this works on all iPhones, and other works only on iPhone X. It should be a bug inside iOS or Xcode.
I am working on an apple watch application. In the application, I have a view where the user may swipe left and right between 3 given results. I am using WKInterfaceLabel to show result information. On each swipe, labels are updated with new text.
View screenshot:
I want to animate the change of text on swipe. How can I do this?
Any help provided will be appreciated.
Thanks!
This is not very elegant, but it should work:
You can fade out the contents of a WKInterfaceLabel, and fade in another label in its place. So, place 2 WKInterfaceLabel objects at the same place. One of them is visible (alpha = 1.0) and the other invisible (alpha = 0.0).
When you swipe, determine the new value that should be shown, and set it to the invisible label.
Then, animate the transition using the function animate(withDuration:animations:) of the WKInterfaceController. In the animation block, change the alpha values as required, something like
animateWithDuration(1.0) {
self.visibleLabel.setAlpha(0.0)
self.invisibleLabel.setAlpha(1.0)
}
Hope this helps!
try:-
func labelimage(img: UIImageView) {
print(labelrate.hidden)
if (labelrate.hidden) {
UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
self.labelrate.alpha = 1
}, completion: nil)
}
else {
UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
self.labelrate.alpha = 0
}, completion: nil)
}
self.labelrate.hidden = !self.labelrate.hidden
}
I have a UITextView and I want to scale it up and down with animation, I tried to scale it like other UIViews, like this:
self.textView.widthConstraint.constant = newWidth
UIView.animate(withDuration: 0.4, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
The animation is a bit weird: the text in the text view is always the same size from the beginning of the animation till the end, with the container scaling up the text simply goes from right to left.
What's the proper way to scale a UITextView along with the text it contains?
If you just want to animate the UITextView scaling, I think it would be better to use CGAffineTransform. You can do it something like this...
UIView.animate(withDuration: 0.4, animations: {
self.textView.transform = self.textView.transform.scaledBy(x: 0.2, y: 0.2)
})
Try this:
self.textView.widthConstraint.constant = newWidth
UIView.animate(withDuration: 0.4, animations: {
self.textView.layoutIfNeeded()
})
Update
According to this SO post answer, you have to use Affine Transform:
The Affine Transform scaling factor is applied to text like anything else. So the onscreen text size should be the nominal textsize times the scaling factor.
I'm making an app in swift using Xcode and I'm having troubles with the animation of some button.
Here's my situation:
I have three buttons in the middle of the screen where i've also added some constraints.
What i need is that when the button is clicked it reaches the top of the screen, like in this second photo with an animation:
I've tried this:
UIView.animateWithDuration(1, delay: 0, options: [], animations: {
self.Button2.center.y = 18 + self.Button2.frame.height/2
}, completion: nil)
But what happens is that the button appears from the bottom of the screen slides up to the position of the first photo. It doesn't respect the position I wrote in the animation. Is it possibile that this is due to the constraints? Because I centered it vertically and horizontally.
Can you help me to make it work?
When you work with autolayout and constraints you never make changes to the button frame in your animation, like your code: you must work always with constraints.
This is a generic example:
myButtonCenterYConstraint.constant = 200.0
myButton.layoutIfNeeded()
UIView.animateWithDuration(Double(0.5), animations: {
myButtonCenterYConstraint.constant = 0
myButton.layoutIfNeeded()
})
So, the first step is to declare the button constraints you will want to change as IBOutlets:
First get the center y of the button then reposition the button.
float centerY = self.Button2.center.y;
UIView.animateWithDuration(1, delay: 0, options: [], animations: {
self.Button2.center.y = centerY + 18 + self.Button2.frame.height/2
}, completion: nil)
You must change the constraint first and then update the UI in animation. Something like this.
yourButton.yourOriginConstraint'sYCoordinate.constant = // Set this to what you want to change.
// yes, you should create an IBOutlet for constraint that you want to modify.
UIView.animateWithDuration(1.0, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
Another way is to not user auto layout.
Here, is the reference