I'm trying to make a very simple login page. Everything is fine, until I started doing some animations.
When I click login button, I move the logo 100px to the top, then I show the inputs.
That worked correctly, but when I click the textfield to edit it, the image (logo) returns to its original position!
My code:
#IBAction func LoginClick(sender: AnyObject) {
UIView.animateWithDuration(2, animations: {
var center = self.logoImage.center
center.y -= 100
self.logoImage.center = center
self.usernameInput.hidden=false
self.passwordInput.hidden=false
self.usernameLine.hidden=false
self.passwordLine.hidden=false
self.slidesImg.hidden=true
})
}
Auto Layout is running and placing your logo back to where the constraints say it should be. Instead of modifying the frame by changing the center, you should create an IBOutlet to the vertical space constraint and then update the constant property to move your logo up.
To create the IBOutlet, first click on the vertical bar that represents the vertical constraint in the Storyboard. Then control-click on the constraint and drag to your viewController code. Give it a name like topSpace.
You'll need to call layoutIfNeeded() to animate the constraint change:
#IBOutlet weak var topSpace: NSLayoutConstraint!
#IBAction func LoginClick(sender: AnyObject) {
topSpace.constant -= 100
UIView.animateWithDuration(2, animations: {
self.logoImage.layoutIfNeeded()
self.usernameInput.hidden=false
self.passwordInput.hidden=false
self.usernameLine.hidden=false
self.passwordLine.hidden=false
self.slidesImg.hidden=true
})
}
Related
I am making a function that the height of a UIView increases and decreases when a button is pressed.
When the height of the UIView was reduced, the value created a layout in the storyboard, When the height of the UIView is increased, the value will be the height of the UITextView.
The picture above is before the UIView is stretched. Press the button at the bottom of the photo to stretch the UIView
The picture above is after the UIView is stretched. If you press the button at the bottom of the picture above, the UIView will shrink again.
The first thing I am curious about is the code to make the height of the UIView increase.
#IBOutlet weak var bookInfoView: UIView!
#IBOutlet weak var bookInfoVieweBtn: UIButton!
#IBOutlet weak var bookInfoTextView: UITextView!
#IBAction func bookInfoViewBtnTapped(_ sender: Any) {
print("##bookInfoViewBtnTapped!")
let f = bookInfoView.frame
let textView = bookInfoTextView.frame
bookInfoView.frame = CGRect(x: f.origin.x, y: f.origin.y, width: f.width, height: textView.height)
}
If you press the button using the code above, it does nothing. What should I do?
1.Set some default value for the height of your the view your are trying to expand. Then if you are using StoryBoard make an IBOutlet to your ViewConroller, and remove the weak reference (that's because we are going to deactivate the height anchor and if it is weak and you deactivate it, the ARC will dealocate it. If your are going for it programatically just store the height anchor in a local variable. So it should like something like this:
#IBOutlet var yourViewHeightAnchor: NSLayoutConstraint!
2. Add a target to your button or if your using StoryBoard or Xib drag a IBAction to you ViewController. When the button is clicked, your only job is to deactive/active the height anchor. ( The activation will serve for collapse)
#IBAction func expandClicked(_ sender: Any) {
yourViewHeightAnchor.isActive.toggle()
}
If you wish to use some animation for expanding/collapsing, your expandClicked function should look something like this:
#IBAction func expandClicked(_ sender: Any) {
UIView.animate(withDuration: 0.6, animations: {
self.yourViewHeightAnchor.isActive.toggle()
self.view.layoutIfNeeded()
})
}
Follow below steps:-
Define height constraint in your storyboard.
create IBOutlet of height constraint
Then on button press, increase/decresse your height of textview like:-
textViewHeightConstant.constant = someValue
I really can't figure out what's wrong with my code. Let me explain in detail what was my aim:
I have two UIView in the same UIViewController. They're called "redSquare" and "greenSquare".
When the UIViewController is presented I want to animate the redSquare in order to move on the Y-axis till it reaches the top-border of the greenSquare.
This is how I set the xCode project:
The behavior that I got is completely the opposite and I really can't understand why and what's happening:
Any tips or explanations for this?
Okay. Part of the problem is that you're aligning the center Y... which means that you're trying to break constraints with your animation.
Another part of the problem is that you are doing your animation in viewDidLoad, which totally runs before viewWillAppear and viewDidAppear get called.
For my own animations, I usually animate a constraint.
That is, get rid of the center-Y constraint for your red box and add a new constraint putting the red box some Y distance from the bottom of the superview. Connect this new constraint to an outlet and then you can animate like this:
#IBOutlet weak var redYConstraint : NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
// This line sets the red box to be in the center Y of the green box
self.redYConstraint.constant = self.greenSquare.frame.midY
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.animate(withDuration: 3.0, delay: 2.0, options: UIViewAnimationOptions.curveEaseIn, animations: {
self.redYConstraint.constant = self.greenSquare.frame.maxY
self.view.layoutIfNeeded()
}, completion: nil)
}
I need to figure out how to program something like this:
The text expands as the user clicks the down button and fold back to the short version after clicking up. Are there any libraries I could study? I am a beginner in programming and just need advice on how to approach this task, what guides to study and so on.
All you have to do is initially set the UILabel to have a numberOfLines of lets say 7 and line break mode to be .byTruncatingTail.
Then on button click simply change the numberOfLines to 0 and line break mode to be .byWordWrapping. Then when you wish to hide the text, just press the button and set the UILabel to its initial values.
To solve this issue read about AutoLayout. This is small example how it is possible to do.
This is coding part. This class contain IBOutlet for the height of the UITextView and button action.
class ViewController: UIViewController {
let defaultHeight = 128
let expectedHeight = 600
var state: Bool = false
#IBOutlet weak var height: NSLayoutConstraint!
#IBAction func showAction(_ sender: Any) {
UIView.animate(withDuration: 0.3, animations: {
self.state = !self.state
self.height.constant = CGFloat(self.state ? self.expectedHeight: self.defaultHeight)
self.view.layoutIfNeeded()
})
}
}
This is from storyboard.
You can set an height constraint for your UILabel, and on the tap button event change the constraint constant to the contentsize of your label.
After your can animate it with
UIView.animate(duration)
I want to animate UITextField from center to top of the view on a button click. TextField has following constraints
Following is the code to on button click to move textfiled to top.
UIView.animateWithDuration(0.5) {
self.txtfield.center.y = 10
}
above code works, textfiled moved to top but when I go back and come to this view again textfield is again in center. I am new to swift I want that once textfield is moved to top it should stay on top.
You should get a reference to the constraint in your code. Then you change the constant value of the constraint instead.
I have added the code to move the text field to top in viewDidLoad but you will of course have this code in your button action. You have to drag from the "Align Center Y" and into your view controller in order to create a reference to the constraint. The reason why I subtract 10 is because your example and intention was to have a 10 points margin from the top. And take note that I "reversed" the first and second item like this:
Remember that when you use auto layout, the frame and center and the size of the views bounds get set by auto layout constraints.
class ViewController: UIViewController {
#IBOutlet weak var textFieldYAlignConstraint: NSLayoutConstraint!
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
UIView.animateWithDuration(1.2) { () -> Void in
self.centeraligntConstraint.constant = -400
self.view.layoutIfNeeded()// to animate layout constraint
}
}
}
So this is what I am trying to do:
Here is the initial screen:
When the bottom pointing arrow is clicked there is a smaller view that transitions from bottom to top like this:
And as you can see the view in the back is dimmed. And when I click on the back view, the smaller sized view goes away by animating downwards.
There were several things that I tried:
1. I tried to segue modally which seemed to animate properly, namely, from bottom to top, but it covers the entire back view.
2. I tried to make the modal view only half the parent size by trying to replicate this post: Present modal view controller in half size parent controller. However, it did not work.
3. So I decided to put a UIView on top of my back view like so:
And I connected the grey colored view with the #IBOutlet weak var messageView: UIView!. And I tried using this code: UIView.transitionWithView(messageView, duration: 1.0, options: UIViewAnimationOptions.CurveEaseIn, animations: nil, completion: nil). However, nothing seems to be happening. Any suggestions on how to accomplish this?
For the Animation of button:
Add autolayout constraint to the BottomLayout Guide.And create an IBOutlet as
#IBOutlet weak var bottomConstraint: NSLayoutConstraint!
var shouldAnimateView:Bool = true
On the Action of the button you need to animate the View using constraint
#IBAction func showOrHideViewBtn(sender: AnyObject) {
if shouldAnimateView {
self.bottomConstraint.constant = self.view.frame.size.height/2+5
UIView.animateWithDuration(Double(0.2), animations: {
self.bottomConstraint.constant = self.view.frame.size.height/2 - self.toanimateView.frame.size.height
self.view.layoutIfNeeded()
})
}else{
self.bottomConstraint.constant = self.view.frame.size.height/2 - self.toanimateView.frame.size.height
UIView.animateWithDuration(Double(0.2), animations: {
self.bottomConstraint.constant = self.view.frame.size.height/2+5
self.view.layoutIfNeeded()
})
}
shouldAnimateView = !shouldAnimateView
}