Home > Mobile >  Type '()' cannot conform to 'View'
Type '()' cannot conform to 'View'

Time:10-05

Sorry Im still new to SwiftUI and Im struggling with outputing random String inside the View. Due to the error "Type '()' cannot conform to 'View" ive got, I learnt that View isnt the appropriate place to write down the functions itself. What should I do to output itemX.randomElement() and itemY.randomElement(). Any help is appreciated thx.

struct SummaryView: View {
    var avgValue = 1.5
    var roundedKarvonenValue: Double
    var itemX = ["A", "B", "C", "D", "E", "F", "G", "H"]
    var itemY = ["I", "J", "K", "L", "M", "N", "O", "P"]

    var body: some View {
            ScrollView {
                VStack(alignment: .leading) {
                    if workoutManager.averageHeartRate < roundedKarvonenValue{
                        print(itemX.randomElement()!)
                    }else{
                        print(itemY.randomElement()!)
                    }

CodePudding user response:

There is a great deal to unpack in this question, but we will start with the simple first. Views are for displaying something on screen. Nothing more. The reason you are having issues with the print() statements is that they are for printing to the console, not the screen. Therefore, the compiler gives you an error. To fix this, use Text like @JoakimDanielson said:

struct SummaryView: View {
    var workoutManager: WorkoutManager //This var must be declared
    
    var avgValue = 1.5
    var roundedKarvonenValue: Double
    var itemX = ["A", "B", "C", "D", "E", "F", "G", "H"]
    var itemY = ["I", "J", "K", "L", "M", "N", "O", "P"]
    
    var body: some View {
        ScrollView {
            VStack(alignment: .leading) {
                if workoutManager.averageHeartRate < roundedKarvonenValue{
                    Text(itemX[0])
                } else {
                    Text(itemY[0])
                }
            }
        }
    }
}

As to your second part as to where to place your functions, is not as clear cut. You should look up MVVM architecture to gain an understanding if the standard way to structure your app in SwiftUI. Right now, you are simply displaying data from HealthKit using Apple's WWDC class WorkoutManager(I presume).

At the very basic level, if your function has to do with changing how the data is displayed, it stays in the View. If the function fundamentally changes something about your Model or is needed by multiple views, it should go into the Model. That is a judgment call.

So, for your code, you are showing a random element from a variable declared in a view. That is all local stuff, so the function stays in the view. Adding the func randomElement() and cleaning your code up a bit more leaves you with this:

struct SummaryView: View {
    // If you are not changing the variables, declare them as constants. This uses less memory.
    let workoutManager: WorkoutManager
    let avgValue = 1.5
    let roundedKarvonenValue: Double
    let itemX = ["A", "B", "C", "D", "E", "F", "G", "H"]
    let itemY = ["I", "J", "K", "L", "M", "N", "O", "P"]
    
    var body: some View {
        ScrollView {
            VStack(alignment: .leading) {
                // I turned your if statement into a Terniary Conditional Operator to shrink the amount of code.
                Text(workoutManager.averageHeartRate < roundedKarvonenValue ? randomElement(itemX) : randomElement(itemY))
            }
        }
    }
                     
    func randomElement(_ stringArray: [String]) -> String {
        let end = stringArray.count - 1
        let index = Int.random(in: 0...end)
        return stringArray[index]
    }
}

I was obviously not able to test this as you didn't supply enough of your code. Please see How to create a Minimal, Reproducible Example.

CodePudding user response:

You can use print statements inside views like this:

     if workoutManager.averageHeartRate < roundedKarvonenValue{
       let _ = print(itemX.randomElement()!)
     }else{
       let _ = print(itemY.randomElement()!)
     }
  • Related