原创不易,对你有帮助的话,点个赞支持一下~
聊天冒泡 的界面
一、Objective-C版本(如需要Swift版本,还请留言,后续更新)
效果图如下:
图描述:红色的是点,从图可知,四个角分别都有三个点,这里要做圆角处理,我暂时想到的是用 addArcWithCenter 方法来画弧线,里面的角其实是一个圆点。对于圆的角度如下图(这个圆形图借用了其它博主的):
代码实现如下:
- (void)drawBubble:(CGRect)rect {
UIBezierPath *mainPath = [[UIBezierPath alloc] init];
CGFloat maxX = rect.size.width - 50;
CGFloat maxY = rect.size.height;
CGFloat minX = 0;
CGFloat minY = 0;
//自定义圆角的半径
CGFloat radius = 10;
/**
顶点值点越小越往里面的收缩
**/
//冒泡三角形突出的顶点
CGFloat cornerLength = 30;
/**
top点和bottom点越小越往中间的收缩
**/
//冒泡三角形的底边的top点
CGFloat cornerTopY1 = 15;
//冒泡三角形的底边的bottom点
CGFloat cornerBottomY2 = 15;
//起点
[mainPath moveToPoint:CGPointMake(maxX - radius, maxY)];
[mainPath addLineToPoint:CGPointMake(minX + radius, maxY)];
[mainPath addArcWithCenter:CGPointMake(minX + radius, maxY - radius) radius:radius startAngle:0.5*M_PI endAngle:1*M_PI clockwise: true];
[mainPath addLineToPoint:CGPointMake(minX, maxY - radius)];
[mainPath addLineToPoint:CGPointMake(minX, radius)];
[mainPath addArcWithCenter:CGPointMake(radius, radius) radius:radius startAngle:1*M_PI endAngle:1.5*M_PI clockwise: true];
[mainPath addLineToPoint:CGPointMake(radius, minY)];
[mainPath addLineToPoint:CGPointMake(maxX - radius, minY)];
[mainPath addArcWithCenter:CGPointMake(maxX - radius, minY + radius) radius:radius startAngle:1.5*M_PI endAngle:0*M_PI clockwise: true];
[mainPath addLineToPoint:CGPointMake(maxX, minY + 10)];
[mainPath addLineToPoint:CGPointMake(maxX, maxY/2 - cornerTopY1)];
[mainPath addLineToPoint:CGPointMake(maxX + cornerLength, maxY/2)];
[mainPath addLineToPoint:CGPointMake(maxX, maxY/2 + cornerTopY1)];
[mainPath addLineToPoint:CGPointMake(maxX, maxY - radius)];
[mainPath addArcWithCenter:CGPointMake(maxX - radius, maxY - radius) radius:radius startAngle:0*M_PI endAngle:0.5*M_PI clockwise: true];
[mainPath closePath];
[mainPath stroke];
CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
shapeLayer.path = mainPath.CGPath;
self.layer.mask = shapeLayer;
}
**备注:**我这里是的聊天冒泡界面是整个UIView来的,因此可以在里面添加内容等。这里需要在Draw方法里面的进行调用(Draw方法是指UIView类里面方法,非自定义)
实现圆圈动画
效果静态图如下:
private var gradientLayer: CALayer? // MARK: 加载小圆圈
func addLoadingAnimation(superView: UIView) {
if self.gradientLayer != nil {
self.gradientLayer?.removeFromSuperlayer()
self.gradientLayer = nil
}
// 形状
let lineWidth: CGFloat = 7
let middleColor = UIColor.hex_00efe7
let circleLayer = CAShapeLayer.init()
circleLayer.lineWidth = lineWidth;
// circleLayer.frame = self.translateTypeView.bounds
circleLayer.fillColor = UIColor.clear.cgColor
circleLayer.strokeColor = UIColor.black.cgColor
// 曲线
// let circlePath = UIBezierPath.init(arcCenter: CGPoint(x: self.translateTypeView.width / 2, y: self.translateTypeView.height / 2), radius: self.translateTypeView.height / 2, startAngle: CGFloat(-Double.pi / 2), endAngle: CGFloat(Double.pi * 2), clockwise: true) // 有毛边
let circlePath = UIBezierPath.init(ovalIn: superView.bounds)
circleLayer.path = circlePath.cgPath
// 渐变
self.gradientLayer = CALayer.init()
// 渐变1
let gradient = CAGradientLayer.init()
gradient.frame = CGRect(x: -lineWidth * 2, y: -lineWidth * 2, width: superView.bounds.size.width / 2 + lineWidth * 2, height: superView.bounds.size.height + lineWidth*3)
gradient.colors = [UIColor.hex_333333.cgColor, middleColor.cgColor]
// gradient.locations = [NSNumber(value: 0.1), NSNumber(value:1.0)] // 设置比例
gradient.startPoint = CGPoint(x: 0.0, y: 0.0)
gradient.endPoint = CGPoint(x: 0.0, y: 1.0)
gradient.shadowPath = circlePath.cgPath
// 渐变1
let gradient2 = CAGradientLayer.init()
gradient2.frame = CGRect(x: superView.bounds.size.width / 2, y: -lineWidth * 2, width: superView.bounds.size.width / 2 + lineWidth * 2, height: superView.bounds.size.height + lineWidth*3)
gradient2.colors = [UIColor.hex_00efe7.cgColor, middleColor.cgColor]
// gradient2.locations = [NSNumber(value: 0.1), NSNumber(value:1.0)]
gradient2.startPoint = CGPoint(x: 0.0, y: 0.0)
gradient2.endPoint = CGPoint(x: 0.0, y: 1.0)
gradient2.shadowPath = circlePath.cgPath
gradientLayer!.addSublayer(gradient)
gradientLayer!.addSublayer(gradient2)
gradientLayer!.mask = circleLayer
// CABasicAnimation strokeEnd动画
// let pathAnimation = CABasicAnimation()
// pathAnimation.keyPath = "strokeEnd"
// pathAnimation.duration = 1.0
// pathAnimation.fillMode = CAMediaTimingFillMode.forwards
// pathAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
// pathAnimation.fromValue = 0.0
// pathAnimation.toValue = 1.0
// pathAnimation.repeatCount = 1
// circleLayer.add(pathAnimation, forKey: "strokeEndAnimationcircle")
// 旋转z
let rotateAnima = CABasicAnimation.init(keyPath: "transform.rotation.z")
rotateAnima.duration = 1.0
rotateAnima.repeatCount = HUGE
rotateAnima.fromValue = NSNumber(value: 0.0)
rotateAnima.toValue = NSNumber(value: Double.pi * 2)
// rotateAnima.beginTime = CACurrentMediaTime() + 3.0 / 4.0
gradientLayer!.add(rotateAnima, forKey: "rotateAnimationcircle")
gradientLayer!.frame = superView.bounds // 一定要设置frame,不然anchorPoint(锚点--旋转中心点始终是(0,0))
superView.layer.addSublayer(gradientLayer!)
}