更新时间:2022-10-15 17:46:59
这是一个关于一个很好的项目来源,它可以实现你的搜索:
public enum EGFloatingTextFieldValidationType {
案例电子邮件
案例编号
}
公共类EGFloatingTextField:UITextField {
私有类型EGFloatingTextFieldValidationBlock =((text :String,inout message:String) - >布尔)!
public var validationType:EGFloatingTextFieldValidationType!
private var emailValidationBlock:EGFloatingTextFieldValidationBlock
private var numberValidationBlock:EGFloatingTextFieldValidationBlock
let kDefaultInactiveColor = UIColor(white:CGFloat(0), alpha:CGFloat(0.54))
让kDefaultActiveColor = UIColor.blueColor()
让kDefaultErrorColor = UIColor.redColor()
让kDefaultLineHeight = CGFloat(22)
让kDefaultLabelTextColor = UIColor (白色: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!
必需public init(编码器aDecoder:NSCoder){
super.init(编码器:aDecoder)
self.commonInit()
}
覆盖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(格式:SELF MATCHES%@,emailRegex)
var isValid = emailTest.evaluateWithObject(text)
if!isValid {
message = 无效的电子邮件地址
}
返回isValid;
})
self.numberValidationBlock =({(text:String,inout message:String) - >布尔在
var numRegex =[0-9。+ - ] +;
var numTest = NSPredicate(格式:SELF MATCHES%@,numRegex)
var isValid = numTest.evaluateWithObject(text)
if!isValid {
message =无效数字
}
返回isValid;
})
self.floating = false
self.hasError = false
self.labelTextColor = kDefaultLabelTextColor
self.label = UILabel (框架: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 =占位符
}
覆盖公共func成员FirstFirstResponder() - > 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
}
覆盖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
}
覆盖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 {() - >无效
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:kCAMe) diaTimingFunctionEaseOut)
anim2.fillMode = kCAFillModeForwards
anim2.removedOnCompletion = false
self.activeBorder.layer.addAnimation(anim2,forKey:_ activeBorder)
CATransaction.commit()
}
func animateLabelBack(){
CATransaction.begin()
CATransaction.setCompletionBlock {() - >无效
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 {() - >无效
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 =消息
s elf.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)
}
}
}
}
扩展名EGFloatingTextField {
}
他的名字是 EGFloatingTextField
你可以找到更多细节
I am pretty new to animating in Swift and have an idea of how to go about this but would like to see how others would do it -
I am trying to create the effect where the placeholder text of a search bar shrinks and moves up above the search field and changes to different color when user goes to enter search bar. Like this:
http://magicus.xyz when you click on username.
If I place a uilabel over a search bar and scale this label on entering the searcher Im not sure entering the search bar would register because a uilabel would be over it..
I am generally trying to replicate those textfields in general. How would I go about creating this animation? Or even adding a bottom border to my search bar?
Bridger:
//
// 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 */
ERROR:
My project:
This is the source about a nice project that achieve exactly what your search:
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 {
}
His name is EGFloatingTextField
and you can find more details here
Usage:
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)
P.S. You need to import PureLayout
library, here you can find the full source and instruction to how to import it.