显示在其他视图中选择的文本(标签)

Displaying Text (Tags) That Was Selected In Another View

提问人:Reflex8 提问时间:8/13/2023 最后编辑:Reflex8 更新时间:8/13/2023 访问量:64

问:

`背景我正在创建一个应用程序,用户可以在其中创建报价,创建报价过程的一部分是,他们可以选择一个标签来适合引用他们,所以如果这是一个快乐的报价,用户可以选择一个快乐标签。我对 SwiftUI 也很陌生,所以请理解我的代码是否不是最好的,如果它没有得到最好的解释,但请随时问我更多问题,以及我是否需要提供我的整个 Xcode 项目以便更好地理解 - 请告诉:)

标记 UI我正在使用一个包,它基本上将您提供的文本样式设置为看起来像标签 - 它还允许用户选择标签(这对我的问题很重要)。标记实现是 GitHub 中的代码 - https://github.com/HappyIosDeveloper/SwiftUI-TagView

设置我有 2 个视图(我有更多的视图,但我相信它们对问题并不重要)- AddQuoteView 和 TagSelectionView。 在 AddQuoteView 上,用户可以创建带有引号(文本)、作者等的引号,他们还能够选择适合引号的标签,当他们单击加号按钮添加标签时,他们会看到 TagSelectionView(在半张纸中显示为视图 - 感谢这个 SwiftUI 包 - https://github.com/franklynw/HalfASheet. 在 TagSelectionView 上,用户最多可以选择 3 个标签(根据需要选择和取消选择它们)。(此 TagSelectionView 由 TagView 支持,该 TagView 可设置样式、创建选择它们等功能)一旦用户对他们的标记选择感到满意,他们就可以按下 TagSelectionView 上的按钮,将其关闭/退出该视图并返回到 AddQuoteView。 我还将其设置为一个 Firebase,用于存储用户创建的引号。

问题我希望向用户显示他们在 AddQuoteView 的 TagSelectionView 中选择的标记,但不会显示这些标记。

下面显示的代码是我认为对此问题相当重要的代码

**AddQuoteView code:**

@State private var tagsIsSelected = true
@State private var showingTagSelectionView = false

VStack{
HStack{
        Image(systemName: "tag.fill")
            .scaleEffect(x: -1, y: 1)
        Text("Label")

        Spacer()
                                Button {
            showingTagSelectionView.toggle()
        } label: {
                                    HStack{
                Image(systemName: "plus")

                if tagsIsSelected == false {
                    Text("Add Tag")
                        .bold()
                }
            }
                                    .foregroundColor(.white)
                .padding()
                .background(Color.blue)
                .frame(height: 36)
                .cornerRadius(18)
                .overlay(Capsule().stroke(Color.blue, lineWidth: 1))
        }
                                .buttonStyle(PlainButtonStyle())


    }
}
HalfASheet(isPresented: $showingTagSelectionView, title: "Tags (3 per quote)") {
    TagSelectionView()
}
            .height(.proportional(0.58))


    **TagSelectionView code**

        ScrollView{
    TagView(tags: [
        TagViewItem(title: "🤗 Acceptance", isSelected: false), TagViewItem(title: "🌲 Adventure", isSelected: false)
        //More tags (but just not shown here)
    ])
}
        .offset(x: 0, y: 40)
    }


**TagView code - styles and creates abilities for the tags**

import SwiftUI

struct TagViewItem: Hashable {
    var title: String
    var isSelected: Bool
    
    static func == (lhs: TagViewItem, rhs: TagViewItem) -> Bool {
        return lhs.isSelected == rhs.isSelected
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(title)
        hasher.combine(isSelected)
    }
}

struct TagView: View {
    @State var tags: [TagViewItem]
    @State private var totalHeight = CGFloat.zero

    var body: some View {
        VStack {
            GeometryReader { geometry in
                self.generateContent(in: geometry)
}
        }
        .frame(height: totalHeight)
    }

    private func generateContent(in g: GeometryProxy) -> some View {
    var width = CGFloat.zero
    var height = CGFloat.zero
    var selectedTagCount = tags.filter { $0.isSelected }.count // Track the number of selected tags
    return ZStack(alignment: .topLeading) {
        ForEach(tags.indices) {
            index in
                item(for: tags[index].title, isSelected: tags[index].isSelected)
                    .padding([.horizontal, .vertical], 4)
                .alignmentGuide(.leading, computeValue: {
                    d in
                        if(abs(width - d.width) > g.size.width) {
                width = 0
                height -= d.height
            }
            let result = width
            if tags[index].title == self.tags.last!.title {
                width = 0
            } else {
                width -= d.width
            }
            return result
        })
                    .alignmentGuide(.top, computeValue: {
            d in
                        let result = height
                        if tags[index].title == self.tags.last!.title {
            height = 0
        }
                        return result
    })
                    .onTapGesture {
        if selectedTagCount < 3 || tags[index].isSelected == true {
            tags[index].isSelected.toggle()
            selectedTagCount += tags[index].isSelected ? 1 : -1
        }
    }
}
        }.background(viewHeightReader($totalHeight))
    }

    private func item(for text: String, isSelected: Bool) -> some View {
    Text(text)
        .bold()
        .foregroundColor(isSelected ? Color(#colorLiteral(red: 0.1340637264, green: 0.6421895015, blue: 0.7360979563, alpha: 1)) : Color.white)
        .padding()
        .lineLimit(1)
        .background(isSelected ? Color(#colorLiteral(red: 0, green: 0.301058143, blue: 0.5746451229, alpha: 1)) : Color(#colorLiteral(red: 0.2903293967, green: 0.2863105237, blue: 0.2821627259, alpha: 1)))
        .frame(height: 36)
        .cornerRadius(18)
}

    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
    }
}
}

我尝试简单地将用户选择的标记放入数组中,然后使用 ForEach 将该数组生成到 AddQuoteView 中,但它们仍然没有显示。

swift firebase firebase-realtime-database swiftui

评论

0赞 workingdog support Ukraine 8/13/2023
从您的问题描述来看,您似乎希望将所选标签从一个视图传递到另一个视图。因此,请查看此链接,它为您提供了一些很好的示例,说明如何管理应用程序中的数据监控数据以及将数据从一个视图传递到另一个视图的方法。如果您以 ios17 为目标平台,请参阅在应用中管理模型数据

答: 暂无答案