在iOS 8键盘扩展中实现键盘按键popupanimation

我想问如何在按住iOS 8键盘扩展的键盘键时实现stream行animation。 我知道如何在每个按键上分配长按手势,但不知道如何使按键animation来呈现该特定按键中的其他字符。 任何帮助,将不胜感激。 谢谢! 🙂

编辑:我在这里看到这个类似的问题,但不同的是,他能够创buildstream行animation。

编辑2:我看到另一个类似的问题在这里被问到,但它们与标准键盘上的默认外观相比看起来有什么不同。

轻触扩展键盘按键

编辑3:我能够实现我想要的行为,当轻敲键盘按键。 我只需要知道如何正确绘制扩展的关键视图。 附上图片供参考。 第一个是我们迄今为止取得的成就。 我想知道如何绘制该字母F键,然后将其转换为UIView

现在的进展

编辑4:我能够创build按键popup视图,但不是在所需的形状或层,我想这就像标准的键盘按键popup。 这里供参考:

当前的关键弹出视图

编辑5:我尝试了PaintCode的演示版本,它生成下面的代码。 这是我的自定义视图的drawRect方法。 我的键宽度通常是26.0和39.0的高度。 我也使用Objective-C btw。

  UIBezierPath* bezierPath = UIBezierPath.bezierPath; [bezierPath moveToPoint: CGPointMake(26, 5.12)]; [bezierPath addLineToPoint: CGPointMake(26, 18.03)]; [bezierPath addCurveToPoint: CGPointMake(23.05, 22.41) controlPoint1: CGPointMake(26, 19.88) controlPoint2: CGPointMake(24.82, 21.51)]; [bezierPath addCurveToPoint: CGPointMake(19.62, 25.27) controlPoint1: CGPointMake(22.05, 23.24) controlPoint2: CGPointMake(20.79, 24.3)]; [bezierPath addCurveToPoint: CGPointMake(19.62, 39.95) controlPoint1: CGPointMake(19.62, 30.82) controlPoint2: CGPointMake(19.62, 39.95)]; [bezierPath addCurveToPoint: CGPointMake(17.17, 42) controlPoint1: CGPointMake(19.62, 41.08) controlPoint2: CGPointMake(18.52, 42)]; [bezierPath addLineToPoint: CGPointMake(8.83, 42)]; [bezierPath addCurveToPoint: CGPointMake(6.38, 39.95) controlPoint1: CGPointMake(7.48, 42) controlPoint2: CGPointMake(6.38, 41.08)]; [bezierPath addCurveToPoint: CGPointMake(6.38, 25.33) controlPoint1: CGPointMake(6.38, 39.95) controlPoint2: CGPointMake(6.38, 30.89)]; [bezierPath addCurveToPoint: CGPointMake(5.67, 24.74) controlPoint1: CGPointMake(6.15, 25.14) controlPoint2: CGPointMake(5.91, 24.94)]; [bezierPath addCurveToPoint: CGPointMake(5.37, 24.49) controlPoint1: CGPointMake(5.57, 24.66) controlPoint2: CGPointMake(5.47, 24.57)]; [bezierPath addLineToPoint: CGPointMake(5.32, 24.45)]; [bezierPath addCurveToPoint: CGPointMake(2.75, 22.3) controlPoint1: CGPointMake(4.41, 23.69) controlPoint2: CGPointMake(3.5, 22.93)]; [bezierPath addCurveToPoint: CGPointMake(1.02, 20.85) controlPoint1: CGPointMake(2.06, 21.92) controlPoint2: CGPointMake(1.47, 21.43)]; [bezierPath addCurveToPoint: CGPointMake(0.98, 20.82) controlPoint1: CGPointMake(0.99, 20.83) controlPoint2: CGPointMake(0.98, 20.82)]; [bezierPath addCurveToPoint: CGPointMake(0, 18.03) controlPoint1: CGPointMake(0.36, 20.02) controlPoint2: CGPointMake(-0, 19.06)]; [bezierPath addLineToPoint: CGPointMake(0, 5.12)]; [bezierPath addCurveToPoint: CGPointMake(2.48, 1.01) controlPoint1: CGPointMake(0, 3.44) controlPoint2: CGPointMake(0.97, 1.94)]; [bezierPath addCurveToPoint: CGPointMake(6.05, 0) controlPoint1: CGPointMake(3.48, 0.39) controlPoint2: CGPointMake(4.71, 0.02)]; [bezierPath addLineToPoint: CGPointMake(6.13, 0)]; [bezierPath addLineToPoint: CGPointMake(19.87, 0)]; [bezierPath addCurveToPoint: CGPointMake(26, 5.12) controlPoint1: CGPointMake(23.25, 0) controlPoint2: CGPointMake(26, 2.29)]; [bezierPath closePath]; [[UIColor redColor] setFill]; [bezierPath fill]; 

问题是,它看起来像这样:

