常用的一些页面效果,做下记录
1. 文字渐入渐出的效果
// 创建文本视图
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 150))
label.text = "这是一段示例文字\n这是一段示例文字\n这是一段示例文字\n这是一段示例文字\n这是一段示例文字\n这是一段示例文字\n这是一段示例文字\n这是一段示例文字\n这是一段示例文字\n"
label.textColor = .black
label.numberOfLines = 0
label.font = UIFont.systemFont(ofSize: 16)
self.view.addSubview(label)
// 创建渐变蒙版图层
let gradientMaskLayer = CAGradientLayer()
gradientMaskLayer.frame = label.bounds
// 设置渐变颜色,这里从透明到白色再到透明,实现上下渐变消失效果
gradientMaskLayer.colors = [UIColor.clear.cgColor, UIColor.white.cgColor, UIColor.white.cgColor, UIColor.clear.cgColor]
// 对应颜色的位置分布,调整可改变渐变区域范围
gradientMaskLayer.locations = [0.0, 0.3, 0.7, 1.0]
// 设置渐变方向为垂直方向(从上到下)
gradientMaskLayer.startPoint = CGPoint(x: 0.5, y: 0)
gradientMaskLayer.endPoint = CGPoint(x: 0.5, y: 1)
// 将渐变蒙版图层应用到文字视图上
label.layer.mask = gradientMaskLayer
2. 静态图片作为背景的模糊效果
let context = CIContext(options: nil)
guard let image = try result.get().image.scaled(toHeight: screenHeight) else {return}
let ciImage = CIImage(cgImage: image.cgImage!)
let filter = CIFilter(name: "CIGaussianBlur")
filter?.setValue(ciImage, forKey: kCIInputImageKey)
filter?.setValue(75.0, forKey: kCIInputRadiusKey)
let result = filter?.value(forKey: kCIOutputImageKey) as! CIImage
let cgImage = context.createCGImage(result, from: result.extent)
let blurredImage = UIImage(cgImage: cgImage!)
// 将处理后的图片设置为背景
imageView.image = blurredImage
3. 剪裁图片的窗口
// 添加遮罩层
let maskLayer = CAShapeLayer()
let path = UIBezierPath(rect: view.bounds)
let cropPath = UIBezierPath(rect: .init(x: 0, y: 0, width: 100, height: 100))
path.append(cropPath.reversing())
maskLayer.path = path.cgPath
maskLayer.fillColor = UIColor(hex: 0x000000, alpha: 0.3).cgColor
self.view.layer.addSublayer(maskLayer)
4. 提取image的主要颜色
func dominantColor(from image: UIImage, darkenBy factor: CGFloat = 0.2) -> UIColor? {
// 缩小图片尺寸以加快处理速度
let scaleFactor: CGFloat = 20.0
let thumbSize = CGSize(width: image.size.width / scaleFactor, height: image.size.height / scaleFactor)
// 创建上下文
guard let cgImage = image.cgImage,
let colorSpace = CGColorSpace(name: CGColorSpace.sRGB),
let context = CGContext(data: nil,
width: Int(thumbSize.width),
height: Int(thumbSize.height),
bitsPerComponent: 8,
bytesPerRow: Int(thumbSize.width) * 4,
space: colorSpace,
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else {
return nil
}
// 在上下文中绘制缩小后的图像
context.draw(cgImage, in: CGRect(origin: .zero, size: thumbSize))
// 获取像素数据
guard let data = context.data else { return nil }
let pixelData = data.bindMemory(to: UInt8.self, capacity: Int(thumbSize.width * thumbSize.height * 4))
// 使用字典统计颜色出现频率
var colorFrequency: [UIColor: Int] = [:]
for x in 0..<Int(thumbSize.width) {
for y in 0..<Int(thumbSize.height) {
let offset = 4 * (y * Int(thumbSize.width) + x)
let red = pixelData[offset]
let green = pixelData[offset + 1]
let blue = pixelData[offset + 2]
let alpha = pixelData[offset + 3]
// 过滤透明像素
guard alpha > 0 else { continue }
// 创建颜色对象
let color = UIColor(
red: CGFloat(red) / 255.0,
green: CGFloat(green) / 255.0,
blue: CGFloat(blue) / 255.0,
alpha: CGFloat(alpha) / 255.0
)
// 统计颜色频率
colorFrequency[color, default: 0] += 1
}
}
// 找到出现次数最多的颜色
guard let dominantColor = colorFrequency.max(by: { $0.value < $1.value })?.key else { return nil }
// 调整颜色亮度
return darkenedColor(dominantColor, by: factor)
}
4.CA动画
let clockwiseFullRotation = CABasicAnimation(keyPath: "transform.rotation")
//clockwiseFullRotation.byValue = 0
clockwiseFullRotation.fromValue = 0
clockwiseFullRotation.toValue = Double.pi * 2 // 顺时针一圈
clockwiseFullRotation.duration = 1.0 // 动画时长 1 秒
clockwiseFullRotation.repeatCount = 1 //重复次数
clockwiseFullRotation.beginTime = 0.0 //开始时间
clockwiseFullRotation.speed = 1.0 //动画速度
clockwiseFullRotation.autoreverses = false //自动到放
clockwiseFullRotation.fillMode = .forwards //动画结束后的状态
layer.add(clockwiseFullRotation, forKey: "rotationAnimation")
// 创建动画组
let animationGroup = CAAnimationGroup()
animationGroup.animations = [animation, animation1, animation2]
animationGroup.duration = 1.3 // 设置动画组的总持续时间
animationGroup.repeatCount = .infinity
animationGroup.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
layer.add(animationGroup, forKey: "scaleAnimation")
1.在 CABasicAnimation 中,动画的 keyPath 决定了它作用的属性,以下是常用的动画 keyPath,分为几大类:
• position:改变图层的中心点位置。
• position.x:仅改变水平位置。
• position.y:仅改变垂直位置。
• anchorPoint:改变图层的锚点位置。
• opacity:改变图层的不透明度,范围是 0.0(完全透明)到 1.0(完全不透明)。
• transform.scale:整体缩放(x、y、z 方向同时缩放)。
• transform.scale.x:水平缩放。
• transform.scale.y:垂直缩放。
• transform.scale.z:深度缩放。
• transform.rotation:绕 z 轴旋转(单位是弧度)。
• transform.rotation.x:绕 x 轴旋转。
• transform.rotation.y:绕 y 轴旋转。
• transform.rotation.z:绕 z 轴旋转。
• backgroundColor:背景颜色的变化。
• borderColor:边框颜色的变化。
• shadowColor:阴影颜色的变化。
• borderWidth:边框宽度的变化。
• cornerRadius:圆角半径的变化。
• shadowOffset:阴影偏移量的变化。
• shadowOpacity:阴影透明度的变化。
• shadowRadius:阴影模糊半径的变化。
• transform:综合形变,可以包含旋转、缩放、平移等。
• transform.translation.x:沿 x 轴平移。
• transform.translation.y:沿 y 轴平移。
• transform.translation.z:沿 z 轴平移。
• path:形状路径的变化(通常用于 CAShapeLayer 的 path 属性)。
• contents:图层内容的变化(例如图像替换)。
• zPosition:改变图层在 z 轴的顺序。
• bounds:图层边界的变化(大小)。
• frame:图层的框架(位置和大小)。
• masksToBounds:是否剪裁子图层。
2.fillMode 决定动画执行后的视觉效果:
• .forwards 表示动画结束后,图层将保持在动画结束的状态(虽然视觉效果是保持的,但实际上图层的真实值并未改变,仍是初始值)。
• 常见的 fillMode 选项:
• .removed(默认值):动画结束后恢复到初始状态。
• .forwards:动画结束后保持在结束状态。
• .backwards:动画开始前,先应用开始状态。
• .both:结合 .forwards 和 .backwards。