I am currently working on an animation project for an Apple Development class where we are moving and animating an ImageView. I can move the image, but I'm stumped on how to return it to the origin location, preferably using the same button.
Code for the move animation is as follows:
#IBAction func move(_ sender: Any) {
UIView.animate(withDuration: 1, animations: {self.imageView.frame.origin.y -= 200
}, completion: nil)
}
declare a variable that will hold the value of your y origin when the view loaded. and also declare a variable that will check if the imageview is currently animating or not.
var onLoadFrameYOrigin : CGFloat = 0.0
var isAnimating : Bool = false
override func viewDidLoad() {
super.viewDidLoad()
onLoadFrameYOrigin = self.searchView.frame.origin.y
}
#IBAction func move(_ sender: Any) {
if !isAnimating {
self.isAnimating = true
UIView.animate(withDuration: 1.0, animations: {
if self.onLoadFrameYOrigin == self.imageView.frame.origin.y {
self.imageView.frame.origin.y -= 200
} else {
self.imageView.frame.origin.y = onLoadFrameYOrigin
}
}) { _ in
self.isAnimating = false
}
}
}
Note : if you have make outlet of constraint of imageView then please
update constraint value during animation not frame.
1) make variable first
var isBack : Bool = false
Now in your button action :
#IBAction func move(_ sender: Any) {
if isBack == false
{
isBack = true
UIView.animate(withDuration: 1, animations: {self.imageView.frame.origin.y -= 200
}, completion: nil)
}
else
{
isBack = false
UIView.animate(withDuration: 1, animations: {self.imageView.frame.origin.y += 200
}, completion: nil)
}
}
Related
What if the UILabel is in class A and the didTapRightutton that will animate it is in class B?
the percentDiscountLabel is in RandomizeDealsCollectionViewCell. This should animate into fade appear if I tap didTapRightutton which is in a different VC called RandomizeDealsViewController
How do I call the function that is inside RandomizeDealsCollectionViewCell to animate the percentDiscountLabel? Is there other way to do this?
class RandomizeDealsCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var percentDiscountLabel: UILabel!
func animatePercentDiscountLabel(deals: String) {
self.percentDiscountLabel.alpha = 0.6
self.percentDiscountLabel.isHidden = false
UIView.animate(withDuration: 0.6, delay: 0, options: .curveEaseInOut, animations: {
self.percentDiscountLabel.alpha = 1.0
}) { (isCompleted) in
}
percentDiscountLabel.text = deals
}
}
class RandomizeDealsViewController: UIViewController {
private var centeredCollectionViewFlowLayout: CenteredCollectionViewFlowLayout!
#IBAction func didTapRightButton(_ sender: Any) {
guard let indexCard = centeredCollectionViewFlowLayout.currentCenteredPage else { return }
if (indexCard > 0) {
centeredCollectionViewFlowLayout.scrollToPage(index: indexCard + 1, animated: true)
// should call the animation function here
}
}
}
If indexCard is indexPath of collectionViewCell which you want to animate,
You can call your cell like ->
in RandomizeDealsViewController
#IBAction func didTapRightButton(_ sender: Any) {
guard let indexCard = centeredCollectionViewFlowLayout.currentCenteredPage else { return }
if (indexCard > 0) {
centeredCollectionViewFlowLayout.scrollToPage(index: indexCard + 1, animated: true)
// should call the animation function here
let cell = collectionView!.cellForItemAtIndexPath(indexCard) as? RandomizeDealsCollectionViewCell
cell?.animatePercentDiscountLabel(deals: "deals")
}
}
I am facing an issue, whenever I going to type in ALTextInputBar() there is a space between keyboard and ALTextInputBar() of 44 points. I don't know from where it is coming. Please have a look on code and image.
#IBOutlet weak var viewChatBox: UIView!
#IBOutlet weak var viewChatBoxBottomConstraint: NSLayoutConstraint!
let textInputBar = ALTextInputBar()
let keyboardObserver = ALKeyboardObservingView()
override func viewDidLoad() {
super.viewDidLoad()
IQKeyboardManager.shared.enable = false
IQKeyboardManager.shared.enableAutoToolbar = false
configureView()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if #available(iOS 11, *) {
// safe area constraints already set
}
else {
if (!(self.topLayoutConstraint != nil)) {
topLayoutConstraint = viewTopBar.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor)
self.topLayoutConstraint?.isActive = true
}
if (!(self.bottomLayoutConstraint != nil)) {
// bottomLayoutConstraint = viewChatBox.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor)
self.bottomLayoutConstraint?.isActive = true
}
}
}
func configureInputBar () {
btnChat = UIButton(frame: CGRect(x: 0, y: 0, width: 36, height: 36))
keyboardObserver.isUserInteractionEnabled = false
textInputBar.showTextViewBorder = true
textInputBar.leftView = nil
textInputBar.rightView = btnChat
textInputBar.alwaysShowRightButton = true
textInputBar.delegate = self
textInputBar.textView.autocorrectionType = .yes
textInputBar.backgroundColor = UIColor(white: 0.95, alpha: 1)
textInputBar.keyboardObserver = keyboardObserver
viewChatBox.addSubview(textInputBar)
applyConstraintToChatBox()
self.view.layoutIfNeeded()
}
func applyConstraintToChatBox() {
textInputBar.translatesAutoresizingMaskIntoConstraints = false
viewChatBox.translatesAutoresizingMaskIntoConstraints = false
let views = ["textView": textInputBar]
let hConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[textView]-0-|", options: [], metrics: nil, views: views)
let vConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[textView]-0-|", options: [], metrics: nil, views: views)
viewChatBox.addConstraints(hConstraints)
viewChatBox.addConstraints(vConstraints)
}
override var inputAccessoryView: UIView? {
get {
return keyboardObserver
}
}
override var canBecomeFirstResponder: Bool {
return true
}
//MARK: - TEXTVIEW DELEGATE
func textView(textView: ALTextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if (textInputBar.text.count == 0) {
return true
}
let newLength = textInputBar.text.count + text.count - range.length
return (newLength <= 144);
}
func inputBarDidChangeHeight(height: CGFloat) {
UIView.animate(withDuration: 0.3, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.7, options: [.curveLinear], animations: { () -> Void in
self.view.layoutIfNeeded()
}, completion: nil)
}
// MARK: - KEYBOARDS
#objc func keyboardWillChangeFrame(notification: Notification) {
let endFrame = ((notification as NSNotification).userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
viewChatBoxBottomConstraint.constant = view.bounds.height - endFrame.origin.y
print("CHAT BOX FRAME: \(viewChatBox.frame)")
print("TEXT FRAME FRAME: \(textInputBar.frame)")
self.view.layoutIfNeeded()
}
Late answer but may help someone. I had the same issue and found this below code in the documentation.
Only helpful for IQKeyboardManager users.
IQKeyboardManager
self.textField.keyboardDistanceFromTextField = 8; //This will modify default distance between textField and keyboard. For exact value, please manually check how far your textField from the bottom of the page. Mine was 8pt.
import UIKit
class UpdateUsersManagmentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func checkBoxTapped(_ sender:UIButton) {
UIView.animate(withDuration: 0.5, delay: 0.1, options: .curveLinear, animations: {
sender.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
}) { (success) in
sender.isSelected = !sender.isSelected
UIView.animate(withDuration: 0.5, delay: 0.1, options: .curveLinear, animations: {
sender.transform = .identity
}, completion: nil)
}
}
}
I would have a method that does that.
func toggleCheckmark(_ checkmark: UIButton) {
if checkmark == self.checkmark1 {
self.selectCheckmark1()
self.deselectCheckmark2()
} else if checkmark == self.checkmark2 {
self.selectCheckmark2()
self.deselectCheckmark1()
}
}
Another option is something like this:
func toggleCheckmark(_ checkmark: UIButton) {
self.selectCheckmark(self.checkmark1, on: checkmark == self.checkmark1)
self.selectCheckmark(self.checkmark2, on: checkmark == self.checkmark2)
}
If you want to select any of the one option from the group, it better to use radio buttons instead of check boxes.
If not, we should do it manually. I did it in swift and its working
#objc func selector(_ sender: NSButton)
{
if sender == checkBox1
{
if sender.state == .on && checkBox2.state == .on
{
checkBox2.state = .off
}
}
if sender == checkBox2
{
if sender.state == .on && checkBox1.state == .on
{
checkBox1.state = .off
}
}
}
I would like to hide the Statusbar when i hide Navigationbar and Toolbar.
How i can make that that the Statusbar is hidden in if NavigationBar.hidden == false && Toolbar.hidden == false{} ??
I have no idea how i can make that, i know the func to return the Statusbarhidden but thats in the whole ViewController and i would to hide it in the func.
Thanks for your Help.
func ImageTapGesture () {
if NavigationBar.hidden == false && Toolbar.hidden == false{
NavigationBar.hidden = true
Toolbar.hidden = true
} else if NavigationBar.hidden == true && Toolbar.hidden == true {
NavigationBar.hidden = false
Toolbar.hidden = false
}
}
Under the Swift language, you can refer to the following code hidden, don't need animation effects can be commented out.
var isHidden:Bool = false
#IBAction func clicked(_ sender: AnyObject) {
isHidden = !isHidden
UIView.animate(withDuration: 0.5, animations: { () -> Void in
self.setNeedsStatusBarAppearanceUpdate()
})
}
override var preferredStatusBarUpdateAnimation : UIStatusBarAnimation {
return UIStatusBarAnimation.slide
}
override var prefersStatusBarHidden : Bool {
return isHidden
}
Can also refer to the following link to the Demo, is a time I write the project requirements.
Github:https://github.com/ReverseScale/HiddenStatusBar
Wish I could help you.
A Swift 2.x compatible workaround to make what do you need to do :
func hideStatusBar(yOffset:CGFloat) { // -20.0 for example
let statusBarWindow = UIApplication.sharedApplication().valueForKey("statusBarWindow") as! UIWindow
statusBarWindow.frame = CGRectMake(0, yOffset, statusBarWindow.frame.size.width, statusBarWindow.frame.size.height)
}
func showStatusBar() {
let statusBarWindow = UIApplication.sharedApplication().valueForKey("statusBarWindow") as! UIWindow
statusBarWindow.frame = CGRectMake(0, 0, statusBarWindow.frame.size.width, statusBarWindow.frame.size.height)
}
To use it for example you can launch:
hideStatusBar(-20.0)
In the below delegate function I was trying to do but did'nt get desired result
override func didUpdateFocusInContext(context: UIFocusUpdateContext,withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
if (context.nextFocusedView == self) {
coordinator.addCoordinatedAnimations({ () -> Void in
self.animationDidStop(CAAnimation(), finished: true)
}, completion: { () -> Void in
})
}
else {
// handle unfocused appearance changes
coordinator.addCoordinatedAnimations({ () -> Void in
self.animationDidStop(CAAnimation(), finished: true)
}, completion: { () -> Void in
})
}
context.nextFocusedView?.layer.shadowOffset = CGSizeZero
context.nextFocusedView?.layer.shadowOpacity = 0.9;
context.nextFocusedView?.layer.shadowRadius = 0;
context.nextFocusedView?.layer.shadowColor= UIColor.orangeColor().CGColor
context.previouslyFocusedView?.layer.shadowOpacity = 0;
}
First of all you have to set your button type to Custom type. By custom type you will get no more system animations, so you have to do all animations by yourself.
Then you can implement didUpdateFocusInContext method either in UIViewController or you can make your own UIButton subclass if there are more button types on a single screen.
Here is a code that I use in my UIButton subclass. This will provide the button enlargement along with red border on focus and will get to normal state on focus loss.
let scale = 1.1
layer.borderColor = UIColor.redColor().CGColor
override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
if context.nextFocusedView == self {
coordinator.addCoordinatedAnimations({ () -> Void in
self.transform = CGAffineTransformMakeScale(scale, scale)
self.layer.borderWidth = 2
}, completion: nil)
}
else {
coordinator.addCoordinatedAnimations({ () -> Void in
self.transform = CGAffineTransformIdentity
self.layer.borderWidth = 0
}, completion: nil)
}
}