Как работают векторные изображения в 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
}
}
}