在这里输入图像说明

如果只有我可以使它足够大,使其像默认的键盘,那么它会工作。

我会用一个CAShapeLayer

您可以随时重置形状图层的形状,甚至可以将形状变化设置为与Apple版本相比更加细致。

这里是一个操场的代码,演示了一个类的简单版本来完成这个:

 import UIKit class KeyPopView: UIView { static let widthPadding : CGFloat = 5.0 static let leftOffset : CGFloat = -5.0 init(frame: CGRect, letters: [String]) { super.init(frame: frame) addLetters(letters) } required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override class func layerClass() -> AnyClass { return CAShapeLayer.self } override func layoutSubviews() { super.layoutSubviews() var run : CGFloat = KeyPopView.widthPadding for l in labels { let s = sizeForLabel(l) let mh = maxHeight(labels) l.frame = CGRectMake(run, -mh, s.width, s.height) run += s.width + KeyPopView.widthPadding } } var shapeLayer: CAShapeLayer { get { return layer as! CAShapeLayer } } var path: CGPathRef { get { return shapeLayer.path } set(nv) { shapeLayer.shadowPath = nv shapeLayer.path = nv } } var labels : [UILabel] = [] { willSet { for l in labels { l.removeFromSuperview() } } didSet { for l in labels { addSubview(l) } path = keyPopPath(labels, cornerRadius: cornerRadius).CGPath } } var cornerRadius : CGFloat = 4 { didSet { path = keyPopPath(labels, cornerRadius: cornerRadius).CGPath } } override var backgroundColor: UIColor? { set(newValue) { shapeLayer.fillColor = newValue?.CGColor } get { return UIColor(CGColor: shapeLayer.fillColor) } } func keyPopPath(ls : [UILabel], cornerRadius: CGFloat) -> UIBezierPath { let radius = CGSizeMake(cornerRadius, cornerRadius); let f = CGRectMake(0, 0, frame.width + KeyPopView.widthPadding * 2, frame.height) let mh = maxHeight(ls) var b = UIBezierPath(roundedRect: CGRectMake(KeyPopView.leftOffset, -mh, widthForLabels(ls) - KeyPopView.leftOffset + KeyPopView.widthPadding, mh), byRoundingCorners: UIRectCorner.AllCorners, cornerRadii: radius) b.appendPath(UIBezierPath(roundedRect: f, byRoundingCorners: UIRectCorner.BottomLeft | UIRectCorner.BottomRight, cornerRadii: radius)) return b } func addLetters(letters : [String]) { labels = letters.map({(s: String) -> UILabel in var l = UILabel() l.text = s return l }) } func widthForLabels(ls: [UILabel]) -> CGFloat { return ls.reduce(0, combine: {(t, l) in t + sizeForLabel(l).width + KeyPopView.widthPadding}) + KeyPopView.widthPadding } func sizeForLabel(l: UILabel) -> CGSize { return l.text!.sizeWithAttributes([NSFontAttributeName: l.font]) } func maxHeight(ls: [UILabel]) -> CGFloat { var m : CGFloat = 0; for l in ls { let h = sizeForLabel(l).height m = m > h ? m : h } return m } } //start with a gray background view var ba = UIView(frame: CGRectMake(0, 0, 300, 300)) ba.backgroundColor = UIColor.grayColor() //add a mock "key" let key = UILabel() key.text = "a" key.textAlignment = NSTextAlignment.Center key.backgroundColor = UIColor.whiteColor() let size = key.text!.sizeWithAttributes([NSFontAttributeName: key.font]) key.frame = CGRectMake(5, 0, size.width + 10, size.height) key.layer.cornerRadius = 5 key.center = ba.center ba.addSubview(key) //add the initial keypop key.hidden = true // the key's rounded corners aren't showing up correctly in my playground preview -- this shouldn't be necessary var k = KeyPopView(frame: CGRectMake(0, 0, size.width, size.height), letters: ["a"]) k.backgroundColor = UIColor.whiteColor() ba.addSubview(k) k.center = CGPointMake(key.center.x - 5, key.center.y) ba //demonstrates resizing of the keypop view to accomdate more letters k.addLetters(["a", "b", "c", "d", "e"]) ba 

在目前的forms下,这门课有许多问题:

  • 信件稍微偏离中心
  • 视图的框架被用作stream行开始的关键帧,而不是被绘制的实际框架。
  • 它只支持左键popup
  • 几个可选项是强制解包
  • 所用path的“干”不像系统键盘那样具有圆angular的内angular
  • variables的名字是为了简洁而不是清晰

但是这应该为实现你想要的东西提供一个很好的基础。

可能是最简单的做只是在Photoshop中的animation或者可以输出animation帧作为单独的图像,然后animationUIImageView ( 文档 )。

所以只要有上面提到的popup东西animation的背景,那么就可以使字母与animation一起淡入,或者用背景animation仔细地animationUILabel