HStack с символами SF Изображение не выровнено по центру

У меня есть этот простой код SwiftUI. Я хочу, чтобы все символы были выровнены по центру, как символ облака.

struct ContentView : View {
var body: some View {
    HStack(alignment: .center, spacing: 10.0) {
        Image(systemName: "cloud.sun")
        Image(systemName: "cloud")
        Image(systemName: "cloud.bolt")
        Text("Text")
        }.font(.title)
    }
}

Но, как вы можете видеть ниже, первый и последний символ не центрированы. Я что-то упустил, или это ошибка?

https://i.st ack.imgur.com/YFPm9.png

Ура!

2 ответа

Решение

Это то, что происходит.

Image просмотры не меняются.

Похоже, что они не знают о своем собственном размере контента, или, возможно, он сообщает неправильное значение.

Чтобы это исправить:

struct ContentView : View {
    var body: some View {
        HStack(alignment: .center, spacing: 10.0) {
            Image(systemName: "cloud.sun")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .background(Color.red)
            Image(systemName: "cloud")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .background(Color.yellow)
            Image(systemName: "cloud.bolt")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .background(Color.pink)
            Text("Text").background(Color.green)
        }
        .frame(width: 250, height: 50)
        .background(Color.gray)
        .font(.title)

    }
}

...сделать Images изменить размер, а также убедиться, что соотношение сторон установлено на .fit или они растянутся.

Установите также рамку на HStack или он расширится, чтобы заполнить весь экран.

@MartinR предложил еще лучшее решение - создание изображений с помощью UIImage - см. его комментарий ниже.

struct ContentView : View {

    var body: some View {
        HStack {
            Image(uiImage: UIImage(systemName: "cloud.sun")!)
                .background(Color.red)
            Image(uiImage: UIImage(systemName: "cloud")!)
                .background(Color.yellow)
            Image(uiImage: UIImage(systemName: "cloud.bolt")!)
                .background(Color.pink)
            Text("Text").background(Color.green)
        }
        .background(Color.gray)
        .font(.title)

    }

}

Выход:

Я столкнулся с той же проблемой, что и вы: символы SF не сообщают правильный размер содержимого в iOS 13. (Хотя это исправлено в iOS 14 и выше).

Проблема с использованием решения, предложенного в решении Маттео Пачиниса, заключается в плохой совместимости с динамикой SwiftUI: цвет переднего плана и размер шрифта (и динамический тип!) Не просто берутся из текущего контекста SwiftUI, а должны дублироваться в UIImage конфигурация (с использованием UIImage(systemName:, withConfiguration:)), что часто непрактично. (см. hackingwithswift.com, чтобы узнать, как это использовать).

Глядя на проблему выше, я предлагаю следующее решение:

      HStack(alignment: .center, spacing: 10.0) {
    Image(systemName: "cloud.sun")
        .hidden()
        .overlay(
            Image(systemName: "cloud.sun")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .background(Color.red)
        )
    Image(systemName: "cloud")
        .hidden()
        .overlay(
            Image(systemName: "cloud")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .background(Color.yellow)
        )
    Image(systemName: "cloud.bolt")
        .hidden()
        .overlay(
            Image(systemName: "cloud.bolt")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .background(Color.pink)
        )
    Text("Text")
        .background(Color.green)
}
.background(Color.gray)
.font(.title)

Похоже, много дублирования кода, но у него есть то преимущество, что символы масштабируются в соответствии с вашим fontуважать foregroundColor модификатор и выровняйте по желанию alignment

Выход:

Но с этим подходом все еще есть некоторая проблема: изображение по-прежнему не имеет правильного внутреннего размера, символы просто нарисованы «красиво по центру». Это означает, что высота HStack все еще зависит от высоты Textэлемент. Если вы просто хотите нарисовать символы в .largeTitle шрифт и текст в .body font, результат будет выглядеть так, как показано ниже, возможно, вызывая перекрытие с соседними представлениями:

Я все еще буду исследовать дальше, чтобы найти решение, обеспечивающее правильный размер представления, так как это меня действительно раздражает.

Другие вопросы по тегам