简体   繁体   中英

Using a variable inside a closure in swift

Here is my ContentView code:

import SwiftUI

struct GridStack<Content: View>: View {
    let rows: Int
    let columns: Int
    let content: (Character) -> Content

    var body: some View {
        VStack {
            ForEach(1 ..< rows, id: \.self) { row in
                HStack {
                    ForEach(1 ..< self.columns, id: \.self) { column in
                        self.content("C").padding().border(Color.black)
                    }
                }
            }
        }
    }

    init(rows: Int, columns: Int, @ViewBuilder content: @escaping (Character) -> Content) {
        self.rows = rows
        self.columns = columns
        self.content = content
    }
}

And here is the snippet from SceneDelegate.swift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?
    let theSheet = ["A", "M", "A", "N"]
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        let contentView = GridStack(rows: Int(11), columns: Int(11),  content: { _ in Text("\theSheet[3]")})
            
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }

In particular please look at the line:

let contentView = GridStack(rows: Int(11), columns: Int(11),  content: { _ in Text(theSheet[3])})

You can see that I have hard coded the value 3 for the index of array theSheet. What I want to do is to dynamically calculate the index using the current "rows" and "columns" value in the formula rows + columns.

I request the experts here to help with this. I am online to provide any further details you need.

If I understood your issue correctly, I guess you want to display a character from array in 10*10 grid. Create a ContentView and call GridStack from ContentView :

struct ContentView: View {
    let theSheet = [YOUR_ARRAY]
    var body: some View {
       GridStack(rows: Int(10), columns: Int(10),  content: { index in
        Text(self.theSheet[index]).padding(8).border(Color.black).frame(width: 30)
       })
    }
}

In GridStack return the index,

  1. Replace let content: (Character) -> Content with let content: (Int) -> Content
  2. Replace self.content("C").padding().border(Color.black) with self.content((row*self.columns)+column)
  3. Call this ContentView in SceneDelegate like let contentView = ContentView()
  4. Return Int instead of Character in your GridStack

Calculated Index using (row*self.columns)+column

Result: https://i.stack.imgur.com/Qdcjg.png

I think that this isn't a good solution to use closures. SwiftUI means using @State / @ObservableObject / @Environment to change the content. This is a reactive programming.

For instance,

struct GridStack<Content: View>: View {
    let rows: Int
    let columns: Int
    @ObservedObject var viewModel = ViewModel()

    var body: some View {
        let state = viewModel.state
        return VStack {
            ForEach(1 ..< rows, id: \.self) { row in
                HStack {
                    ForEach(1 ..< self.columns, id: \.self) { column in
                        Text("state: \($0)")
                    }
                }
            }
        }
    }

    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM