UIKit 像素对齐
Pixel aligns rectangles, taking the device’s screen scale into account.
像素出现锯齿,如何解决?
常见的场景
#if canImport(UIKit)
protocol PixelAlignedGeometry {
var pixelAligned: Self { get }
}
extension CGFloat: PixelAlignedGeometry {
/// defaul ceil
var pixelAligned: CGFloat {
if self == 0 { return self }
let scale = UIScreen.main.scale
return ceil(self * scale) / scale
}
}
extension CGPoint: PixelAlignedGeometry {
var pixelAligned: CGPoint {
if self == .zero { return self }
return .init(x: x.pixelAligned, y: y.pixelAligned)
}
}
extension CGSize: PixelAlignedGeometry {
var pixelAligned: CGSize {
if self == .zero { return self }
return .init(width: width.pixelAligned, height: height.pixelAligned)
}
}
extension CGRect: PixelAlignedGeometry {
/// CGRect.pixelAligned apply the same trategy as CGRect.integral
///
/// A rectangle with the smallest pixelAligned float values for its origin and size that contains the source rectangle. That is, given a rectangle with fractional origin or size values, pixelAligned rounds the rectangle’s origin downward and its size upward to the nearest whole pixelAligned floats, such that the result contains the original rectangle. Returns a null rectangle if rect is a null rectangle.
var pixelAligned: CGRect {
if isEmpty || isNull || isInfinite { return self }
let scale = UIScreen.main.scale
return .init(x: floor(origin.x * scale) / scale,
y: floor(origin.y * scale) / scale,
width: ceil(size.width * scale) / scale,
height: ceil(size.height * scale) / scale)
}
}
extension UIEdgeInsets: PixelAlignedGeometry {
var pixelAligned: UIEdgeInsets {
if self == .zero { return self }
return .init(top: top.pixelAligned,
left: left.pixelAligned,
bottom: bottom.pixelAligned,
right: right.pixelAligned)
}
}
#endif