JBButton 是用 Swift 编写的不可配置和可动画的按钮。它提供了一个加载状态,完全可定制,从而避免使用阻塞的HUD。
如果您不想使用上述任何依赖管理器,您可以通过下载 JBButton.framework
并将其添加到项目中来手动将 JBButton 集成到您的项目中。
将一个 UIView 拖拽到您想添加 JBButton 的 ViewController 中。在身份检查器中,将其设置为 JBButton
自定义类,并按 Enter
。它将自动为您设置正确的模块。然后,只需在属性检查器中对其进行自定义!作为按钮是一个 IBDesignable 组件,大部分布局可以在故事板中完成。查看下面的简单示例。
界面构建器 | 结果 |
---|---|
不要忘记首先导入 JBButton
🙃
根据您正在使用的语言
@IBOutlet weak var tweet: JBButton!
或者
@property(nonatomic, weak) IBOutlet JBButton *tweet;
如果您想与按钮交互,则您的类可以扩展 JBButtonDelegate
协议,以处理 didTapOnButton(:)
方法,并将 delegate
设置为代码或界面构建器中。
界面构建器中有许多 IBInspectable
。您可以通过查看代码文档获取更多详细信息,或者参考以下表格。
可检查项 | 类型 | 文档 | 默认值 |
---|---|---|---|
title | String? | 要显示的文本 | "击中我!" |
titleColor | UIColor | 文本颜色 | UIColor.blackColor() |
标题对齐方式 | Int | 文本对齐方式。将其视为 NSTextAlignment.<alignment>.rawValue | 1 (即 NSTextAlignmentCenter ) |
图片 | UIImage? | 要显示的图片 | 无默认值 |
图片颜色 | UIColor | 如果以模板方式呈现,图片的颜色 | UIColor.blackColor() |
图片渲染模式 | Int | 图片的渲染模式。0 表示 .Original 1 表示 .Template | 0 |
图片位置 | Int | 图片在按钮中的位置。0 表示 .Top 1 表示 .Bottom 2 表示 .Left 3 表示 .Right 4 表示 .Centered | 0 |
圆角半径 | CGFloat | 按钮的圆角半径 | 0 |
边框宽度 | CGFloat | 按钮的边框宽度 | 1 |
borderColor | UIColor | 按钮的边框颜色 | UIColor.blackColor() |
内边距 | CGFloat | 按钮的内边距 | 0 |
高亮 | Bool | 决定按钮是否在点击时高亮显示 | true |
在下面的示例中,imageRenderingMode
设置为模板,imagePosition
设置为顶部,highlight
设置为 true,…
快速点击 | 较长时间的点击 |
---|---|
属性或方法 | 文档 |
---|---|
delegate: JBButtonDelegate? | 按钮的代理。可以在代码或IB中设置。 |
customTouchesBeganAnimations: CAAnimationGroup? | 自定义触摸开始动画组。在代码中设置。 |
customTouchesEndedAnimations: CAAnimationGroup? | 自定义触摸结束动画组。在代码中设置。 |
customLoadingAnimations: CAAnimationGroup? | 自定义加载动画组。在代码中设置。 |
hideTitleOnLoad: Bool | 告诉按钮是否在加载时隐藏标题。 |
isLoading: Bool | 告诉您按钮是否处于加载状态。 |
setTitleFont(font: UIFont) | 为标题设置自定义字体。 |
setTitleText(title: String) | 设置新的标题。 |
按钮动画已经变得很简单。您可以设置属性,例如 customTouchesBeganAnimations
或 customTouchesEndedAnimations
,以传递 CAAnimationGroup
。
示例
// Scale animation
let scaleDown = CASpringAnimation(keyPath: "transform.scale")
scaleDown.damping = 0.4
scaleDown.initialVelocity = 12.0
scaleDown.fromValue = 1.0
scaleDown.toValue = 0.9
// Group set to customTouchesBeganAnimations
let group = CAAnimationGroup()
group.animations = [scaleDown]
group.duration = 0.35
group.fillMode = kCAFillModeForwards
group.removedOnCompletion = false
self.pinIt.customTouchesBeganAnimations = group
// Reverse scale animation
let scaleUp = CASpringAnimation(keyPath: "transform.scale")
scaleUp.damping = 0.4
scaleUp.initialVelocity = 12.0
scaleUp.fromValue = 0.9
scaleUp.toValue = 1.0
// Rotation animation
let rotate = CABasicAnimation(keyPath: "transform.rotation")
rotate.fillMode = kCAFillModeBoth
rotate.toValue = (360 * M_PI / 180)
// Group set to customTouchesEndedAnimations
let group2 = CAAnimationGroup()
group2.animations = [scaleUp, rotate]
group2.duration = 0.35
group2.fillMode = kCAFillModeForwards
group2.removedOnCompletion = false
self.pinIt.customTouchesEndedAnimations = group2
结果
按钮可以用来避免令人反感的HUDs。它提供方便的方法来处理长时间加载过程。它可以进行相当好的定制,但示例会说明一切。
一个简单的Facebook登录按钮,包含文本和Facebook标志。我们希望它在连接过程中为 “加载中”。
该组件的默认行为是在加载过程中用 UIActivityIndicatorView
替换图片。
不是很多要做… 对于这种需求,IB就足够了。
要激活“加载状态”,您只需实现以下方法 didTapOnButton(:)
func didTapOnButton(sender: JBButton!) {
if sender == self.signInWithFacebook {
sender.startLoading(withTitle: "Signing in")
}
}
不带任何配置的方法 startLoading(:)
将替换图像为默认加载器,并替换标题。您可以不带 withTitle
参数调用该方法。
在 viewDidLoad(:)
中,您可以告诉按钮
self.signInWithFacebook.hideTitleOnLoad = true
在这种情况下,加载时将隐藏文本,加载器将居中。
一个简单的 1Password 连接按钮,包含文本和 1Password 徽标。我们希望它在连接过程中处于“加载”状态。我们想要添加自定义加载器。
// Creating a custom indicator
let indicator = NVActivityIndicatorView(frame: CGRect.zero, type: NVActivityIndicatorType.Pacman, color: UIColor.whiteColor(), padding: 0)
// Setting it to the button
self.onePassword.setCustomLoader(indicator, startAnimationBlock: { () in
indicator.startAnimation()
}, stopAnimationBlock: { () in
indicator.stopAnimation()
})
// Set the font
self.onePassword.setTitleFont(UIFont(name: "Menlo-Regular", size: 18)!)
CGRect.zero
。这会让按钮自动计算框架。
startAnimationBlock
和 stopAnimationBlock
中定义开始和停止方法,以便按钮可以正确地开始和停止动画。在此处,我使用了来自 @ninjaprox 的精彩 pod From NVActivityIndicatorView。这些指标响应自定义开始和停止方法 startAnimation()
和 stopAnimations()
。
func didTapOnButton(sender: JBButton!) {
if sender == self.onePassword {
sender.startLoading()
}
}
在 viewDidLoad(:)
中,您可以告诉按钮
self.onePassword.hideTitleOnLoad = true
在这种情况下,文本将在加载时隐藏,加载器将居中(如果框架设置为 CGRect.zero
)。
一个包含仅图像的边框按钮。我们希望“加载”过程是强化的。
👯 👯 .
// Pulse animation
let pulseAnimation = CABasicAnimation(keyPath: "transform.scale")
pulseAnimation.duration = 2
pulseAnimation.toValue = 1.15
// Rotate animation
let rotateLayerAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateLayerAnimation.duration = 0.5
rotateLayerAnimation.beginTime = 0.5
rotateLayerAnimation.fillMode = kCAFillModeBoth
rotateLayerAnimation.toValue = (360 * M_PI / 180)
// Group set to customLoadingAnimations
let group = CAAnimationGroup()
group.animations = [pulseAnimation, rotateLayerAnimation]
group.duration = 2
group.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
group.autoreverses = true
group.repeatCount = FLT_MAX
self.key.customLoadingAnimations = group
func didTapOnButton(sender: JBButton!) {
if sender == self.key {
sender.startLoading()
}
}
一个带“去吧!”标题的黑色按钮。我们希望它有阴影。我们希望“加载”状态要微妙,有一个自定义漂亮的加载器。我们希望当按下按钮时,阴影消失,当我们停止按下按钮时重新出现——当然,以动画的形式。
// Set the title font
self.go.setTitleFont(UIFont(name: "Copperplate-Light", size: 18.0)!)
// Hide the shadow on tap
let hideShadowAnimation = CABasicAnimation(keyPath: "shadowOpacity")
hideShadowAnimation.fromValue = 0.5
hideShadowAnimation.toValue = 0
let hideShadow = CAAnimationGroup()
hideShadow.animations = [hideShadowAnimation]
hideShadow.duration = 0.2
hideShadow.fillMode = kCAFillModeForwards
hideShadow.removedOnCompletion = false
self.go.customTouchesBeganAnimations = hideShadow
// Show the shadow when tap stops
let showShadowAnimation = CABasicAnimation(keyPath: "shadowOpacity")
showShadowAnimation.fromValue = 0
showShadowAnimation.toValue = 0.5
let showShadow = CAAnimationGroup()
showShadow.animations = [showShadowAnimation]
showShadow.duration = 0.2
showShadow.fillMode = kCAFillModeForwards
showShadow.removedOnCompletion = false
self.go.customTouchesEndedAnimations = showShadow
// Add a shadow
self.go.layer.masksToBounds = false
self.go.layer.shadowColor = UIColor.blackColor().CGColor
self.go.layer.shadowOffset = CGSize(width: 5, height: 5)
self.go.layer.shadowOpacity = 0.5
// Add a custom loader
let indicator = NVActivityIndicatorView(frame: CGRect.zero, type: NVActivityIndicatorType.BallPulseSync, color: UIColor.whiteColor(), padding: 0)
self.go.setCustomLoader(indicator, startAnimationBlock: { () in
indicator.startAnimation()
}, stopAnimationBlock: { () in
indicator.stopAnimation()
})
func didTapOnButton(sender: JBButton!) {
if sender == self.go {
sender.startLoading()
}
}
要以那种方式向 UIView 添加阴影,它可能没有圆角。为了将阴影添加到圆角的 UIView 中,请参看下面的示例。
基本上是一个按钮。但是…我们希望它有一个渐变层,是圆角的,有阴影,在加载时动画,在点击时动画,并且包含自定义的登录按钮。这很简单,对吧?
👯 💃
由于我想有一个圆角和阴影的按钮,我需要在 IB 中将相同大小的 JBButton
嵌入到UIView中。
// Set the title font
self.gradientLogin.setTitleFont(UIFont(name: "AmericanTypewriter-Bold", size: 18.0)!)
// Create a gradiant layer
let c1 = UIColor(red: 0/255, green: 161/255, blue: 0/255, alpha: 1)
let c2 = UIColor(red: 0/255, green: 161/255, blue: 255/255, alpha: 1)
let gradientLayer = CAGradientLayer()
gradientLayer.frame = self.gradientLogin.bounds
gradientLayer.colors = [c1.CGColor, c2.CGColor]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1)
self.gradientLogin.layer.addSublayer(gradientLayer)
// Rounded
self.gradientLogin.cornerRadius = 25
// Add the custom indicator
let indicator = NVActivityIndicatorView(frame: CGRect.zero, type: NVActivityIndicatorType.LineScalePulseOut, color: UIColor.whiteColor(), padding: 0)
self.gradientLogin.setCustomLoader(indicator, startAnimationBlock: { () in
indicator.startAnimation()
}, stopAnimationBlock: { () in
indicator.stopAnimation()
})
// Add a shadow to the container view
self.gradientLoginContainer.layer.masksToBounds = false
self.gradientLoginContainer.layer.shadowColor = UIColor.blackColor().CGColor
self.gradientLoginContainer.layer.shadowOffset = CGSize(width: 5, height: 5)
self.gradientLoginContainer.layer.shadowOpacity = 0.5
// Scale animation
let scaleSmallAnimation = CASpringAnimation(keyPath: "transform.scale")
scaleSmallAnimation.fromValue = 1.0
scaleSmallAnimation.toValue = 0.9
scaleSmallAnimation.damping = 0.4
scaleSmallAnimation.initialVelocity = 12.0
// Group set to customTouchesBeganAnimations
let touchesBegan = CAAnimationGroup()
touchesBegan.animations = [scaleSmallAnimation]
touchesBegan.duration = 0.2
touchesBegan.fillMode = kCAFillModeForwards
touchesBegan.removedOnCompletion = false
self.gradientLogin.customTouchesBeganAnimations = touchesBegan
// Scale animation
let scaleBigAnimation = CASpringAnimation(keyPath: "transform.scale")
scaleBigAnimation.fromValue = 0.9
scaleBigAnimation.toValue = 1.0
scaleBigAnimation.damping = 0.4
scaleBigAnimation.initialVelocity = 12.0
// Group set to customTouchesEndedAnimations
let touchesEnded = CAAnimationGroup()
touchesEnded.animations = [scaleBigAnimation]
touchesEnded.duration = 0.2
touchesEnded.fillMode = kCAFillModeForwards
touchesEnded.removedOnCompletion = false
self.gradientLogin.customTouchesEndedAnimations = touchesEnded
// Pulse animation
let pulseAnimation = CABasicAnimation(keyPath: "transform.scale")
pulseAnimation.duration = 2
pulseAnimation.toValue = 0.85
// Group set to customLoadingAnimations
let group = CAAnimationGroup()
group.animations = [pulseAnimation]
group.duration = 2
group.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
group.autoreverses = true
group.repeatCount = FLT_MAX
self.gradientLogin.customLoadingAnimations = group
func didTapOnButton(sender: JBButton!) {
if sender == self.gradientLogin {
sender.startLoading()
}
}