如何提供 Apple Watch Complication Asset for 45mm?
How to provide Apple Watch Complication Asset for 45mm?
为 Graphic Circular Complication
添加资产时,没有为 45mm 版本添加资产的选项,因此图像未填充可用的 space。
结果(图像未填满 space,因为它太小):
我了解到我需要为 40/42mm 使用 PDF 资源,但我的图像是光栅图像,因此我无法将其创建为 PDF。我想自己缩放图像并将其添加为资产,但没有删除它的选项。
我该怎么办?
问题是资产目录中的图像尺寸小于 Apple Human Interface Guidelines 中的实际尺寸。因此,这会导致图像不被填充。由于没有删除 45mm 版本的选项,您需要自己计算和调整图像大小。
这篇文章就是解决方案!
ComplicationController+Ext.swift
extension ComplicationController {
enum ComplicationImageType {
case graphicCircularImage
}
struct ComplicationImageSizeCollection {
var size38mm: CGFloat = 0
let size40mm: CGFloat
let size41mm: CGFloat
let size44mm: CGFloat
let size45mm: CGFloat
// The following sizes are taken directly from HIG: https://developer.apple.com/design/human-interface-guidelines/watchos/overview/complications/
static let graphicCircularImageSizes = ComplicationImageSizeCollection(size40mm: 42, size41mm: 44.5, size44mm: 47, size45mm: 50)
func sizeForCurrentWatchModel() -> CGFloat {
let screenHeight = WKInterfaceDevice.current().screenBounds.size.height
if screenHeight >= 242 {
// It's the 45mm version..
return self.size45mm
}
else if screenHeight >= 224 {
// It's the 44mm version..
return self.size44mm
}
else if screenHeight >= 215 {
// It's the 41mm version..
return self.size41mm
}
else if screenHeight >= 197 {
return self.size40mm
}
else if screenHeight >= 170 {
return self.size38mm
}
return self.size40mm // Fallback, just in case.
}
static func sizes(for type: ComplicationImageType) -> ComplicationImageSizeCollection {
switch type {
case .graphicCircularImage: return Self.graphicCircularImageSizes
}
}
static func getImage(for type: ComplicationImageType) -> UIImage {
let complicationImageSizes = ComplicationImageSizeCollection.sizes(for: .graphicCircularImage)
let width = complicationImageSizes.sizeForCurrentWatchModel()
let size = CGSize(width: width, height: width)
var filename: String!
switch type {
case .graphicCircularImage: filename = "gedenken_graphic_circular_pdf"
}
return renderPDFToImage(named: filename, outputSize: size)
}
static private func renderPDFToImage(named filename: String, outputSize size: CGSize) -> UIImage {
// Create a URL for the PDF file
let resourceName = filename.replacingOccurrences(of: ".pdf", with: "")
let path = Bundle.main.path(forResource: resourceName, ofType: "pdf")!
let url = URL(fileURLWithPath: path)
guard let document = CGPDFDocument(url as CFURL),
let page = document.page(at: 1) else {
fatalError("We couldn't find the document or the page")
}
let originalPageRect = page.getBoxRect(.mediaBox)
// With the multiplier, we bring the pdf from its original size to the desired output size.
let multiplier = size.width / originalPageRect.width
UIGraphicsBeginImageContextWithOptions(size, false, 0)
let context = UIGraphicsGetCurrentContext()!
// Translate the context
context.translateBy(x: 0, y: (originalPageRect.size.height * multiplier))
// Flip the context vertically because the Core Graphics coordinate system starts from the bottom.
context.scaleBy(x: multiplier * 1.0, y: -1.0 * multiplier)
// Draw the PDF page
context.drawPDFPage(page)
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
}
}
ComplicationController.swift
func createGraphicCircularTemplate() -> CLKComplicationTemplate {
let template = CLKComplicationTemplateGraphicCircularImage()
let imageLogoProvider = CLKFullColorImageProvider()
imageLogoProvider.image = ComplicationImageSizeCollection.getImage(for: .graphicCircularImage)
template.imageProvider = imageLogoProvider
return template
}
为 Graphic Circular Complication
添加资产时,没有为 45mm 版本添加资产的选项,因此图像未填充可用的 space。
结果(图像未填满 space,因为它太小):
我了解到我需要为 40/42mm 使用 PDF 资源,但我的图像是光栅图像,因此我无法将其创建为 PDF。我想自己缩放图像并将其添加为资产,但没有删除它的选项。
我该怎么办?
问题是资产目录中的图像尺寸小于 Apple Human Interface Guidelines 中的实际尺寸。因此,这会导致图像不被填充。由于没有删除 45mm 版本的选项,您需要自己计算和调整图像大小。
这篇文章就是解决方案!
ComplicationController+Ext.swift
extension ComplicationController {
enum ComplicationImageType {
case graphicCircularImage
}
struct ComplicationImageSizeCollection {
var size38mm: CGFloat = 0
let size40mm: CGFloat
let size41mm: CGFloat
let size44mm: CGFloat
let size45mm: CGFloat
// The following sizes are taken directly from HIG: https://developer.apple.com/design/human-interface-guidelines/watchos/overview/complications/
static let graphicCircularImageSizes = ComplicationImageSizeCollection(size40mm: 42, size41mm: 44.5, size44mm: 47, size45mm: 50)
func sizeForCurrentWatchModel() -> CGFloat {
let screenHeight = WKInterfaceDevice.current().screenBounds.size.height
if screenHeight >= 242 {
// It's the 45mm version..
return self.size45mm
}
else if screenHeight >= 224 {
// It's the 44mm version..
return self.size44mm
}
else if screenHeight >= 215 {
// It's the 41mm version..
return self.size41mm
}
else if screenHeight >= 197 {
return self.size40mm
}
else if screenHeight >= 170 {
return self.size38mm
}
return self.size40mm // Fallback, just in case.
}
static func sizes(for type: ComplicationImageType) -> ComplicationImageSizeCollection {
switch type {
case .graphicCircularImage: return Self.graphicCircularImageSizes
}
}
static func getImage(for type: ComplicationImageType) -> UIImage {
let complicationImageSizes = ComplicationImageSizeCollection.sizes(for: .graphicCircularImage)
let width = complicationImageSizes.sizeForCurrentWatchModel()
let size = CGSize(width: width, height: width)
var filename: String!
switch type {
case .graphicCircularImage: filename = "gedenken_graphic_circular_pdf"
}
return renderPDFToImage(named: filename, outputSize: size)
}
static private func renderPDFToImage(named filename: String, outputSize size: CGSize) -> UIImage {
// Create a URL for the PDF file
let resourceName = filename.replacingOccurrences(of: ".pdf", with: "")
let path = Bundle.main.path(forResource: resourceName, ofType: "pdf")!
let url = URL(fileURLWithPath: path)
guard let document = CGPDFDocument(url as CFURL),
let page = document.page(at: 1) else {
fatalError("We couldn't find the document or the page")
}
let originalPageRect = page.getBoxRect(.mediaBox)
// With the multiplier, we bring the pdf from its original size to the desired output size.
let multiplier = size.width / originalPageRect.width
UIGraphicsBeginImageContextWithOptions(size, false, 0)
let context = UIGraphicsGetCurrentContext()!
// Translate the context
context.translateBy(x: 0, y: (originalPageRect.size.height * multiplier))
// Flip the context vertically because the Core Graphics coordinate system starts from the bottom.
context.scaleBy(x: multiplier * 1.0, y: -1.0 * multiplier)
// Draw the PDF page
context.drawPDFPage(page)
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
}
}
ComplicationController.swift
func createGraphicCircularTemplate() -> CLKComplicationTemplate {
let template = CLKComplicationTemplateGraphicCircularImage()
let imageLogoProvider = CLKFullColorImageProvider()
imageLogoProvider.image = ComplicationImageSizeCollection.getImage(for: .graphicCircularImage)
template.imageProvider = imageLogoProvider
return template
}