0

Currently, i've reached the place where i succeeded in parsing the local JSON data into SwiftUI's list-view. Now, the data i want to show to the user is formatted in html with various html tags combined with the main description. I want to show that description into WKWebView or some other view where i can show exactly html formatted text with html properties applied. Below is the current scenario where i'm stuck.enter image description here

when user presses the last drop down list, i want them to show that description on other view which can read and apply all the html formatted properties of the JSON data instead of just showing

and other html tags.

Below is the code that i'm currently using..

import SwiftUI

struct lvl4: View {
    @State var book: Book = Book()
    


    var body: some View {
        NavigationView {

            // alternatively
            List {
                ForEach(book.bookContent) { bookContent in
                    Section(header: Text(bookContent.title)) {
                        OutlineGroup(bookContent.child, children: \.child) { item in
                            Text(item.title)
                                .fontWeight(.ultraLight)
                                .lineSpacing(20)
                        }
                    }
                }
            }

            ForEach(book.bookContent) { bookContent in
                VStack {
                    Text(bookContent.title)
                        .foregroundColor(Color.black)
                        .fontWeight(.heavy)


                    List(bookContent.child, children: \.child) { item in
                        Text(item.title)
                            .padding()
                            .monospacedDigit()
                            .drawingGroup()





                    }
                }
            }

        }.navigationViewStyle(.stack)
        .onAppear {
            loadData()
        }
    }


//    func replacingOccurrences(of target: String = "<p>",
//                         with replacement: String = "",
//                      options: NSString.CompareOptions = [],
//                              range searchRange: NSRange) -> String{
//
//        return replacement
//    }
    
    
    func loadData() {
            do {
                if let url = Bundle.main.url(forResource: "સાગર મંથન", withExtension: "json") {
                    let data = try Data(contentsOf: url)
                    book = try JSONDecoder().decode(Book.self, from: data)




                }
            } catch {
                print("error: \(error)")
            }
        }



struct Book: Identifiable, Codable {
    let id = UUID()
    var bookTitle: String = ""
    var isLive: Bool = false
    var userCanCopy: Bool = false
    var bookContent: [BookContent] = []

    enum CodingKeys: String, CodingKey {
        case bookTitle = "book_title"
        case isLive = "is_live"
        case userCanCopy = "user_can_copy"
        case bookContent = "book_content"
    }
    
    
    
}

    struct BookContent: Identifiable, Codable {
        let id = UUID()
        var title, type: String
        var child: [Child]
//        var rendered: String
    }

    struct Child: Identifiable, Codable {
        let id = UUID()
        var title, type: String
        var child: [Child]?

    }
}


struct lvl4_Previews: PreviewProvider {
    static var previews: some View {
        lvl4()
    }
}

New updated code with implemented disclosuregroup, outline group, content view: that has the attributed string working and implemented disclosure group

import SwiftUI
import Foundation


struct ContentView: View {
    
    @EnvironmentObject var booksList:BooksList
    @State var books: [BookModel] = []
    @State var selection: BookModel?
  
    
    
