Ios 在Swift中实现UILabel动画效果的最佳方法?

Ios 在Swift中实现UILabel动画效果的最佳方法?,ios,swift,Ios,Swift,我对Swift中的动画制作非常陌生,我有一个想法,但我想看看其他人会怎么做- 我正在尝试创建这样一种效果:当用户进入搜索栏时,搜索栏的占位符文本缩小并向上移动到搜索字段上方,并更改为不同的颜色。像这样: 当你点击用户名时 如果我将uilabel放置在搜索栏上,并在输入搜索者时缩放此标签,我不确定输入搜索栏是否会注册,因为uilabel将位于其上方 我通常会尝试复制这些文本字段。我将如何开始创建此动画?或者甚至在我的搜索栏中添加一个底部边框 布里杰: // // Makestagram-Brid

我对Swift中的动画制作非常陌生,我有一个想法,但我想看看其他人会怎么做-

我正在尝试创建这样一种效果:当用户进入搜索栏时,搜索栏的占位符文本缩小并向上移动到搜索字段上方,并更改为不同的颜色。像这样:

当你点击用户名时

如果我将uilabel放置在搜索栏上,并在输入搜索者时缩放此标签,我不确定输入搜索栏是否会注册,因为uilabel将位于其上方

我通常会尝试复制这些文本字段。我将如何开始创建此动画?或者甚至在我的搜索栏中添加一个底部边框

布里杰:

//
//  Makestagram-Bridging-Header.h
//  round
//
//  Created by Skylar Thomas on 6/24/16.
//  Copyright © 2016 Make School. All rights reserved.
//

#ifndef Makestagram_Bridging_Header_h
#define Makestagram_Bridging_Header_h

#import "PureLayout.h"

#endif /* Makestagram_Bridging_Header_h */

错误:

我的项目:


您可以这样尝试:

