ViOS
ViOS

Reputation: 233

How to make Text tappable inside Group? Compiler problem can't type check

The idea is to create Privacy Text from where I can tap on some selected link and open Safari window inside the app.

As you can see that commented code is redirecting to Safari app to see the web page.

But the problem is with compiler that says - The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressionsThe compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

Here's the code, Please let me know how to overcome this, thanks 🙏

import SwiftUI

struct PrivacyText: View {
    let text: String
//    private let privacyPolicy = "[Privacy Policy](https://www.apple.com/)"
//    private let termsAndConditions = "[Terms & Conditions](https://www.google.com.ua/)"
    
    private let privacyPolicy = URL(string: "https://www.apple.com/")
    private let termsAndConditions = URL(string: "https://www.google.com.ua/")
    @State private var isSafariPresented = false
    @State private var selectedUrl: URL?
    
    var body: some View {
//        Group {
//            Text(text) +
//            Text(" ") +
//            Text(.init(privacyPolicy)) +
//            Text(" and ") +
//            Text(.init(termsAndConditions))
//        }
//        .accentColor(.primary)
//        .foregroundColor(Color(hex: 0x727272))
//        .font(.system(size: 11))
//        .multilineTextAlignment(.center)
        Group {
            Text(text) +
            Text(" ") +
            Text("Privacy Policy")
                .foregroundColor(.white)
                .onTapGesture {
                    selectedUrl = privacyPolicy
                    isSafariPresented.toggle()
                }
            Text(" and ") +
            Text("Terms & Conditions")
                .foregroundColor(.white)
                .onTapGesture {
                    selectedUrl = termsAndConditions
                    isSafariPresented.toggle()
                }
        }
        //            .accentColor(.primary)
        .foregroundColor(Color(hex: 0x727272))
        .font(.system(size: 11))
        .multilineTextAlignment(.center)
        .fullScreenCover(isPresented: $isSafariPresented) {
            if let selectedUrl = selectedUrl {
                SFSafariView(url: selectedUrl)
            }
        }
    }
}

struct PrivacyText_Previews: PreviewProvider {
    static var previews: some View {
        PrivacyText(text: "By continuing, you agree to")
    }
}

import SafariServices

struct SFSafariView: UIViewControllerRepresentable {
    let url: URL

    func makeUIViewController(context: UIViewControllerRepresentableContext<Self>) -> SFSafariViewController {
        let safariController = SFSafariViewController(url: url)
        safariController.preferredBarTintColor = UIColor(.white.opacity(0.8))
        safariController.preferredControlTintColor = UIColor(.white.opacity(0.8))
        
        return safariController
    }

    func updateUIViewController(_ uiViewController: SFSafariViewController, context: UIViewControllerRepresentableContext<SFSafariView>) {
        return
    }
}

Upvotes: 1

Views: 51

Answers (1)

lorem ipsum
lorem ipsum

Reputation: 29464

The compiler is unable to type-check this expression in reasonable time is caused most of the time because of a typo.

Your first typo is because of

Text(text) +
Text(" ") + // Here
Text("Privacy Policy")
    .foregroundColor(.white)
    .onTapGesture {

And

Text(" and ") + //Here
Text("Terms & Conditions")
    .foregroundColor(.white)
    .onTapGesture {

It is a typo because once you add a ViewModifier(s) (.foregroundColor(.white) and . onTapGesture) the Text becomes a View + does not work between a View and a Text

The second typo is

        if let selectedUrl = selectedUrl {
            SFSafariView(url: selectedUrl)
        }//Here

You need an else, in a very fragile manner you assume that you don't need an else by setting $isSafariPresented first.

The second is easier to fix just use .fullScreenCover(item:)

.fullScreenCover(item: $selectedURL) { selectedUrl in
    SFSafariView(url: selectedUrl)
}

The first is more complex and you won't get the multiline formatting.

//switch to HStack
HStack {
    Text(text) +
    Text(" ") //Remove +
    Text("Privacy Policy")
        .foregroundColor(.white)
        .onTapGesture {
            selectedURL = privacyPolicy
        }
    Text(" and ") //Remove +
    Text("Terms & Conditions")
        .foregroundColor(.white)
        .onTapGesture {
            selectedURL = termsAndConditions
        }
}.lineLimit(1).minimumScaleFactor(0.5)

Upvotes: 1

Related Questions