Как сделать рамку максимально определенной ширины и всегда как можно короче? - PullRequest
1 голос
/ 23 апреля 2020

Я пытаюсь создать компонент, который получает имя и отображает его внутри фрейма. Я хочу, чтобы эта рамка имела наименьшую ширину, насколько это возможно, с учетом отступов и избежания разрыва строки. Ограничение ширины составляет 90: после этого строка текста должна быть разбита. Я пытался использовать атрибут maxWidth модификатора frame, но мой кадр получает фиксированное значение 90 в качестве ширины. Вот фрагмент кода компонента:

import SwiftUI

struct ContentView: View {
    var name: String

    var body: some View {
        Text(name)
            .font(.system(size: 12))
            .background(Color.red)
            .padding(.horizontal, 7)
            .padding(.vertical, 5)
            .background(Color.yellow)
            .frame(minWidth: 0, maxWidth: 90)
            .background(Color.green)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ContentView(name: "This is a very long name")
                .previewDisplayName("Long name")
            ContentView(name: "Hi")
                .previewDisplayName("Short name")
        }
        .previewLayout(.sizeThatFits)
    }
}

Предварительный просмотр выглядит следующим образом:

Я также пытался использовать minWidth и idealWidth атрибуты, но результат всегда одинаков. Как я могу сделать, чтобы ширина принимала 90 как предел вместо фиксированного значения?

Ответы [ 2 ]

0 голосов
/ 23 апреля 2020

На самом деле fixedSize по одной оси должно работать, но по какой-то причине это не так, поэтому предлагается ниже только решение во время выполнения (не для stati c Preview), ie. рассчитать лимит вручную и применить к следующему refre sh (чтобы избежать зацикливания).

demo

struct DemoTightingText: View {
    var name: String
    @State private var maxWidth: CGFloat = 90
    var body: some View {
        VStack {
            Text(name)
                .font(.system(size: 12))
                .background(Color.red)
                .padding(.horizontal, 7)
                .padding(.vertical, 5)
                .background(Color.yellow)
                .background(GeometryReader {gp -> Color in
                        DispatchQueue.main.async {
                            // update on next cycle with calculated width !!!
                            self.maxWidth = min(gp.size.width, 90)
                        }
                        return Color.clear
                    })
        }
        .frame(maxWidth: maxWidth)
        .background(Color.green)
//      .fixedSize(horizontal: true, vertical: false) // this must be work, but don't
    }
}
0 голосов
/ 23 апреля 2020

Я не совсем уверен, что это именно то, что вам нужно, но если вы переместите модификатор frame (minWidth: 0, maxWidth: 90), чтобы сделать его последним, тогда все представления в начале цепочки модификаторов будут иметь размер это меньше или равно maxWidth. Любой модификатор, находящийся позже в цепочке, чем модификатор кадра, не будет меняться по размеру.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...