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, результат будет выглядеть так, как показано ниже, возможно, вызывая перекрытие с соседними представлениями:
Я все еще буду исследовать дальше, чтобы найти решение, обеспечивающее правильный размер представления, так как это меня действительно раздражает.