daewonyoon
daewonyoon

Reputation: 326

SwiftUI Recursive View for Continued Fraction

I wrote a ContinuedFractionView to draw continued fraction structure on my (macos) app.

It works fine when my CF list is relatively short. However, when the list gets a bit longer ( 7, 8, ... ), UI window nearly stops (unresponsive for minutes).

Why? and how could I improve my view?


import SwiftUI

struct ContinuedFractionView: View {
    let continuedFraction: [Int]
    var body: some View {
        HStack(alignment: .top) {
            if continuedFraction.count > 1 {
                VStack {
                    Text("")
                    Text(String(continuedFraction[0]))
                }
                VStack {
                    Text("")
                    Text("+")
                }
                VStack {
                    Text("1")
                    Divider()
                        .background(Color.black)
                    ContinuedFractionView(continuedFraction:  Array(continuedFraction[1...]))
                }
            } else {
                Text(String(continuedFraction[0]))

            }
        }
    }
}

struct ContinuedFractionView_Previews: PreviewProvider {
    static var previews: some View {
        ContinuedFractionView(continuedFraction: [1,2,3,4,5,6,7])
    }
}

Upvotes: 0

Views: 53

Answers (1)

Ashley Mills
Ashley Mills

Reputation: 53092

Does it have to be done recursively? If not, it should be pretty straightforward to draw this:

struct ContentView: View {
    
    let fracs = [1,2,3,4,5]
    
    var body: some View {
        List {
            Section("Mine") {
                NonRecursive(fracs: fracs)
            }
            
            Section("Yours") {
                ContinuedFractionView(continuedFraction: fracs)
            }
        }
        .listStyle(.plain)
    }
}

struct NonRecursive: View {
    
    let fracs: [Int]

    var body: some View {
        VStack(alignment: .leading) {
            ForEach(Array(fracs.dropLast().enumerated()), id: \.1) { (index, frac) in
                HStack(alignment: .top) {
                    HStack {
                        Spacer(minLength: 0)
                        VStack(alignment: .trailing) {
                            Text("")
                            Text(frac, format: .number) + Text(" +")
                        }
                    }
                    .frame(width: CGFloat(index + 1) * 25)
                    VStack {
                        Text("1")
                        Divider()
                            .background(Color.black)
                        if let last = fracs.last, index == fracs.count - 2 {
                            Text(last, format: .number)
                        }
                    }
                }
            }
        }
    }
}

enter image description here

Upvotes: 1

Related Questions