要创建动画,请执行以下操作:

  • 将标签放置在文本字段上,并将轻触手势识别器添加到标签。将标签缩放到其位置,并在点击标签时将文本字段设置为第一响应者
  • 要创建底部边框,请执行以下操作:

  • 根据需要,在文本字段下方添加高度为1或2像素的UIView/UIImageView。并为文本字段设置无边框样式

  • 要更改带有颜色的图标,请尝试。通过这种方式,您只需传递字符串名称即可将图标更改为彩色图标。

    这是关于一个优秀项目的源代码,该项目完全实现了您的搜索:

        public enum EGFloatingTextFieldValidationType {
            case Email
            case Number
        }
    
        public class EGFloatingTextField: UITextField {
    
    
            private typealias EGFloatingTextFieldValidationBlock = ((text:String,inout message:String)-> Bool)!
    
            public var validationType : EGFloatingTextFieldValidationType!
    
    
            private var emailValidationBlock  : EGFloatingTextFieldValidationBlock
            private var numberValidationBlock : EGFloatingTextFieldValidationBlock
    
    
            let kDefaultInactiveColor = UIColor(white: CGFloat(0), alpha: CGFloat(0.54))
            let kDefaultActiveColor = UIColor.blueColor()
            let kDefaultErrorColor = UIColor.redColor()
            let kDefaultLineHeight = CGFloat(22)
            let kDefaultLabelTextColor = UIColor(white: CGFloat(0), alpha: CGFloat(0.54))
    
    
            public var floatingLabel : Bool!
            var label : UILabel!
            var labelFont : UIFont!
            var labelTextColor : UIColor!
            var activeBorder : UIView!
            var floating : Bool!
            var active : Bool!
            var hasError : Bool!
            var errorMessage : String!
    
    
    
            required public init(coder aDecoder: NSCoder) {
                super.init(coder: aDecoder)
                self.commonInit()
            }
    
    
            override public init(frame: CGRect) {
                super.init(frame: frame)
                self.commonInit()
            }
    
            func commonInit(){
    
                self.emailValidationBlock = ({(text:String, inout message: String) -> Bool in
                    var emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"
    
                    var emailTest = NSPredicate(format:"SELF MATCHES %@" , emailRegex)
    
                    var  isValid = emailTest.evaluateWithObject(text)
                    if !isValid {
                        message = "Invalid Email Address"
                    }
                    return isValid;
                })
                self.numberValidationBlock = ({(text:String,inout message: String) -> Bool in
                    var numRegex = "[0-9.+-]+";
                    var numTest = NSPredicate(format:"SELF MATCHES %@" , numRegex)
    
                    var isValid =  numTest.evaluateWithObject(text)
                    if !isValid {
                        message = "Invalid Number"
                    }
                    return isValid;
    
                })
                self.floating = false
                self.hasError = false
    
                self.labelTextColor = kDefaultLabelTextColor
                self.label = UILabel(frame: CGRectZero)
                self.label.font = self.labelFont
                self.label.textColor = self.labelTextColor
                self.label.textAlignment = NSTextAlignment.Left
                self.label.numberOfLines = 1
                self.label.layer.masksToBounds = false
                self.addSubview(self.label)
    
    
                self.activeBorder = UIView(frame: CGRectZero)
                self.activeBorder.backgroundColor = kDefaultActiveColor
                self.activeBorder.layer.opacity = 0
                self.addSubview(self.activeBorder)
    
                self.label.autoAlignAxis(ALAxis.Horizontal, toSameAxisOfView: self)
                self.label.autoPinEdge(ALEdge.Left, toEdge: ALEdge.Left, ofView: self)
                self.label.autoMatchDimension(ALDimension.Width, toDimension: ALDimension.Width, ofView: self)
                self.label.autoMatchDimension(ALDimension.Height, toDimension: ALDimension.Height, ofView: self)
    
                self.activeBorder.autoPinEdge(ALEdge.Bottom, toEdge: ALEdge.Bottom, ofView: self)
                self.activeBorder.autoPinEdge(ALEdge.Left, toEdge: ALEdge.Left, ofView: self)
                self.activeBorder.autoPinEdge(ALEdge.Right, toEdge: ALEdge.Right, ofView: self)
                self.activeBorder.autoSetDimension(ALDimension.Height, toSize: 2)
    
                NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("textDidChange:"), name: "UITextFieldTextDidChangeNotification", object: self)
            }
            public func setPlaceHolder(placeholder:String){
                self.label.text = placeholder
            }
    
            override public func becomeFirstResponder() -> Bool {
    
                var flag:Bool = super.becomeFirstResponder()
    
                if flag {
    
                    if self.floatingLabel! {
    
                        if !self.floating! || self.text!.isEmpty {
                            self.floatLabelToTop()
                            self.floating = true
                        }
                    } else {
                        self.label.textColor = kDefaultActiveColor
                        self.label.layer.opacity = 0
                    }
                    self.showActiveBorder()
                }
    
                self.active=flag
                return flag
            }
            override public func resignFirstResponder() -> Bool {
    
                var flag:Bool = super.becomeFirstResponder()
    
                if flag {
    
                    if self.floatingLabel! {
    
                        if self.floating! && self.text!.isEmpty {
                            self.animateLabelBack()
                            self.floating = false
                        }
                    } else {
                        if self.text!.isEmpty {
                            self.label.layer.opacity = 1
                        }
                    }
                    self.label.textColor = kDefaultInactiveColor
                    self.showInactiveBorder()
                    self.validate()
                }
                self.active = flag
                return flag
    
            }
    
            override public func drawRect(rect: CGRect){
                super.drawRect(rect)
    
                var borderColor = self.hasError! ? kDefaultErrorColor : kDefaultInactiveColor
    
                var textRect = self.textRectForBounds(rect)
                var context = UIGraphicsGetCurrentContext()
                var borderlines : [CGPoint] = [CGPointMake(0, CGRectGetHeight(textRect) - 1),
                    CGPointMake(CGRectGetWidth(textRect), CGRectGetHeight(textRect) - 1)]
    
                if  self.enabled  {
    
                    CGContextBeginPath(context);
                    CGContextAddLines(context, borderlines, 2);
                    CGContextSetLineWidth(context, 1.0);
                    CGContextSetStrokeColorWithColor(context, borderColor.CGColor);
                    CGContextStrokePath(context);
    
                } else {
    
                    CGContextBeginPath(context);
                    CGContextAddLines(context, borderlines, 2);
                    CGContextSetLineWidth(context, 1.0);
                    var  dashPattern : [CGFloat]  = [2, 4]
                    CGContextSetLineDash(context, 0, dashPattern, 2);
                    CGContextSetStrokeColorWithColor(context, borderColor.CGColor);
                    CGContextStrokePath(context);
    
                }
            }
    
            func textDidChange(notif: NSNotification){
                self.validate()
            }
    
            func floatLabelToTop() {
    
                CATransaction.begin()
                CATransaction.setCompletionBlock { () -> Void in
                    self.label.textColor = self.kDefaultActiveColor
                }
    
                var anim2 = CABasicAnimation(keyPath: "transform")
                var fromTransform = CATransform3DMakeScale(CGFloat(1.0), CGFloat(1.0), CGFloat(1))
                var toTransform = CATransform3DMakeScale(CGFloat(0.5), CGFloat(0.5), CGFloat(1))
                toTransform = CATransform3DTranslate(toTransform, -CGRectGetWidth(self.label.frame)/2, -CGRectGetHeight(self.label.frame), 0)
                anim2.fromValue = NSValue(CATransform3D: fromTransform)
                anim2.toValue = NSValue(CATransform3D: toTransform)
                anim2.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
                var animGroup = CAAnimationGroup()
                animGroup.animations = [anim2]
                animGroup.duration = 0.3
                animGroup.fillMode = kCAFillModeForwards;
                animGroup.removedOnCompletion = false;
                self.label.layer.addAnimation(animGroup, forKey: "_floatingLabel")
                self.clipsToBounds = false
                CATransaction.commit()
            }
            func showActiveBorder() {
    
                self.activeBorder.layer.transform = CATransform3DMakeScale(CGFloat(0.01), CGFloat(1.0), 1)
                self.activeBorder.layer.opacity = 1
                CATransaction.begin()
                self.activeBorder.layer.transform = CATransform3DMakeScale(CGFloat(0.01), CGFloat(1.0), 1)
                var anim2 = CABasicAnimation(keyPath: "transform")
                var fromTransform = CATransform3DMakeScale(CGFloat(0.01), CGFloat(1.0), 1)
                var toTransform = CATransform3DMakeScale(CGFloat(1.0), CGFloat(1.0), 1)
                anim2.fromValue = NSValue(CATransform3D: fromTransform)
                anim2.toValue = NSValue(CATransform3D: toTransform)
                anim2.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
                anim2.fillMode = kCAFillModeForwards
                anim2.removedOnCompletion = false
                self.activeBorder.layer.addAnimation(anim2, forKey: "_activeBorder")
                CATransaction.commit()
            }
    
            func animateLabelBack() {
                CATransaction.begin()
                CATransaction.setCompletionBlock { () -> Void in
                    self.label.textColor = self.kDefaultInactiveColor
                }
    
                var anim2 = CABasicAnimation(keyPath: "transform")
                var fromTransform = CATransform3DMakeScale(0.5, 0.5, 1)
                fromTransform = CATransform3DTranslate(fromTransform, -CGRectGetWidth(self.label.frame)/2, -CGRectGetHeight(self.label.frame), 0);
                var toTransform = CATransform3DMakeScale(1.0, 1.0, 1)
                anim2.fromValue = NSValue(CATransform3D: fromTransform)
                anim2.toValue = NSValue(CATransform3D: toTransform)
                anim2.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
    
                var animGroup = CAAnimationGroup()
                animGroup.animations = [anim2]
                animGroup.duration = 0.3
                animGroup.fillMode = kCAFillModeForwards;
                animGroup.removedOnCompletion = false;
    
                self.label.layer.addAnimation(animGroup, forKey: "_animateLabelBack")
                CATransaction.commit()
            }
            func showInactiveBorder() {
    
                CATransaction.begin()
                CATransaction.setCompletionBlock { () -> Void in
                    self.activeBorder.layer.opacity = 0
                }
                var anim2 = CABasicAnimation(keyPath: "transform")
                var fromTransform = CATransform3DMakeScale(1.0, 1.0, 1)
                var toTransform = CATransform3DMakeScale(0.01, 1.0, 1)
                anim2.fromValue = NSValue(CATransform3D: fromTransform)
                anim2.toValue = NSValue(CATransform3D: toTransform)
                anim2.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
                anim2.fillMode = kCAFillModeForwards
                anim2.removedOnCompletion = false
                self.activeBorder.layer.addAnimation(anim2, forKey: "_activeBorder")
                CATransaction.commit()
            }
    
            func performValidation(isValid:Bool,message:String){
                if !isValid {
                    self.hasError = true
                    self.errorMessage = message
                    self.labelTextColor = kDefaultErrorColor
                    self.activeBorder.backgroundColor = kDefaultErrorColor
                    self.setNeedsDisplay()
                } else {
                    self.hasError = false
                    self.errorMessage = nil
                    self.labelTextColor = kDefaultActiveColor
                    self.activeBorder.backgroundColor = kDefaultActiveColor
                    self.setNeedsDisplay()
                }
            }
    
            func validate(){
    
                if self.validationType != nil {
                    var message : String = ""
    
                    if self.validationType! == .Email {
    
                        var isValid = self.emailValidationBlock(text: self.text, message: &message)
    
                        performValidation(isValid,message: message)
    
                    } else {
                        var isValid = self.numberValidationBlock(text: self.text, message: &message)
    
                        performValidation(isValid,message: message)
                    }
                }
            }
    
    
        }
    
        extension EGFloatingTextField {
    
        }
    
    他的名字是
    EGFloatingTextField
    ,您可以找到更多详细信息

    用法

    let emailLabel = EGFloatingTextField(frame: CGRectMake(8, 64, CGRectGetWidth(self.view.bounds) - 16, 48))
    emailLabel.floatingLabel = true
    emailLabel.setPlaceHolder("Email")
    emailLabel.validationType = .Email
    emailLabel.keyboardType = .EmailAddress
    self.view.addSubview(emailLabel)
    
    另外,您需要导入
    PureLayout
    库,您可以找到完整的源代码以及如何导入它的说明


    实现此功能时遇到问题-即使我在pod文件中写入了所需的行,也无法使用import PureLayout获得此类模块。我应该在单独的脚本中添加所有这些内容吗?当我这样做的时候,它不知道这里的EG文本字段是什么样子的:还有关于如何导入itOk的说明,我看了一遍,但有点模糊——当我在单独的文件中导入它时,我没有收到错误,只是当我在我的视图控制器文件中导入它时。我是否将上述代码放在一个单独的文件中?通常我对这些手动说明没有问题:它说运行pod安装,但我不知道这意味着什么-pod安装什么?我写pod安装Purelayout吗?关于如何在标签中设置缩放动画有什么想法吗?我试过CGAffineTransform,但它像上面答案的gif一样跳跃帧/不平滑。我远离键盘,我将发布EODI的简单解决方案,我认为这些就是你想要的效果(hoshi,我相信它被称为)。