Learn Courses My Dashboard

Where do I put this conditional?

I’m very rusty with iOS and completely new to SwiftUI.

I’m trying to display one string or another (both constants) based on a toggle. The toggle seems to be ok, but when I try to move the appropriate constant to the display string, I anger the syntax gods. My question is what am I doing wrong and how do i fix it? Thanks!

  
    var body: some View {
        VStack {
            Toggle("Show Solution", isOn: $showSolution)
                .toggleStyle(SwitchToggleStyle(tint: cDynamic))
                .padding(.leading, 22).padding(.trailing, 22)
//            if showSolution {
//                dispStr = solution
//            } else {
//                dispStr = original
//            }
            VStack {
 

You need to put the String into a Text element:

var body: some View {
    VStack {
        Toggle("Show Solution", isOn: $showSolution)
            .toggleStyle(SwitchToggleStyle(tint: cDynamic))
            .padding(.leading, 22).padding(.trailing, 22)
        Text(showSolution ? solution : original)
        VStack {

Thank you, Unfortunately that won’t solve my problem. I didn’t show all the view because it’s very long. My bad. Each of strings are 81 characters long and each character populates it’s own button. Any ideas would be quite welcome.

Create a For loop to make a button based on each character in the string

But will all these buttons do the same thing?

Kinda. They’re very close. Here a sample of two adjacent buttons:

Button {
       buttonWasTapped(currTag: 1)
 } label: {
    Text(String((showSolution ? solution : original).dropFirst(1).dropLast(79)))
      .foregroundColor(original.dropFirst(1).dropLast(79) == "0" ? cStatic : cDynamic)
}.tag(1)
                        
Button {
       buttonWasTapped(currTag: 2)
 } label: {
        Text(String((showSolution ? solution : original).dropFirst(2).dropLast(78)))
         .foregroundColor(original.dropFirst(2).dropLast(78) == "0" ? cStatic : cDynamic)
}.tag(2)

I like the idea of a loop. Please tell me more. Thanks!

The tag that you’re incrementing and the number inside of dropFirst, use that as a variable to increment through your for loop

You can make a ForEach loop, and make an array from that long string use the ForEach loop to increment through the array and make the buttons

Sorry, I’m lost, This is my first SwiftUI program of any consequence. Where does the long string come from? I’m guessing that I’ll be building it. Where? Also, how can I control the position of the buttons?There will be a 9x9 grid. I’ll attach a screenshot. Thank you.

I have no idea you mentioned:

That depends on how you build this view.

The screenshot, is this something you created or a mock-up?

I’m confused what you’re trying to accomplish

Not a good idea to store the entire layout as a single String. You should store each grid along with its solution as a separate item, say in a JSON file.

I mean, you can do it, using something like this:

import SwiftUI

extension String {
    //breaks a String into smaller strings of the given length
    //this would be even easier using the Swift Algorithms package
    func chunked(by length: Int) -> [String] {
        guard length < self.count else {
            return [self]
        }
        
        var startIndex = self.startIndex
        var results: [Substring] = []
        
        while startIndex < self.endIndex {
            let endIndex = self.index(startIndex, offsetBy: length, limitedBy: self.endIndex) ?? self.endIndex
            results.append(self[startIndex..<endIndex])
            startIndex = endIndex
        }
        
        return results.map { String($0) }
    }
}

struct Square: View {
    let squareString: String

    let solution: String = "" //???
    //this would ideally be passed in
    //but how is it determined?

    let displaySolution: Bool

    let cols: [GridItem] = Array(repeating: .init(.flexible(), spacing: 5), count: 3)
    
    var body: some View {
        LazyVGrid(columns: cols, spacing: 20) {
            ForEach(Array(squareString), id: \.self) { character in
                Text(String(character))
                    .foregroundColor(displaySolution && solution.contains(character) ? .green : .primary)
            }
        }
    }
}

struct NumberSquares: View {
    @State private var showSolution = false
    
    let cols: [GridItem] = Array(repeating: .init(.flexible(), spacing: 40), count: 3)
    let s = "987246351654173928321985746128634795537892461694157832519472863286319745473568219"
    
    var body: some View {
        VStack {
            Toggle("Show Solution", isOn: $showSolution)
                .padding(.vertical)
            LazyVGrid(columns: cols, spacing: 40) {
                ForEach(s.chunked(by: 9), id: \.self) { ss in
                    Square(squareString: ss, displaySolution: showSolution)
                }
            }
        }
        .font(.system(size: 21))
        .padding()
    }
}

struct NumberSquares_Previews: PreviewProvider {
    static var previews: some View {
        NumberSquares()
    }
}

You can chunk the 81-number string into smaller, 9-number strings for display in a grid, but then how do you indicate which 3 numbers out of each 9-number grid is the solution? Ideally, you would pass in the solution when you create each Square, but given, e.g., "987246351", how do you determine which 3 numbers constitute the solution?

So, I suppose the “long string” is the 81 digit string being returned from another program.

The screenshot is from the simulator in xCode.

My goal is to make a SwiftUI app that solves sudoku problems. The “engine” used to solve the puzzles is a c++ program, I want pass problems/solutions between the SwiftUI part and the engine using the 81 digit strings. You can see what I’ve done at GitHub - 56phil/CPPInSwift. Thank you.

It appears that I misled you. I apologize. The solution is all 81 digits. The color of the first three digits is probably to blame. As I just told the moderator who is also helping me, I’m working on a sudoku app. My reply there should, I hope, help clear things up. Thank you.

Both original and solution come from functions in a C++ program that is part of / this project. They are strings that represent a flattened out a 9x9 array if type int. All elements in these arrays are one digit numbers. The first 9 characters come from the first row of the array, the next 9 from the second row, etc. Zeroes in original are just placeholders that represent spaces for the player to fill. I’ll include two screenshots. The first will be of original, a sudoku puzzle to be solved. The second will show the solution.