Swiftui 使用ViewBuilder时,内容包装未对齐的HStack

Swiftui 使用ViewBuilder时,内容包装未对齐的HStack,swiftui,swiftui-navigationlink,Swiftui,Swiftui Navigationlink,我从中获得了以下代码,并尝试在方法func text(for word:String)->some View中使用ViewBuilder,以便将一些HStack文本内容包装到NavigationLink中 问题是,一旦我这样做,计算的对齐就会被破坏 如果从命名方法中删除@ViewBuilderanotion,则内容将正确对齐 我怎样才能解决这个问题 public struct HStackTextWrapping: View { private let words:

我从中获得了以下代码,并尝试在方法
func text(for word:String)->some View中使用
ViewBuilder
,以便将一些HStack文本内容包装到
NavigationLink

问题是,一旦我这样做,计算的对齐就会被破坏

如果从命名方法中删除
@ViewBuilder
anotion,则内容将正确对齐

我怎样才能解决这个问题

public struct HStackTextWrapping: View {
    
    
    private let words: [String]
    private let parentView: ParentView
    private let textModifiers: (Text) -> Text
    
    @State private var totalHeight: CGFloat
    
    public init(_ string: String,
         in parentView: ParentView,
         @ViewBuilder textModifiers: @escaping (Text) -> Text = { $0 })
    {
        self.words = string.components(separatedBy: .whitespaces)
        self.parentView = parentView
        self.textModifiers = textModifiers
        
        switch parentView {
        case .scrollview:
            totalHeight = .zero
        case .vstack:
            totalHeight = .infinity
        }
    }
    
    public var body: some View {
        VStack {
            GeometryReader { geometry in
                self.generateContent(in: geometry)
            }
        }
        .ifCondition(self.parentView == .scrollview) {
            $0.frame(height: totalHeight)
        }
        .ifCondition(self.parentView == .vstack) {
            $0.frame(maxHeight: totalHeight)
        }
    }
    
    private func generateContent(in g: GeometryProxy) -> some View {
        var width: CGFloat = .zero
        var height: CGFloat = .zero
        
        return ZStack(alignment: .topLeading) {
            ForEach(self.words, id: \.self) { word in
                self.text(for: word)
                    .padding(0)
                    .alignmentGuide(.leading) { d in
                        if abs(width - d.width) > g.size.width {
                            width = 0
                            height -= d.height
                        }
                        let result = width
                        if word == self.words.last {
                            width = 0
                        } else {
                            width -= d.width
                        }
                        print("(\(result), ")
                        return result
                    }
                    .alignmentGuide(.top) { d in
                        let result = height
                        if word == self.words.last {
                            height = 0
                        }
                        print("\(result)) " + word)
                        return result
                    }
            }
        }
        .background(viewHeightReader($totalHeight))
        
    }
    
    @ViewBuilder
    private func text(for word: String) -> some View {
        let potentialWhitespace = word == self.words.last ? "" : " "
        let text = self.textModifiers(Text(word + potentialWhitespace))
        
        if word.first == "@" {
            NavigationLink(destination: AnyView(ProfileView(username: String(word.dropFirst()))), label: { text })
                .foregroundColor(ColorPalette.primary.color)
        }
        else if word.first == "#" {
            NavigationLink(destination: AnyView(Text(word)), label: { text })
                .foregroundColor(ColorPalette.primary.color)
        }
        else {
            text
        }
    }
    
    private func viewHeightReader(_ binding: Binding<CGFloat>) -> some View {
        return GeometryReader { geometry -> Color in
            let rect = geometry.frame(in: .local)
            DispatchQueue.main.async {
                binding.wrappedValue  = rect.size.height
            }
            return .clear
        }
    }
    
    private func resolveTags(in text: String) {
        
    }
}

public enum ParentView {
    case scrollview
    case vstack
}
public struct HStackTextWrapping:视图{
private let words:[字符串]
private let parentView:parentView
私有let Text修饰符:(Text)->Text
@国有私有var总高度:CGFloat
public init(uString:string,
在parentView:parentView中,
@ViewBuilder文本修饰符:@escaping(Text)->Text={$0})
{
self.words=string.components(分隔符:。空格)
self.parentView=parentView
self.textModifiers=textModifiers
切换父视图{
案例.滚动视图:
总高度=.0
案例.vstack:
总高度=.无穷大
}
}
公共机构:一些看法{
VStack{
GeometryReader{中的几何体
自生成内容(在:几何中)
}
}
.ifCondition(self.parentView==.scrollview){
$0.帧(高度:总高度)
}
.ifCondition(self.parentView==.vstack){
$0.帧(最大高度:总高度)
}
}
private func generateContent(在g:GeometryProxy中)->一些视图{
变量宽度:CGFloat=.0
变量高度:CGFloat=.0
返回ZStack(对齐:。顶部引导){
ForEach(self.words,id:\.self){word in
self.text(用于:word)
.填充(0)
.alignmentGuide(.leading){d in
如果abs(宽度-d.width)>g.size.width{
宽度=0
高度-=d.高度
}
让结果=宽度
如果word==self.words.last{
宽度=0
}否则{
宽度-=d.宽度
}
打印(“(\(结果)”)
返回结果
}
.alignmentGuide(.top){d英寸
让结果=高度
如果word==self.words.last{
高度=0
}
打印(“\(结果))”+字)
返回结果
}
}
}
.背景(viewHeightReader($totalHeight))
}
@视图生成器
私有func文本(用于单词:字符串)->某些视图{
让potentialWhitespace=word==self.words.last?”:“”
让text=self.textModifiers(text(word+potentialWhitespace))
如果word.first==“@”{
导航链接(目标:AnyView(ProfileView(用户名:String(word.dropFirst()))),标签:{text})
.foregroundColor(调色板.primary.color)
}
如果word.first==“#”{
NavigationLink(目标:AnyView(文本(word)),标签:{Text})
.foregroundColor(调色板.primary.color)
}
否则{
文本
}
}
private func viewHeightReader(u-binding:binding)->一些视图{
返回GeometryReader{geometry->Color in
设rect=geometry.frame(in:.local)
DispatchQueue.main.async{
binding.wrappedValue=rect.size.height
}
返回,完毕
}
}
专用func resolveTags(文本:字符串){
}
}
公共枚举父视图{
案例滚动视图
案例vstack
}