SwiftUI на macOS, как использовать собственный символ изображения на кнопке? - PullRequest
1 голос
/ 17 апреля 2020

ВНИМАТЕЛЬНО ПРОЧИТАЙТЕ ВОПРОС, ЭТО МАП. C APP, systemName недоступно на ма c os

Я пытаюсь создать простое приложение, используя swiftUI однако в macOS у меня возникают некоторые проблемы с отображением некоторых значков.

Теперь я везде читал, что вам нужно скачать приложение SF Symbols и самостоятельно экспортировать символы, чтобы использовать их, поэтому я сделал это, Затем я добавил экспортированный символ в .xcassets, и теперь я пытаюсь создать кнопку с изображением, вот код:

import SwiftUI

struct ActionBar: View {

    var body: some View {
        HStack {
            Spacer()
            Button(action: {

            }) {
                Image("Plus")
                    .font(Font.system(size: 24, weight: .light))
                    .foregroundColor(Color.red)
                Text("Test")
            }
        }
        .frame(maxWidth: .infinity)
        .padding()
        .background(Color.init(red: 0.8, green: 0.8, blue: 0.8))
    }
}

struct ActionBar_Previews: PreviewProvider {
    static var previews: some View {
        ActionBar()
    }
}

Я пробовал много вариантов, например:

Image(nsImage: NSImage(name: "Plus"))

но вся информация, включая яблоки, документация говорит только о UIImage, который, насколько я понял, является частью UIKit, который является iOS версией инфраструктуры UI Кто-нибудь заставил это работать на macOS?

Большое спасибо!

Редактировать: ресурс был импортирован как Image Symbol Set, Xcode не выдает никаких ошибок, так как я только что взял SVG генерируется SF Sy Приложение mbols и поместите его непосредственно в ресурсы.

Редактировать 2: Я просто наткнулся на эту запись , в которой говорится, что поддержка SVG не удалась ... Я пытался преобразовать SVG в PNG, но xcode не принимает pngs как наборы символов ... так что, я думаю, эта функция просто сломана? который сосет ...

Ответы [ 3 ]

2 голосов
/ 17 апреля 2020

В MacOS нет доступных системных изображений. Но NSImage.Name предоставляет альтернативный вариант. Эта ссылка показывает большинство значков системы MacOS по умолчанию.

Это пример NSImage.Name:

Icon(NSImage.refreshTemplateName)

Ниже приведено определение вида Icon:

struct Icon: View {
    var image: NSImage.Name
    var body: some View {
        Image(nsImage: NSImage(named: image)!)
            .renderingMode(.original)
            .resizable()
            .scaledToFit()
    }
    init(_ image: NSImage.Name){
        self.image = image
    }
}

PS Image представление не имеет модификатора .font(). Пожалуйста, проверьте его документацию на предмет правильного синтаксиса.

Редактировать: Вы можете пропустить дополнительный вид в следующем формате.

Image(nsImage: NSImage(name: NSImage.addTemplateName))

Список NSImage.Names: здесь

1 голос
/ 18 апреля 2020

Вот мое решение, но это очень много взлома, и я не знаю, одобрит ли это Apple. Так что рассмотрите этот ответ для «образовательных целей», я думаю.

Концепция

Основная идея состоит в том, чтобы изменить файл SVG, экспортируемый приложением SF Symbols, чтобы он содержал только один экземпляр выбранного символа вместо полного шаблона и использование инфраструктуры SVGKit для его отображения через объект NSViewRepresentable.

Export

Использование приложения SF Symbols на вашем Ma c и выберите символ, который вы хотите использовать, а затем выполните «Экспорт шаблона пользовательского символа».

Изменение

Откройте экспортированный файл SVG в текстовом редакторе, например Sublime Text или CotEditor.

Удалите все в файле, кроме заголовка и поля «Символы», которое должно содержать только вариант символа, который вы хотите использовать. Затем измените размер визуализированного холста и также правильно выровняйте символ.

Например, если вы хотите использовать версию "плюс" в "Regular-L", ваш окончательный вариант "plus.svg" Файл должен быть таким:

<?xml version="1.0" encoding="UTF-8"?>
<!--Generator: Apple Native CoreSVG 123-->
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
       "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128">
 <!--glyph: "uni10017C.medium", point size: 100.000000, font version: "Version 15.0d7e11", template writer version: "5"-->

 <g id="Symbols">
  <g id="Regular-L" transform="matrix(1 0 0 1 0 100)">
   <path d="M 67.4316 17.3828 C 70.0684 17.3828 72.2168 15.2832 72.2168 12.7441 L 72.2168 -30.3711 L 114.062 -30.3711 C 116.65 -30.3711 118.848 -32.5684 118.848 -35.1562 C 118.848 -37.793 116.65 -39.9414 114.062 -39.9414 L 72.2168 -39.9414 L 72.2168 -83.1055 C 72.2168 -85.6445 70.0684 -87.7441 67.4316 -87.7441 C 64.8438 -87.7441 62.6953 -85.6445 62.6953 -83.1055 L 62.6953 -39.9414 L 20.8496 -39.9414 C 18.2617 -39.9414 16.0645 -37.793 16.0645 -35.1562 C 16.0645 -32.5684 18.2617 -30.3711 20.8496 -30.3711 L 62.6953 -30.3711 L 62.6953 12.7441 C 62.6953 15.2832 64.8438 17.3828 67.4316 17.3828 Z"/>
  </g>
</g>
</svg>

Подводя итог:

  • Сохранить заголовок
  • Оставить поле id="Symbols"
  • В поле Символы, оставьте только одну категорию, в моем примере id="Regular-L"
  • Измените размер в заголовке, в моем примере width="128" height="128"
  • Выровняйте символ, изменив два последних параметра поле преобразования, в моем примере transform="matrix(1 0 0 1 0 100)" (x 0 и y 100)

Установить SVGKit

  • Закрыть Xcode
  • Установить SVGKit (https://github.com/SVGKit/SVGKit) с использованием версии Cocoapods
  • Откройте файл .xcworkspace, созданный Cocoapods

Создайте представление

Добавьте измененный plus.svg файл в ваш проект (не в каталоге ресурсов, а в самом проекте)

Создайте структуру NSViewRepresentable следующим образом:

import SVGKit

struct IconView: NSViewRepresentable {

    let name: String

    func makeNSView(context: Context) -> SVGKFastImageView {
        let img = SVGKImage(named: name)!
        return SVGKFastImageView(svgkImage: img)!
    }

    func updateNSView(_ nsView: SVGKFastImageView, context: Context) {
        // not implemented
    }

}

Используйте view

Затем используйте его в ContentView (дайте ему рамку, чтобы он не заполнил все окно), например:

struct ContentView: View {
    var body: some View {
        VStack {
            IconView(name: "plus")
                .frame(width: 200, height: 200, alignment: .center)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}
1 голос
/ 17 апреля 2020

вам не нужно загружать или экспортировать символы самостоятельно, просто сделайте это, и это также будет работать с катализатором ios и ma c:

import SwiftUI

struct ContentView: View {
var body: some View {
    HStack {
        Spacer()
        Button(action: {

        }) {
            Image(systemName: "plus")
                .font(Font.system(size: 24, weight: .light))
                .foregroundColor(Color.red)
            Text("Test")
        }
    }
    .frame(maxWidth: .infinity)
    .padding()
    .background(Color.init(red: 0.8, green: 0.8, blue: 0.8))
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...