Começo com o seguinte código:
import SwiftUI
struct ContentView: View {
var body: some View {
HStack(spacing: 20) {
ExtractedView(text: "Energy")
ExtractedView(text: "Breath Control")
}
.padding(.horizontal, 20)
}
}
#Preview {
ContentView()
}
struct ExtractedView: View {
let text: String
var body: some View {
Button {
} label: {
HStack(spacing: 8) {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text(text)
.lineLimit(1)
.font(.system(size: 18, weight: .bold))
}
.padding(.horizontal, 8)
.padding(.vertical, 8)
.background {
Color.yellow
}
}
}
}
O resultado aproximado que quero alcançar:
Em outras palavras, preciso adicionar espaçamento igual dentro de cada elemento após o texto, mas não sei como fazer isso. Tentei um código diferente, mas o tamanho do botão se torna igual ou o iOS adiciona uma nova linha ao segundo rótulo ou tenta encurtar o segundo rótulo mesmo quando há espaço suficiente.
Uma maneira de resolver é usar um personalizado
Layout
:Aqui está um exemplo de implementação que funciona desta maneira:
Também é necessária uma alteração em
ExtractedView
, para que ele se expanda e preencha a largura disponível antes que o fundo amarelo seja adicionado:Para usar, basta substituir o
HStack
no seu código original porPaddedToFill
:Na sua captura de tela do resultado aproximado, o padding extra sempre estava no lado final de cada botão. Para atingir esse resultado, basta adicionar um
alignment
parâmetro ao definir omaxWidth
inExtractedView
:O EDIT
Layout
foi introduzido no iOS 16. Se você ainda precisa dar suporte ao iOS 15, precisará de uma solução de fallback para esta versão. Uma maneira seria medir o tamanho do contêiner usando umGeometryReader
, então compartilhar a largura excedente entre os botões.Aqui está um exemplo de como isso pode ser resolvido dessa forma. A maneira mais fácil de preencher os botões é permitir que o tamanho do preenchimento extra seja passado como um parâmetro para
ExtractedView
:O tamanho do acolchoamento extra é calculado da mesma forma que o costume
Layout
, com base no tamanho ideal do contêiner.HStack
ao fundo e usando umGeometryReader
para medir seu tamanho.HStack
com outroGeometryReader
.EDIT 2 O costume
Layout
fica mais complicado se os rótulos de texto devem ser quebrados quando não couberem em uma linha. Você pode tentar estas mudanças:.lineLimit
emExtractedView
:sizeThatFits
para solicitar o dobro da altura se a largura proposta for menor que a largura ideal:Esta é uma aproximação bastante grosseira da altura que será realmente necessária e permite que o texto seja quebrado em apenas uma linha adicional. Uma implementação mais rigorosa precisaria chamar as subvisualizações com uma proposta de largura reduzida, computada exatamente como está sendo feita em
placeSubviews
.placeSubviews