Как работают векторные изображения в Xcode (т.е. Файлы в формате pdf)?

Как работает векторная поддержка в Xcode 6?

Когда я пытаюсь изменить размер изображения, он выглядит неровным, что дает?

Ответ 1

Как использовать векторы в Xcode (7 и 6.3 +):

  • Сохраните изображение как .pdf файл с соответствующим размером @1x (например, 44x44 для кнопки на панели инструментов).
  • В вашем файле Images.xcassets создайте новый набор изображений.
  • В Attributes Inspector установите Масштабные коэффициенты на Один вектор.
  • Перетащите файл pdf в раздел Все, Универсальный.
  • Теперь вы можете ссылаться на свое изображение по его имени так же, как и на любой файл .png.

    UIImage(named: "myImage")
    

Как использовать векторы в старых версиях Xcode (6.0 - 6.2): ​​

  • Выполните действия, описанные выше, за исключением шага 3, установите Типы на Векторы.

Как работают векторы в Xcode

Поддержка векторов запутывается в Xcode, потому что, когда большинство людей думает о векторах, они думают о изображениях, которые могут масштабироваться вверх и вниз и по-прежнему выглядят хорошо. Однако Xcode 6 и 7 не имеют полной векторной поддержки для iOS, поэтому все работает немного по-другому.

Векторная система очень простая. Он принимает ваше изображение .pdf и создает @1x.png, @2x.png и @3x.png активы в время сборки. (Вы можете использовать инструмент для проверки содержимого Assets.car, чтобы проверить это.)

Например, предположим, что вам предоставляется foo.pdf, который представляет собой векторный ресурс 44x44. В время сборки он будет генерировать следующие файлы:

Это работает одинаково для любого размера изображения. Например, если у вас есть bar.pdf, который равен 100x100, вы получите:


Последствия:

  • Вы не можете выбрать новый размер для изображения; он будет выглядеть только хорошо, если вы держите его в размере 44x44. Причина в том, что полная поддержка векторов не реализована. Единственное, что делают эти векторы, это экономить время сохранения ваших имиджевых активов. Если у вас есть инструмент (например, Photoshop script), который уже делает это одноэтапным процессом, единственное, что вы получите, используя векторы pdf, - это надежная поддержка (например, если в iOS 9 Apple начинает требовать активы @4x, они будут работать), и у вас будет меньше файлов для поддержки.
  • Вы должны запросить все свои активы размером @1x, сохраненные как файлы PDF. Помимо прочего, это позволит UIImageViews иметь правильный собственный размер содержимого.

Почему это (возможно) работает следующим образом:

  • Это делает его обратно совместимым с предыдущими версиями iOS.
  • Изменение размеров векторов может быть сложной вычислительной задачей во время выполнения; реализуя его таким образом, нет показов производительности.

Ответ 2

В Xcode 8 вы все равно можете добавить PDF файл, создать новый набор изображений и в инспекторе атрибутов установить параметр "Масштабы в единую шкалу". введите описание изображения здесь

Ответ 3

Это дополнение к отличному ответу @Senseful.

Как сделать векторные изображения в формате .pdf

Я расскажу, как это сделать в Inkscape, так как это бесплатный и открытый исходный код, но другие программы должны быть похожими.

В Inkscape:

  • Создайте новый проект.
  • Перейдите в меню "Файл" > "Свойства документа" и задайте размер настраиваемой страницы независимо от размера вашего @1x (44x44, 100x100 и т.д.) с единицами в px.
  • Сделайте свое произведение.
  • Перейдите в Файл > Сохранить как... > Формат документа для печати (*.pdf) > Сохранить > ОК. (Кроме того, вы можете перейти в "Печать" > "Печать в файл" > "Формат вывода: PDF > Печать", но вариантов не так много.)

Примечания:

  • Как упоминается в принятом ответе, вы не можете изменять размер изображения, потому что Xcode по-прежнему создает растрированные изображения во время сборки. Если вам нужно изменить размер изображения, вы должны создать новый .pdf файл с другим размером.
  • Если у вас уже есть изображение .svg, которое является неправильным размером страницы, выполните следующие действия:

    • Измените размер страницы (Inkscape > Файл > Свойства документа)
    • Выберите все объекты (Ctrl + A) на рабочем пространстве и измените их размер в соответствии с новым размером страницы. (Удерживайте Ctrl, чтобы сохранить размер аспект.)
  • Чтобы преобразовать файл .svg в .pdf, вы также можете найти онлайн-утилиты для выполнения этой работы. Вот один пример из этого ответа. Это дает вам возможность легко установить размер .pdf.

Дальнейшее чтение

Ответ 4

Вы можете использовать обычные PDF файлы в своем проекте в качестве векторных изображений и делать изображения любых размеров с помощью этого расширения. Этот способ лучше, потому что iOS не будет генерировать изображения PNG из ваших файлов PDF, а также вы можете отображать изображения любого размера, который вы хотите:

extension UIImage {

static func fromPDF(filename: String, size: CGSize) -> UIImage? {
    guard let path = Bundle.main.path(forResource: filename, ofType: "pdf") else { return nil }
    let url = URL(fileURLWithPath: path)
    guard let document = CGPDFDocument(url as CFURL) else { return nil }
    guard let page = document.page(at: 1) else { return nil }

    let imageRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
    if #available(iOS 10.0, *) {
        let renderer = UIGraphicsImageRenderer(size: size)
        let img = renderer.image { ctx in
            UIColor.white.withAlphaComponent(0).set()
            ctx.fill(imageRect)
            ctx.cgContext.translateBy(x: 0, y: size.height)
            ctx.cgContext.scaleBy(x: 1.0, y: -1.0)
            ctx.cgContext.concatenate(page.getDrawingTransform(.artBox, rect: imageRect, rotate: 0, preserveAspectRatio: true))
            ctx.cgContext.drawPDFPage(page);
        }

        return img
    } else {
        // Fallback on earlier versions
        UIGraphicsBeginImageContextWithOptions(size, false, 2.0)
        if let context = UIGraphicsGetCurrentContext() {
            context.interpolationQuality = .high
            context.setAllowsAntialiasing(true)
            context.setShouldAntialias(true)
            context.setFillColor(red: 1, green: 1, blue: 1, alpha: 0)
            context.fill(imageRect)
            context.saveGState()
            context.translateBy(x: 0.0, y: size.height)
            context.scaleBy(x: 1.0, y: -1.0)
            context.concatenate(page.getDrawingTransform(.cropBox, rect: imageRect, rotate: 0, preserveAspectRatio: true))
            context.drawPDFPage(page)
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return image
        }
        return nil
    }
}

}