Home > Back-end >  Is it possible to make SwiftUI List item text selectively bold for FAQ section?
Is it possible to make SwiftUI List item text selectively bold for FAQ section?

Time:06-26

I have a SwiftUI expandable FAQ view with Question text that I want bold and Answer text that I want to leave as non-bold text.

I am only able to make either BOTH bold OR both regular weight but want to know if it is possible to selective make the question text bold only??

Below is my code and screen-shot of what I have so far.

enter image description here

FAQ VIEW

struct FAQ: View {
   
    let questionItems : [QuestionAnswer] = [ qa1(), qa2(), qa3() ]
    
    var body: some View {
        VStack {
            List(questionItems, children: \.textTwo) { item in
                Text(item.textOne)
                     //.bold() makes BOTH bold or regular without
                     .padding([.top, .bottom], 15)
            }
            .foregroundColor(.black)
            .clipped()
        }
        .navigationBarTitle("Frequently asked questions", displayMode: .inline)
        .navigationBarBackButtonHidden(true)
    }
}

func qa1() -> QuestionAnswer {
    return .init(textOne: "Question one", textTwo: [.init(textOne: "Answer one")])
}

func qa2() -> QuestionAnswer {
    return .init(textOne: "Question two", textTwo: [.init(textOne: "Answer two")])
}

func qa3() -> QuestionAnswer {
    return .init(textOne: "Question three", textTwo: [.init(textOne: "Answer three")])
}

DATA MODEL

struct QuestionAnswer: Identifiable {
    let id = UUID()
    let textOne: String
    var textTwo: [QuestionAnswer]?
}

CodePudding user response:

You could check if a row has any children to decide whether to bold the text or not.

List(questionItems, children: \.textTwo) { item in
    if item.hasChildren {
        Text(item.textOne)
            .bold()
            .padding([.top, .bottom], 15)
    } else {
        Text(item.textOne)
            .padding([.top, .bottom], 15)
    }
}

extension QuestionAnswer {
    var hasChildren: Bool { textTwo?.isEmpty == true }
}

Or with suggested approach from the comments

List(questionItems, children: \.textTwo) { item in
    Text(item.hasChildren ? "**\(item.textOne)**" : item.textOne )
        .padding([.top, .bottom], 15)
}

CodePudding user response:

You could use this trick from the docs here: enter image description here

CodePudding user response:

you may use attributed string .

extension Text {
    init(_ string: String, configure: ((inout AttributedString) -> Void)) {
        var attributedString = AttributedString(string) 
        configure(&attributedString) 
        self.init(attributedString) // Text initialization
    }
}

Usage:

Text("Your Text") { string in
            string.foregroundColor = .Color
            if let range = string.range(of: "Attributed") { 
                string[range].foregroundColor = .YourColor // Use Your Style
            }
        }

Use anywhere you need . for your current problem use attributed string on your list . and you may design as you can .

  • Related