When I start typing in uitextfield i want some animation to happen and it should not reverse back until i finish typing. I am using this code to animate:
func textFieldDidBeginEditing(textField: UITextField) {
println("begin")
UIView.animateWithDuration(1.0, animations:{
self.secondTextfield.frame = CGRectMake(self.secondTextfield.frame.origin.x + 500, self.secondTextfield.frame.origin.y, self.secondTextfield.frame.size.width, self.venueTextField.frame.size.height)
})
}
What I want to do is: when i start typing in first textfield, i want the second text field to hide out from view and when i finish typing, i want it to animate back in.
What my issue is: When I start typing the animation happens and it comes back to the original position.It doesn't wait for me to finish typing.
Why not change alpha to 0, intead change its frame?
You need to identify witch textfield is editing.
You need to deal with textFieldDidEndEditing to get second textField back.
Example:
func textFieldDidBeginEditing(textField: UITextField) {
if textField == firstTextField {
UIView.animateWithDuration(1.0, animations:{
self.secondTextfield.alpha = 0
})
}
}
func textFieldDidEndEditing(textField: UITextField) {
if textField == firstTextField {
UIView.animateWithDuration(1.0, animations:{
self.secondTextfield.alpha = 1
})
}
}
While not knowing exactly what the problem is, I've found a reasonable alternative to solving your problem:
Instead of animating your frame, animate the auto-layout constraint that defines your textField's x coordinate. For instance, the image below consists of two textFields. I want to animate the bottom one when I begin typing in the top one:
The vertical constraint is a centre x alignment that I want to animate. To achieve the effect, I connected an #IBOutlet to my NSLayoutConstraint:
I had my view controller adopt UITextFieldDelegate and implemented three methods:
extension ViewController: UITextFieldDelegate {
func textFieldDidBeginEditing(textField: UITextField) {
self.c.constant += 100 //c is my constraint
UIView.animateWithDuration(1.0) {
self.view.layoutIfNeeded()
}
}
func textFieldDidEndEditing(textField: UITextField) {
println("textFieldDidEndEditing")
self.c.constant -= 100
UIView.animateWithDuration(1.0) {
self.view.layoutIfNeeded()
}
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
a.resignFirstResponder()
return true
}
}
This method needs a bit of auto-layout know how, but I was able to achieve the effect you desired.
Related
I am using swift in a storyboad application, and I would like it to, when a user enters the box (IE, when it becomes the first responder) to enter text it highlights all the text. What is done in most web browsers. Here is what I have tried, which has not worked:
func textFieldDidBeginEditing(_ textField: UITextField) {
// textField.selectAll(nil)
print("click 2")
// textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)
}
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
print("click 1")
// textField.selectAll(nil)
// textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)
return true
}
Making a button that runs this code does actually work, but I want it to be when you click on the field. Making an invisible button on top seems like a bad idea. I've tried other variations of this as well, but none have worked for me.
UPDATE: What I've ended up doing was making an invisible button on top of the existing text field, and then making that select the text. It may be a little janky but it works perfectly so I have no problems with that solution anymore. Extra code:
#IBAction func seachBtnClicked(_ sender: Any) {
//The invisible button over the search bar has been clicked
search.selectAll(nil)
searchBtn.isHidden = true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
//Return has been pressed, so we are going to load a new page
processInput()
//This does mean that it only comes back if you press enter,
//but right now I think that's how I want it.
//Could change it to be in the textFieldDidEndEditing() function to change that
searchBtn.isHidden = false
return true
}
You are probably just missing the textField.delegate = self for your textfield. The first of the two functions, func textFieldDidBeginEditing(_ textField: UITextField) is the one that is always performed as soon as a textfield is tapped on to focus on it.
Try adding yourTextField.delegate = self in your viewDidLoad function and see if that works out.
What I've ended up doing was making an invisible button on top of the existing text field, and then making that select the text. It may be a little janky but it works perfectly so I have no problems with that solution anymore. Extra code:
#IBAction func seachBtnClicked(_ sender: Any) {
//The invisible button over the search bar has been clicked
search.selectAll(nil)
searchBtn.isHidden = true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
//Return has been pressed, so we are going to load a new page
processInput()
//This does mean that it only comes back if you press enter,
//but right now I think that's how I want it.
//Could change it to be in the textFieldDidEndEditing() function to change that
searchBtn.isHidden = false
return true
}
I have listed the important code, I have omitted the other irrelevant
extension OpenVIPSearchInputView{
func showSearchBtn(){
UIView.animate(withDuration: 1) {
self.proviceButton.snp.updateConstraints {
$0.leading.equalTo(self).offset(50)
}
self.searchButton.snp.updateConstraints {
$0.trailing.equalTo(self).offset(-200)
}
self.layoutIfNeeded()
}
}
}
extension OpenVIPSearchInputView: UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
showSearchBtn()
}
}
I customized this control, and wanted to animate the buttons in it. I updated the two constraints, but only one button was animated after the chase. I'm confused, I don't know what happened.
Try putting every action to separate UIView.animate(withDuration: 1) {}
I have a view (grey background) and another over it with a UITextField.
When I tap on the grey background, I want the view with the UITextField to disappear with an animation (move to top)
When I tap on the return key (virtual keyboard) the animation is smooth, but when I tap on the grey background, it disappears without animation. When I comment out the vueRecherche.isHidden = true in the completion, it's ok, but I want to hide it!
here is my function
private func fermeRecherche() {
if self.constraintVueRecherche_Top.constant == -5 {
return
}
self.txtRercherche.endEditing(true)
UIView.animate(withDuration: 0.3, animations: {
self.constraintVueRecherche_Top.constant = -5
self.vueFondGris.alpha = 0.0
self.view.layoutIfNeeded()
}, completion: { termine in
self.vueRecherche.isHidden = true
self.vueFondGris.isHidden = true
})
}
with this call, the animation is smooth :
func textFieldDidEndEditing(_ textField: UITextField) {
fermeRecherche()
}
but not with this one :
let tap=UITapGestureRecognizer(target: self, action: #selector(self.tapFondGris(_:)))
vueFondGris.addGestureRecognizer(tap)
func tapFondGris(_ sender: UITapGestureRecognizer) {
fermeRecherche()
}
any ideas?
Thanks
I have a text field where user should enter info. And a label which points user to text field (like a hint).
I want to stop animation and remove hint label once user presses the text field to enter data.
There is repeating animation on text label. Was created by:
override func viewDidLoad() {
super.viewDidLoad()
textInput.addTarget(self, action: #selector(CalculatorViewController.removeAnimation(_:)), forControlEvents: UIControlEvents.TouchDown)
self.hintLabel.alpha = 0.0
UIView.animateWithDuration(1.5, delay: 0, options: .Repeat
, animations: ({
self.hintLabel.alpha = 1.0
}), completion: nil
)
After it I have created a function to remove annotation
func removeAnimation(textField: UITextField) {
view.layer.removeAllAnimations()
self.view.layer.removeAllAnimations()
print("is it working?!")
}
Should work according to documentation.
My label keeps flashing even though I see the string printed in console. I guess problem is that animation is repeated but have no clue how to resolve this issue.
//Just remove the animation from the label. It will Work
func remove()
{
self.hintLabel.layer.removeAllAnimations()
self.view.layer.removeAllAnimations()
self.view.layoutIfNeeded()
}
Update:
If you want to go nuclear, you could do this, as well:
func nukeAllAnimations() {
self.view.subviews.forEach({$0.layer.removeAllAnimations()})
self.view.layer.removeAllAnimations()
self.view.layoutIfNeeded()
}
Here's my function that animates my view
func animateViewMoving (up:Bool, moveValue :CGFloat) {
let movementDuration:NSTimeInterval = 0.3
let movement:CGFloat = ( up ? -moveValue : moveValue)
self.view.setNeedsLayout()
UIView.animateWithDuration(movementDuration, animations: {
self.view.layoutIfNeeded()
self.view.frame.origin.y += movement
})
}
I call this function on these two functions of UITextFieldDelegate
func textFieldDidBeginEditing(textField: UITextField) {
animateViewMoving(true, moveValue: 200)
}
func textFieldDidEndEditing(textField: UITextField) {
animateViewMoving(false, moveValue: 200)
}
The problem is this- Whenever I run my build and open the view for the first time, the view shifts up on pressing the textField and shifts down when editing the textField ends. However if I go back to a previous view and enter the view again, the view does not shift up on pressing the textField. Why is animateWithDuration working irregularly?
Sorry I don't know swift so I'll just write my solution in objective-C.
I assume that you are using AutoLayout. If that's the case I suggest that when you animate a view, you animate it's constraints, not the frame of the view. I encountered a lot of problems before when I animate the frame of the view.
Here's a sample:
- (void)moveSubview
{
_subviewLeadingSuperLeading.constant = 20; //just a sample to move the subview horizontally.
[UIView animateWithDuration:0.5 animations:^
{
[self.view layoutIfNeeded];
}
completion:^(BOOL isFinished)
{
//Do whatever you want
}];
}
I hope this will help you. :)