Swift2:TKSubmitTransitionButton。当用户登录/注册不正确时,如何停止按钮的转换/动画
Posted
技术标签:
【中文标题】Swift2:TKSubmitTransitionButton。当用户登录/注册不正确时,如何停止按钮的转换/动画【英文标题】:Swift2: TKSubmitTransitionButton. How do i stop a button from transition/ animating when user login/ signup are incorrect 【发布时间】:2016-03-31 09:32:27 【问题描述】:我已经尝试了很多次,我得到的最好的结果是,无论我使用什么命令,都会有一个永远不会取消或停止的动画。
在遵循@Mattias 示例之后,我更新了我的代码,看起来像这样:
// DESIGN ANIMATION... TKTRANSITIONSUBMITBUTTON
@IBOutlet weak var btnFromNib: TKTransitionSubmitButton!
@IBAction func onTapButton(sender: AnyObject)
btnFromNib.startLoadingAnimation()
if let email = self.emailField.text where email != "", let password = self.passwordField.text where password != ""
DataService.ds.REF_BASE.authUser(email, password: password, withCompletionBlock: error, authData in
if error != nil
self.btnFromNib.returnToOriginalState()
if error.code == STATUS_ACCOUNT_NONEXIST
self.showErrorAlert("This User does not exist", msg: "Please Sign Up")
else
else
self.btnFromNib.startFinishAnimation(1, completion:
let myTabbarController = self.storyboard?.instantiateViewControllerWithIdentifier("myTabbarController") as! UITabBarController
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window?.rootViewController = myTabbarController
myTabbarController.transitioningDelegate = self
)
)
按钮仍在不停地旋转/动画。检查自定义动画类后,该函数继承自:
public func startLoadingAnimation()
self.cachedTitle = titleForState(.Normal)
self.setTitle("", forState: .Normal)
self.shrink()
NSTimer.schedule(delay: shrinkDuration - 0.25) timer in
self.spiner.animation()
public func startFinishAnimation(delay: NSTimeInterval, completion:(()->())?)
NSTimer.schedule(delay: delay) timer in
self.didEndFinishAnimation = completion
self.expand()
self.spiner.stopAnimation()
public func animate(duration: NSTimeInterval, completion:(()->())?)
startLoadingAnimation()
startFinishAnimation(duration, completion: completion)
public override func animationDidStop(anim: CAAnimation, finished flag: Bool)
let a = anim as! CABasicAnimation
if a.keyPath == "transform.scale"
didEndFinishAnimation?()
NSTimer.schedule(delay: 1) timer in
self.returnToOriginalState()
func returnToOriginalState()
self.layer.removeAllAnimations()
self.setTitle(self.cachedTitle, forState: .Normal)
我注意到它有一个公共覆盖 func animationDidStop(anim: CAAnimation, finished: Bool) 作为停止动画的函数。但是当我使用它时,我得到了这个错误!
我如何正确地让它工作? ...
提前致谢
** 更新问题**
【问题讨论】:
【参考方案1】:我检查了TKTransitionSubmitButton
的代码,其中有名为startLoadingAnimation()
、returnToOriginalState()
和startFinishAnimation()
的公共方法。
我建议:
Button tapped
startLoadingAnimation()
Check credentials
If wrong/error: returnToOriginalState()
If correct: startFinishAnimation()
转换,来自TKTransitionSubmitButton
文档:
btn.startFinishAnimation
//Your Transition
let secondVC = SecondViewController()
secondVC.transitioningDelegate = self
self.presentViewController(secondVC, animated: true, completion: nil)
编辑:据我所知,该课程的.animate()
调用了开始和结束动画,这就是你不能取消它的原因。
EDIT2这对我来说是有效的(但我不确定静态cornerRadius)
import UIKit
class ViewController: UIViewController
@IBOutlet weak var submitButton: TKTransitionSubmitButton!
override func viewDidLoad()
super.viewDidLoad()
submitButton.layer.cornerRadius = 15
// Do any additional setup after loading the view, typically from a nib.
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
@IBAction func buttonPressed(sender: AnyObject)
submitButton.startLoadingAnimation()
delay(2, closure:
self.checkCredentials()
)
func checkCredentials()
//FAKING WRONG CREDENTIALS
let userAndPasswordCorrect = false
if !userAndPasswordCorrect
submitButton.returnToOriginalState()
//Alert or whatever
//Faking network delay
func delay(delay:Double, closure:()->())
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
【讨论】:
可以帮我写出代码吗? .. returnToOriginalState() 不是公共函数,即使我成功了,也会出错。使用你的方法有点令人困惑,尽管它很有意义 当我调用 returnToOriginalState() 函数时,它并没有取消动画。相反,它一直在旋转。看到 animationDidStop(anim: CAAnimation, finished: Bool) 确实调用了 returnToOriginalState()。但我无法编写代码来让它工作。 我会全力以赴的! 更新的答案,为我工作。祝你好运! (而且这些方法对我都是公开的,我没有更改按钮类中的任何内容) 我已经更新了这个问题。我通过更多的调整尝试了你的方式很多次,但不明白为什么它不起作用。我的猜测是,如果我能够成功地调用公共覆盖函数 animationDidStop(anim: CAAnimation, finished flag: Bool),我会成功地让它停止动画。抱歉打扰了。谢谢【参考方案2】:我检查了TKTransitionSubmitButton的代码。
我解决了这个问题。请尝试在 DispatchQueue.main.async 下停止动画并正常工作。
'func apicallforLogin()
let urlString = "http://"
guard let requestUrl = URL(string:urlString) else return
let request = URLRequest(url:requestUrl)
let task = URLSession.shared.dataTask(with: request)
(data, response, error) in
if error == nil,let usableData = data
DispatchQueue.main.async
self.btnLogin.startFinishAnimation(0.1, completion:
let HomeVC = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
HomeVC.transitioningDelegate = self
self.navigationController?.pushViewController(HomeVC, animated: false)
)
print(usableData)
else
DispatchQueue.main.async
self.btnLogin.returnToOriginalState()
task.resume()'
【讨论】:
【参考方案3】:好吧,您现在可能已经得到了答案,但我只想给出我的答案。你可以复制下面的代码,一切都会好起来的。我已做出更改并为此问题创建了拉取请求。
import Foundation
import UIKit
@IBDesignable
open class TKTransitionSubmitButton : UIButton, UIViewControllerTransitioningDelegate, CAAnimationDelegate
lazy var spiner: SpinerLayer! =
let s = SpinerLayer(frame: self.frame)
return s
()
@IBInspectable open var spinnerColor: UIColor = UIColor.white
didSet
spiner.spinnerColor = spinnerColor
open var didEndFinishAnimation : (()->())? = nil
let springGoEase = CAMediaTimingFunction(controlPoints: 0.45, -0.36, 0.44, 0.92)
let shrinkCurve = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
let expandCurve = CAMediaTimingFunction(controlPoints: 0.95, 0.02, 1, 0.05)
let shrinkDuration: CFTimeInterval = 0.1
@IBInspectable open var normalCornerRadius:CGFloat = 0.0
didSet
self.layer.cornerRadius = normalCornerRadius
var cachedTitle: String?
var isAnimating = false
public override init(frame: CGRect)
super.init(frame: frame)
self.setup()
public required init!(coder aDecoder: NSCoder)
super.init(coder: aDecoder)!
self.setup()
func setup()
self.clipsToBounds = true
spiner.spinnerColor = spinnerColor
open func startLoadingAnimation()
self.isAnimating = true
self.cachedTitle = title(for: UIControlState())
self.setTitle("", for: UIControlState())
self.layer.addSublayer(spiner)
// Animate
self.cornerRadius()
self.shrink()
_ = Timer.schedule(delay: self.shrinkDuration - 0.25) timer in
self.spiner.animation()
open func startFinishAnimation(_ delay: TimeInterval,_ animation: CAMediaTimingFunction, completion:(()->())?)
self.isAnimating = true
_ = Timer.schedule(delay: delay) timer in
self.didEndFinishAnimation = completion
self.expand(animation)
self.spiner.stopAnimation()
open func animate(_ duration: TimeInterval,_ animation: CAMediaTimingFunction, completion:(()->())?)
startLoadingAnimation()
startFinishAnimation(duration, animation, completion: completion)
open func setOriginalState()
self.returnToOriginalState()
self.spiner.stopAnimation()
public func animationDidStop(_ anim: CAAnimation, finished flag: Bool)
let a = anim as! CABasicAnimation
if a.keyPath == "transform.scale"
didEndFinishAnimation?()
_ = Timer.schedule(delay: 1) timer in
self.returnToOriginalState()
open func returnToOriginalState()
self.spiner.removeFromSuperlayer()
self.layer.removeAllAnimations()
self.setTitle(self.cachedTitle, for: UIControlState())
self.spiner.stopAnimation()
self.isAnimating = false
func cornerRadius()
let cornerRadiusAnim = CABasicAnimation(keyPath: "cornerRadius")
// cornerRadiusAnim.fromValue = frame.width
cornerRadiusAnim.toValue = frame.height/2
cornerRadiusAnim.duration = shrinkDuration
cornerRadiusAnim.timingFunction = shrinkCurve
cornerRadiusAnim.fillMode = kCAFillModeForwards
cornerRadiusAnim.isRemovedOnCompletion = false
layer.add(cornerRadiusAnim, forKey: cornerRadiusAnim.keyPath)
func shrink()
let shrinkAnim = CABasicAnimation(keyPath: "bounds.size.width")
shrinkAnim.beginTime = CACurrentMediaTime() + 0.1
shrinkAnim.fromValue = frame.width
shrinkAnim.toValue = frame.height
shrinkAnim.duration = shrinkDuration
shrinkAnim.timingFunction = shrinkCurve
shrinkAnim.fillMode = kCAFillModeForwards
shrinkAnim.isRemovedOnCompletion = false
layer.add(shrinkAnim, forKey: shrinkAnim.keyPath)
func expand(_ animation: CAMediaTimingFunction)
let expandAnim = CABasicAnimation(keyPath: "transform.scale")
expandAnim.fromValue = 1.0
expandAnim.toValue = 26.0
expandAnim.timingFunction = animation
expandAnim.duration = 0.3
expandAnim.delegate = self
expandAnim.fillMode = kCAFillModeForwards
expandAnim.isRemovedOnCompletion = false
layer.add(expandAnim, forKey: expandAnim.keyPath)
【讨论】:
以上是关于Swift2:TKSubmitTransitionButton。当用户登录/注册不正确时,如何停止按钮的转换/动画的主要内容,如果未能解决你的问题,请参考以下文章
Swift2.0 Multipeer Connectivity 无法连接