我想问一下如何在持有iOS 8键盘扩展键盘键时实现流行动画。我知道如何在每个键上分配长按手势,但不知道如何设置键的动画以呈现该特定键中的其他字符。
编辑:我看到这个类似的问题被问到here,但区别在于他能够制作流行动画。
编辑2:我看到另一个类似的问题被问到here,但与标准键盘上的默认外观相比,它们的外观有所不同。
编辑3 :点击键盘键时,我能够达到理想的行为。我只需要知道如何正确绘制扩展的关键视图。附图片供参考。第一个是我们到目前为止所取得的成就。我想知道如何绘制该字母F键,然后将其翻译为UIView
。
编辑4:我能够创建关键的弹出视图,但不能创建我想要的类似于标准键盘弹出窗口的所需形状或图层。这里仅供参考:
编辑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];
问题是,它看起来像这样:
如果只有我可以使它足够大以使其像默认键盘一样,那么它就可以工作。
答案 0 :(得分:7)
我会使用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
目前的形式,这个课有很多问题:
然而,这应该为实现你想要的东西提供良好的基础。
答案 1 :(得分:0)
最简单的方法是在photoshop中做动画或者可以将动画帧作为单独的图像输出,然后为UIImageView
(docs)设置动画。
因此,只需以上述方式设置弹出式动画的背景,然后可以使动画淡入淡出,或者使用背景动画小心地动画UILabel