Creating an inline text link that will open up another view in my application

504 Views Asked by At

I'm trying to create a view in my app that displays a chunk of text. I want certain words within that text to be a clickable link that opens up another view. I've been googling for a long time and can't seem to find the right approach.

Simply trying to do things like HStack{ Text("example text") Button("word"), action) Text("rest of example text") } don't work as it really screws up the overall layout of the chunk of text.

I'm also looking into attributed string. I'm wondering if I can make a custom url that points to the view in my app that I want and then apply that to the attributed string. Is that possible?

What's the best approach here?

When I try to open the view inside handling the clicked url nothing happens. Is it just not possible to do this? Do I need to navigate to another swiftUi view instead?

struct shortStoryView: View {
    @State var showPopUpScreen: Bool = false
    
    var body: some View {
        GeometryReader{ geo in
            ZStack{
                Image("homeWallpaper")
                    .resizable()
                    .scaledToFill()
                    .edgesIgnoringSafeArea(.all)
                    .frame(width: geo.size.width, height: geo.size.height, alignment: .center)
                    .opacity(1.0)
                
                testStory(showNewScreen: self.$showPopUpScreen).frame(width: 350, height:500).background(Color.white.opacity(0.75)).cornerRadius(20).overlay( RoundedRectangle(cornerRadius: 16)
                    .stroke(.gray, lineWidth: 6))
                .shadow(radius: 10)
                
            }
        }
    }
    
    struct testStory: View{
        @Binding var showNewScreen: Bool
        
        var body: some View{
            ScrollView(.vertical, showsIndicators: true) {
                    Text("Cristoforo Colombo [nasce](myappurl://action) nel 1451 vicino a Genova, nel nord Italia. A 14 anni diventa marinaio e viaggia in numerosi Paesi. Per Cristoforo Colombo la Terra è rotonda e verso la fine del ‘400, vuole viaggiare verso l’India e vuole farlo con un viaggio verso ovest. La spedizione è costosa e Colombo prima chiede aiuto al re del Portogallo e poi alla regina Isabella di Castiglia. Nel 1492, dopo mesi di navigazione, scopre però un nuovo continente: l’America, che viene chiamata il Nuovo Mondo. Cristoforo Colombo fa altri viaggi in America ma ormai non è più così amato e così muore nel 1506 povero e dimenticato da tutti.")
                        .modifier(textModifer())
                        .environment(\.openURL, OpenURLAction { url in
                            handleURL(url)
                        })
                }
            }
        
        func handleURL(_ url: URL) -> OpenURLAction.Result {
            popUpView()
            return .handled
        }
    }
    
    struct popUpView: View{
        @Environment(\.presentationMode) var presentationMode
        
        var body: some View{
            ZStack(alignment: .topLeading) {
                Text("Nascire - To be Born")
                    .font(Font.custom("Arial Hebrew", size: 20))
                    .background(Color.white.opacity(0.5))
                
                Button(action: { presentationMode.wrappedValue.dismiss()},
                       label: {
                    Image(systemName: "xmark")
                        .foregroundColor(.white)
                        .font(.largeTitle)
                })
            }
        }
    }
1

There are 1 best solutions below

0
Jed On

This isn't exactly what you are looking for but this is what I did as a work around.

NavigationLink {
    RandomView()
} label: {
    Group {
        Text("Your text")
            .font(.subheadline)
            .foregroundStyle(Color.black)
            
        + Text("More text")
            .font(.subheadline)
            .foregroundStyle(Color(.systemBlue))
    }
    .multilineTextAlignment(.leading)
}

I made the whole text a navigation link. I am not sure how to make just one Text() the nav link unless you want to put them side by side in a hstack but that might look odd if the users device is small or the text is long and spills over.