0

When adding assets for the Graphic Circular Complication there is no option to add an asset for the 45mm version, thus the image does not fill the available space.

enter image description here

Result (The image does not fill the space as it is too small):

enter image description here

I have read that I need to use PDF assets for the 40/42mm but my image is a raster image and thus I can't create it as a PDF. I want to scale the image myself and add it as an asset but there is no option to drop it.

What should I do?

SwiftiSwift
  • 7,528
  • 9
  • 56
  • 96

1 Answers1

1

The issue is that the size of the image in the asset catalog is smaller than it really should be according to the Apple Human Interface Guidelines. Thus this causes the images not to be filled. As there's no option to drop the 45mm version you need to calculate and resize the image yourself.

This article is the solution!

http://www.glimsoft.com/02/18/watchos-complications/?utm_campaign=iOS%2BDev%2BWeekly&utm_medium=web&utm_source=iOS%2BDev%2BWeekly%2BIssue%2B547

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
}
SwiftiSwift
  • 7,528
  • 9
  • 56
  • 96