    var body: some View {
        
//        NavigationView {
            
            
        VStack(alignment:.trailing, spacing: 40 ){
            
            ScrollView(.vertical, showsIndicators: false){
               
                ForEach(booksList.books) { book in
            
//                        NavigationLink(destination: lvl4(books: [book], selection: nil)){
//                                               Text(book.bukTitle!)
//                        .listRowInsets(EdgeInsets())
//
            
                    if #available(iOS 15.0, *) {
                        DisclosureGroup ("\(Text(book.bukTitle!) .fontWeight(.medium) .font(.system(size: 27))) "){
                            ForEach(book.bookContent ?? []) { bookContent in
                                DisclosureGroup("\(Text(bookContent.title).fontWeight(.light) .font(.system(size: 25)))")
                                {
                                    OutlineGroup(bookContent.child  , children: \.child) { item in
                                         if #available(iOS 15, *) {
                                                
                                         
                                             Text(attributedString(from: item.title, font: Font.system(size: 23) ))
                                                 .navigationTitle(Text(bookContent.title))
                                                 .padding(10)
                                                
                                            
//                                             if (([Child].self as? NSNull) == nil)  {
                                                   
                                                 
//                                                     NavigationLink(destination: ScrollView {Text(attributedString(from: item.title, font: Font.system(size: 25) )).padding(30) .lineSpacing(10) .navigationTitle(Text(bookContent.title)) .navigationBarTitleDisplayMode(.inline)
//
//                                                        })
//                                                        {
//
//    //                                                        EmptyView()
//        //                                                    .navigationTitle(Text(bookContent.title))
//                                                        }
                                                
                                                 
                                                 
//                                                    }
                                         
                                             
                                         }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }.padding(35)
        
    }
    
                  
//
//                    DisclosureGroup("\(Text(book.bukTitle!).fontWeight(.light) .font(.system(size: 23)))"){
//
//                        ForEach(book.bookContent ?? []) { bookContent in
//
//                            DisclosureGroup("\(Text(bookContent.title))" ){
//
//                                OutlineGroup(bookContent.child, children: \.child) { chld in
//
//
//                                    List(bookContent.child, children: \.child)
//                                    {
//                                      OutlineGroup(bookContent.child, children: \.child) { item in
//                                            if #available(iOS 15, *) {
//
//                                                NavigationLink(destination: ScrollView{Text(attributedString(from: item.title, font: Font.system(size: 22) )).padding(30) .lineSpacing(10) .navigationTitle(Text(bookContent.title)) .navigationBarTitleDisplayMode(.inline)}){
//                                                    EmptyView()
//
//                                                }
//                                            }
//                                        }
//                                    }
//                            }
//                        }
//                    }
//                }
//            }
//        }
//    }
//}

@available(iOS 13.0.0, *)
struct ContentView_Previews: PreviewProvider {
    @available(iOS 13.0.0, *)
    static var previews: some View {
        ContentView()
    }
}
}

Issue 1 with implemented Navigationlink

: The updated code has Navigationlink commented out as the code is acting unusual..: The navigationLink starts to show in all the nested branches after first drop down. Below shown Picture dipcts the issue. ::enter image description here

  • 1
    You can use `AttributedString` to parse HTML and put it into a Text: https://stackoverflow.com/questions/56892691/how-to-show-html-or-markdown-in-a-swiftui-text – Larme Jan 13 '22 at 09:27
  • I don't understand. What do you mean by "limit the string data". – Larme Jan 18 '22 at 08:45
  • the data comes from json file and not html file. Moreover, the json has complex nested structure. How do i parse such string? –  Jan 24 '22 at 09:50
  • "the data comes from json file and not html file". You don't understand: One String property of your Codable String is a String with HTML tags, so just parse that one, not the whole JSON, just that string. I didn't understand which property it is. But instead of just writing `Text(something)`, translate `something` first... – Larme Jan 24 '22 at 09:55

1 Answers1

0

to "...show exactly html formatted text with html properties applied...", try this function that uses AttributedString: (note, this is particular for this text type, Gujarati?)

func attributedString(from str: String) -> AttributedString {
    if let theData = str.data(using: .utf16) {
        do {
            let theString = try NSAttributedString(data: theData, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil)
            return AttributedString(theString)
        } catch {  print("\(error)")  }
    }
    return AttributedString(str)
}

and replace Text(item.title) with Text(attributedString(from: item.title))

You can also look at this SO post/anwser: Convert html links inside text to clickable links - SwiftUI

  • woking great (and yes, its Gujarati language). but, how can i show it on other swiftUI view(detail view) using navigation link or something else.? . //FYI: I tried Text(item.title) using navigation link in outline group but "Navigationlink" then shows in all the outline group items.. (might be due to placing at wrong place) –  Jan 26 '22 at 06:50
  • 1
    read-up on how to use `NavigationLink`, or ask another question about it. The `attributedString` function will still work. – workingdog support Ukraine Jan 26 '22 at 07:54
  • the size of the attributed string is very small. is there any way around to make them larger? –  Jan 27 '22 at 05:50
  • 1
    yes, `AttributedString` can have a lot of parameters, such as font size. Read/study how to do it, there is a lot of info on this. One way here is to modify the `AttributedString(theString)` in the function `attributedString(...)` before you return it. – workingdog support Ukraine Jan 27 '22 at 06:25
  • everything now working as expected :) –  Feb 18 '22 at 06:46
  • is there any way to frequently change the size of the text of that view which ever user needs it( something like sizer scroller from setting)? –  Mar 30 '22 at 07:31