dankell
dankell

Reputation: 81

SwiftUI: Modifier inside Array

I'm currently trying to put all possible modifiers directly into an array and then call them via forEach. It works with most of them too, unfortunately with frame (height, width, alignmet) not as I would like. Text and frame should align at the same time. But no matter how I try, it doesn't work. In addition, I also fail to integrate .bold and .italic in this way. I am aware that there are other ways. If it is possible in any way, I would like to be able to include all modifiers in this way. Is that even possible?

import SwiftUI

struct Tests: Identifiable {
    var id: Int
    var text: String
    var textcolor: Color
    var textfont: Font
    var height: CGFloat
    var width: CGFloat
    var alignment: Alignment
    var textbackcolor: Color
    var corner: CGFloat
    var show: Bool
    var user: String
}

struct ContentView: View {

    @State private var testvar = [
        Tests(id: 000, text: "Hello World 1", textcolor: .red, textfont: .title, height: 100, width: 300, alignment: .trailing, textbackcolor: .blue, corner: 20, show: true, user: "System"),
        Tests(id: 001, text: "Hello World 2", textcolor: .green,  textfont: .largeTitle, height: 100, width: 300, alignment: .center, textbackcolor: .black, corner: 50, show: true, user: "George"),
       ]

    var body: some View {
        NavigationView {
            VStack {

                    ForEach(self.testvar) { txt in if txt.show == true {
                        Text("\(txt.text)")
                            .frame(width: txt.width, height: txt.height, alignment: txt.alignment)
                            .font(txt.textfont)
                            .foregroundColor(txt.textcolor)
                            .background(txt.textbackcolor)
                            .cornerRadius(txt.corner)
                        //.bold?
                        //.italic?
                        } }
               }
        }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Upvotes: 1

Views: 923

Answers (1)

user3441734
user3441734

Reputation: 17544

Changing the order of modifiers (italic or bold must have to be applied on Text only)

ForEach(self.testvar) { txt in if txt.show == true {
    Text("\(txt.text)")
        .bold()
        .italic()
        .frame(width: txt.width, height: txt.height, alignment: txt.alignment)
        .font(txt.textfont)
        .foregroundColor(txt.textcolor)
        .background(txt.textbackcolor)
        .cornerRadius(txt.corner)
    }
}

on data

@State private var testvar = [
        Tests(id: 000, text: "Hello World 1", textcolor: .red, textfont: .title, height: 100, width: 300, alignment: .trailing, textbackcolor: Color(.blue).opacity(0.2), corner: 20, show: true, user: "System"),
        Tests(id: 001, text: "Hello World 2", textcolor: .green,  textfont: .largeTitle, height: 300, width: 300, alignment: .center, textbackcolor: .black, corner: 50, show: true, user: "George"),
       ]

I've got enter image description here

If you are wondering why .largeTitle is not italic, please see How to apply .italic() to .largeTitle Font?

UPDATE to reflect discussion

to be able to modify the style based on values in your array, use simple Text extension

extension Text {
    func style(bold: Bool = false, italic: Bool = false) -> Self {
        var s = self
        if bold {
            s = s.bold()
        }
        if italic {
            s = s.italic()
        }
        return s
    }
}

which is (I hope so) self-explanatory

enter image description here

Upvotes: 3

Related Questions