Как мне исчезнуть верхний или нижний край символа SF в SwiftUI? - PullRequest
1 голос
/ 25 января 2020

Я пытаюсь воссоздать визуал, который состоит из 3 символов SF. Изображение в середине 100% solid без выцветания. Я хотел бы добавить верхний край самого верхнего изображения и нижний край самого нижнего изображения.

Я использую символы SF.

Я хотел бы воспроизвести следующее:

(верхняя часть изображения исчезает)

ИЗОБРАЖЕНИЕ

ИЗОБРАЖЕНИЕ

ИЗОБРАЖЕНИЕ

(нижняя часть изображения)

Как бы я совершил sh это?

Ответы [ 2 ]

3 голосов
/ 25 января 2020

Во-первых, имейте в виду, что вокруг SF Symbols существуют правила использования. Это может или не может быть изменено таким образом. В частности, есть список «как есть» символов , которые нельзя использовать для произвольных целей. Но это ничего не меняет в ответе.

Второе, на что следует обратить внимание, это то, что символы SF - странный зверь между текстом и изображениями. Они часто действуют как текст, и они часто рисуют вне рамок . Это создает проблемы. Вы можете исправить это, заставив их быть реальными изображениями, как описано в связанном ответе.

let config = UIImage.SymbolConfiguration(scale: .large)
let image = Image(uiImage: UIImage(systemName:"star.fill", withConfiguration: config)!)

В конце концов, до тех пор, пока вы можете получить Image с правильным кадром, остальное будет работать. Неважно, что это символ SF.

Ответ Аспери объясняет, как это исправить, используя resizable.

let image = Image(systemName: "star.fill").resizable().aspectRatio(contentMode: .fit)

(я добавил aspectRatio так что это не искажает.)

Сначала определите свой градиент. Так будет работать затухание, и вы можете настроить его с помощью набора цветов или отдельных цветовых остановок. Единственное, что здесь имеет значение, это непрозрачность.

let fade =  Gradient(colors: [Color.clear, Color.black])

(см. Ответ Аспери для примера использования стопов, которые дают вам больше контроля над затуханием.)

С этим вы можете примените этот градиент как маску:

let fade =  Gradient(colors: [Color.clear, Color.black])
let image = Image(systemName: "star.fill")
    .resizable().aspectRatio(contentMode: .fit).frame(height: 48)

struct ContentView: View {
    var body: some View {
        VStack {
            image
                .mask(LinearGradient(gradient: fade, startPoint: .top, endPoint: .bottom))
            image
            image
                .mask(LinearGradient(gradient: fade, startPoint: .bottom, endPoint: .top))
        }
    }
}

Это вызывает проблемы с размером. Этот подход представляет собой гибкий стек. Он будет расти, чтобы заполнить любой контейнер, в который он вставлен. Возможно, вы захотите ограничить его несколькими способами.

Во-первых, вы можете определить высоту всего стека, поместив в него рамку:

    VStack {
        image
            .mask(LinearGradient(gradient: fade, startPoint: .top, endPoint: .bottom))
        image
        image
            .mask(LinearGradient(gradient: fade, startPoint: .bottom, endPoint: .top))
    }.frame(height: 128)
     ^^^^^^^^^^^^^^^^^^^

Или вместо этого вы можете установить размер каждого изображения:

let image = Image(systemName: "star.fill")
    .resizable().aspectRatio(contentMode: .fit).frame(width: 48)
                                               ^^^^^^^^^^^^^^^^^

Three symbols with fading at top and bottom

1 голос
/ 25 января 2020

Вот мой альтернативный вариант (без использования UIKit)

enter image description here

struct TestSFSymbolsFade: View {
    var body: some View {
        VStack {
            Image(systemName: "ant.fill").resizable()
            Image(systemName: "ant.fill").resizable()
            Image(systemName: "ant.fill").resizable()
        }
        .mask(LinearGradient(gradient: Gradient(stops: [
            .init(color: .clear, location: 0),
            .init(color: .black, location: 0.25),
            .init(color: .black, location: 0.75),
            .init(color: .clear, location: 1)
        ]), startPoint: .top, endPoint: .bottom))
        .frame(width: 40, height: 160) // < just for demo, can be any or absent
    }
}
...