我有以下代碼:
import SwiftUI
struct EntryHeaderIconView: View {
private let backgroundSize: Double = 88
private let color: Color
private let initials: String
init(color: Color,
initials: String = "") {
self.color = color
self.initials = initials
}
var body: some View {
ZStack(alignment: .center) {
Circle()
// .frame(width: backgroundSize,
// height: backgroundSize)
// Uncommenting this fixes the issue, but the text now clips
.foregroundColor(color)
icon
}
}
@ViewBuilder
private var icon: some View {
Text(verbatim: initials)
.font(.system(size: 48, weight: .bold, design: .rounded))
.foregroundColor(.white)
.accessibilityIdentifier("entry_header_initials")
}
}
struct ContentView: View {
var body: some View {
VStack {
EntryHeaderIconView(color: .red,
initials: "RT")
EntryHeaderIconView(color: .green,
initials: "LV")
EntryHeaderIconView(color: .red,
initials: "中國")
Spacer()
}
}
}
我的目標是讓Circle元素完全適合Text元素。但是,它要么在 中繼續增長VStack,因此它占據盡可能多的空間,看起來像這樣(尺寸線被注釋掉):

或者,如果我將固定大小設定為Circle,則內容會被剪裁:
var body: some View {
ZStack(alignment: .center) {
Circle()
.frame(width: backgroundSize,
height: backgroundSize)
// Uncommenting this fixes the issue, but the text now clips
.foregroundColor(color)
icon
}
}

我的目標是使Circle大小取決于Text大小,以便它與它一起增長(或縮小)。
使用 AutoLayout 很容易制作,如何使用 SwiftUI 來實作?
uj5u.com熱心網友回復:
AZStack占用其子視圖所需的空間。您沒有為 提供明確frame的Circle,那么 SwiftUI 怎么知道Circle的大小應該與 的大小匹配icon?
相反,您應該在將Circle一些應用于.backgroundiconpaddingicon
struct EntryHeaderIconView: View {
private let color: Color
private let initials: String
init(color: Color,
initials: String = "") {
self.color = color
self.initials = initials
}
var body: some View {
icon
.padding(.all, 30)
.background(background)
}
private var background: some View {
Circle()
.foregroundColor(color)
}
private var icon: some View {
Text(verbatim: initials)
.font(.system(size: 48, weight: .bold, design: .rounded))
.foregroundColor(.white)
.accessibilityIdentifier("entry_header_initials")
}
}
struct EntryHeaderIconView_Preview: PreviewProvider {
static var previews: some View {
VStack {
EntryHeaderIconView(color: .red,
initials: "RT")
EntryHeaderIconView(color: .green,
initials: "LV")
EntryHeaderIconView(color: .red,
initials: "中國")
}
}
}
uj5u.com熱心網友回復:
您需要對文本應用填充,然后以圓形顯示背景。
以下是實作這一目標的方法:
struct Example: View {
var body: some View {
VStack {
Text("1")
.font(.footnote)
.foregroundColor(.white)
.padding(5)
.background(.red)
.clipShape(Circle())
Text("2")
.font(.headline)
.foregroundColor(.white)
.padding(5)
.background(.red)
.clipShape(Circle())
Text("3")
.font(.largeTitle)
.foregroundColor(.white)
.padding(5)
.background(.red)
.clipShape(Circle())
}
}
}

uj5u.com熱心網友回復:
我將發布此內容,因為它與其他兩個答案不同,它們更簡單且有效。這在處理不同尺寸時更加靈活,但仍然使它們看起來一致。這使用 PreferenceKey 來讀取首字母的大小,并將圓圈限制為特定大小。
struct EntryHeaderIconView: View {
@State var backgroundSize = CGFloat.zero
// This gives a consistent additional size of the circle around the intitials
let circleSizeMultiplier = 1.5
private let color: Color
private let initials: String
init(color: Color,
initials: String = "") {
self.color = color
self.initials = initials
}
var body: some View {
ZStack(alignment: .center) {
Circle()
// The frame is sized at the circleSizeMultiplier times the
// largest dimension of the initials.
.frame(width: backgroundSize * circleSizeMultiplier,
height: backgroundSize * circleSizeMultiplier)
.foregroundColor(color)
icon
// This reads the size of the initials
.background(GeometryReader { geometry in
Color.clear.preference(
key: SizePreferenceKey.self,
value: geometry.size
)
})
}
// this sets backgroundSize to be the max value of the width or height
.onPreferenceChange(SizePreferenceKey.self) {
backgroundSize = max($0.width, $0.height)
}
}
@ViewBuilder
private var icon: some View {
Text(verbatim: initials)
.font(.system(size: 48, weight: .bold, design: .rounded))
.foregroundColor(.white)
.accessibilityIdentifier("entry_header_initials")
}
}
// This is the actual preferenceKey that makes it work.
fileprivate struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/449306.html
