Tab View not working.

The code below shows the GUI for my app, however none of the buttons on my storyboard are clickable. This code forms part of my A-level computer science project and all help will be very much welcomed.

The code for my GUI is shown below:

//

//  ContentView.swift

//  Custom app bar 3

//

//  Created by ### on 08/09/2022.

//

import SwiftUI

import UIKit

import MapKit

struct ContentView100: View {

    

    @State var selected = 2  // The app will open on this page.

    

    var body: some View {

        

        TabView(selection: $selected) {

            

            

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            Button(action: {}) {

                //HapticsManager.shared.vibrate(for: .success)

                ContentView5().edgesIgnoringSafeArea(.all) // Naviagtion Stacks (Help page)

                

            }

            

            .tabItem {

                Image(systemName: "questionmark.circle.fill")

                Text("Help")

            }.tag(0)  //On menu bar

            

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            Button(action: {}) {

               //HapticsManager.shared.vibrate(for: .success)

                storyboardview2().edgesIgnoringSafeArea(.all) // ViewController2 (Photos page)

                

            }

            

            .tabItem {

                Image(systemName: "photo")

                Text("Photos")

            }.tag(1)  //On menu bar

            

            

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            Button(action: {}) {

                //HapticsManager.shared.vibrate(for: .success)

                storyboardview().edgesIgnoringSafeArea(.all) // ViewController (Camera page)

                

            }

            

            .tabItem {

                Image(systemName: "camera")

                Text("Camera")

            }.tag(2)  //On menu bar

            

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            Button(action: {}) {

               // HapticsManager.shared.vibrate(for: .success)

                storyboardview3().edgesIgnoringSafeArea(.all) // ViewController3 = OCR - does not belog here (History page)

                

            }

            

            .tabItem {

                Image(systemName: "clock")

                Text("History")

            }.tag(3)  //On menu bar

            

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            Button(action: {}) {

              //  HapticsManager.shared.vibrate(for: .success)

                Tutorial().edgesIgnoringSafeArea(.all) // Tutorial - does not belong here (Settings page)

                

            }

            

            .tabItem {

                Image(systemName: "gearshape")

                Text("Settings")

            }.tag(4)  //On menu bar

            

        }

        

    }

    

    

    

    

    

    

    struct Company: Identifiable, Hashable {

        var id = UUID()

        let ticker: String

    }

    

    

    

    

    

    

    

    struct storyboardview: UIViewControllerRepresentable{

        func makeUIViewController(context content: Context) -> UIViewController {

            let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)

            let controller = storyboard.instantiateViewController(identifier: "takePhoto")

            return controller

        }

        func updateUIViewController(_ uiViewController: UIViewController, context: Context) {

            

        }

    }

    

    

    

    

    

    struct storyboardview2: UIViewControllerRepresentable{

        func makeUIViewController(context content: Context) -> UIViewController {

            let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main) //Working

            let controller = storyboard.instantiateViewController(identifier: "selectPhoto") //Working

            return controller //Working

        }

        func updateUIViewController(_ uiViewController: UIViewController, context: Context) {

            

        }

    }

}

Answered by ssmith_c in 736728022

the code you have posted does not compile - ContentView5 and Tutorial are missing. The PreviewProvider is missing - usually this builds your ContentView, but for some reason you have a ContentView100.

It would be easier to read your code if you posted inside a code block (see the little icons at the bottom of the Your Reply pane).

Try again and maybe someone can help you out!

Accepted Answer

the code you have posted does not compile - ContentView5 and Tutorial are missing. The PreviewProvider is missing - usually this builds your ContentView, but for some reason you have a ContentView100.

It would be easier to read your code if you posted inside a code block (see the little icons at the bottom of the Your Reply pane).

Try again and maybe someone can help you out!

There are many issues with the code you posted:

  • You have defined no action in any button. So nothing happens when you tap on them. I added some print to the console to get something when you tap on button that appears in the middle of screen.
  • you do not provide any storyboard, so app crashes.
  • all struct should start with Uppercase.

I modified and completed the code with some dummy struct to make it run. And reformatted it.

import SwiftUI
import UIKit
import MapKit

struct ContentView5: View {
    var body: some View {
        Text("ContentView5")
    }
}

struct Tutorial: View {
    var body: some View {
        Text("Tutorial")
    }
}

struct ContentView100: View {
    
    @State var selected = 2  // The app will open on this page.
    
    var body: some View {
        
        TabView(selection: $selected) {
            
            Button(action: { print("ContentView5") }) {
                //HapticsManager.shared.vibrate(for: .success)
                ContentView5().edgesIgnoringSafeArea(.all) // Naviagtion Stacks (Help page)
            }
            .tabItem {
                Image(systemName: "questionmark.circle.fill")
                Text("Help")
            }.tag(0)  //On menu bar
            
            Button(action: { print("Storyboardview2") }) {
                //HapticsManager.shared.vibrate(for: .success)
                Storyboardview2().edgesIgnoringSafeArea(.all) // ViewController2 (Photos page)
            }
            .tabItem {
                Image(systemName: "photo")
                Text("Photos")
            }.tag(1)  //On menu bar
            
            Button(action: { print("Storyboardview") }) {
                //HapticsManager.shared.vibrate(for: .success)
                Storyboardview().edgesIgnoringSafeArea(.all) // ViewController (Camera page)
            }
            .tabItem {
                Image(systemName: "camera")
                Text("Camera")
            }.tag(2)  //On menu bar
            
            Button(action: { print("Storyboardview3") }) {
                // HapticsManager.shared.vibrate(for: .success)
                Storyboardview3().edgesIgnoringSafeArea(.all) // ViewController3 = OCR - does not belog here (History page)
            }
            .tabItem {
                Image(systemName: "clock")
                Text("History")
            }.tag(3)  //On menu bar
            
            Button(action: { print("Tutorial") }) {
                //  HapticsManager.shared.vibrate(for: .success)
                Tutorial().edgesIgnoringSafeArea(.all) // Tutorial - does not belong here (Settings page)
            }
            .tabItem {
                Image(systemName: "gearshape")
                Text("Settings")
            }.tag(4)  //On menu bar
            
        }
        
    }
    
    
    struct Company: Identifiable, Hashable {
        var id = UUID()
        let ticker: String
    }
    
    
    struct Storyboardview: View {    // Just to be able to compile
        var body: some View {
            Text("Storyboardview")
        }
    }

    struct Storyboardview2: View {    // Just to be able to compile
        var body: some View {
            Text("Storyboardview2")
        }
    }

    struct Storyboardview3: View {    // Just to be able to compile
        var body: some View {
            Text("Storyboardview3")
        }
    }

//    struct storyboardview: UIViewControllerRepresentable{
//        func makeUIViewController(context content: Context) -> UIViewController {
//            let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
//            let controller = storyboard.instantiateViewController(identifier: "takePhoto")
//            return controller
//        }
//        func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
//
//        }
//    }
//
//    struct storyboardview2: UIViewControllerRepresentable{
//        func makeUIViewController(context content: Context) -> UIViewController {
//            let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main) //Working
//            let controller = storyboard.instantiateViewController(identifier: "selectPhoto") //Working
//            return controller //Working
//        }
//        func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
//
//        }
//    }
//
//    struct storyboardview3: UIViewControllerRepresentable{
//        func makeUIViewController(context content: Context) -> UIViewController {
//            let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main) //Working
//            let controller = storyboard.instantiateViewController(identifier: "selectPhoto") //Working
//            return controller //Working
//        }
//        func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
//
//        }
//    }
}

Hi, thank you for your replies, I realise that I did not provide enough code, so below is my ViewController which links to my Storyboard and defines all its actions. Many thanks for your help.

//

//  ViewController.swift

//  TextRecognizeInImage

//

//  Created by ############# on 21/10/2022.

//



import SwiftUI

import UIKit

import Vision



class ViewController: UIViewController {



    @IBOutlet weak var imageView: UIImageView!

    @IBOutlet weak var textView: UITextView!

    @IBOutlet weak var activityIndicator: UIActivityIndicatorView!

    @IBOutlet weak var button: UIButton!

    @IBOutlet weak var shareButton: UIButton!

    

    var request = VNRecognizeTextRequest(completionHandler: nil)

    

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        button.backgroundColor = .systemCyan // Background colour of the select photo button

        button.setTitle("Take Picture", for: .normal)

        button.setTitleColor(.white, for: .normal)

        button.layer.cornerRadius = 25

        button.layer.borderWidth = 20

        button.layer.borderColor = UIColor.systemCyan.cgColor

        

        shareButton.layer.cornerRadius = 25

        shareButton.layer.borderWidth = 10

        shareButton.layer.borderColor = UIColor.systemCyan.cgColor

        

        stopAnimating()

    }

    

    

    private func startAnimating() {

        self.activityIndicator.startAnimating()

    }

    

    private func stopAnimating(){

        self.activityIndicator.stopAnimating()

    }

    @IBAction func takePictureButton(_ sender: Any) {
        setupGallary()
    }

    private func setupGallary(){
        if UIImagePickerController.isSourceTypeAvailable(.photoLibrary){
            let imageTaker = UIImagePickerController()
            imageTaker.sourceType = .camera
            imageTaker.allowsEditing = true
            imageTaker.delegate = self
            present(imageTaker, animated: true)
        }
    }
    private func setupVisionTextRecognizeImage(image: UIImage?){        

        // setup TextRecognition
        var textString = ""

        request = VNRecognizeTextRequest(completionHandler: { (request, error)in
            guard let observations = request.results as?[VNRecognizedTextObservation] else {fatalError("Recieved Invalid Observation")}
            for observation in observations{
                guard let topCandidate = observation.topCandidates(1).first else{
                    print("No candidate")
                    continue
                }
                textString += "\n\(topCandidate.string)"
                DispatchQueue.main.async{
                    self.stopAnimating()
                    self.textView.text = textString
                }
            }
        })

        request.customWords = ["Cust0m"]
        request.minimumTextHeight = 0.03125
        request.recognitionLevel = .accurate
        request.recognitionLanguages = ["en_UK", "en-US", "fr-FR", "it-IT", "de-DE", "es-ES", "pt-BR", "zh-Hans", "zh-Hant", "yue-Hans", "yue-Hant", "ko-KR", "ja-JP", "ru-RU", "uk-UA"]
        request.usesLanguageCorrection = true
        let requests = [request]

        // creating request handler
        DispatchQueue.global(qos: .userInitiated).async{
            guard let img = image?.cgImage else {fatalError("Missing image to scan")}
            let handle = VNImageRequestHandler(cgImage: img, options: [:])
            try? handle.perform(requests)
        }
    }
    @IBAction func shareButton(_ sender: Any) {
        self.enterTextViaAlert()
    }
    private func enterTextViaAlert(){
        self.convertToPdfFileAndShare()
    }
    private func convertToPdfFileAndShare(){
        let fmt = UIMarkupTextPrintFormatter(markupText: self.textView.text)
        
        // 2. Assign print formatter to UIPrintPageRenderer
        let render = UIPrintPageRenderer()
        render.addPrintFormatter(fmt, startingAtPageAt: 0)

        // 3. Assign paperRect and printableRect
        let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi
        render.setValue(page, forKey: "paperRect")
        render.setValue(page, forKey: "printableRect")

        // 4. Create PDF context and draw
        let pdfData = NSMutableData()
        UIGraphicsBeginPDFContextToData(pdfData, .zero, nil)
        for i in 0..<render.numberOfPages {
            UIGraphicsBeginPDFPage();
            render.drawPage(at: i, in: UIGraphicsGetPDFContextBounds())
        }
        UIGraphicsEndPDFContext();
        

        // 5. Save PDF file
        guard let outputURL = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("output").appendingPathExtension("pdf")

        else { fatalError("Destination URL not created")}
        pdfData.write(to: outputURL, atomically: true)
        print("open \(outputURL.path)")

        if FileManager.default.fileExists(atPath: outputURL.path){
            let url = URL(fileURLWithPath: outputURL.path)
            let activityViewController: UIActivityViewController = UIActivityViewController(activityItems: [url], applicationActivities: nil)

            let excludedActivities = [UIActivity.ActivityType.postToFlickr, UIActivity.ActivityType.postToWeibo, UIActivity.ActivityType.message, UIActivity.ActivityType.mail, UIActivity.ActivityType.print, UIActivity.ActivityType.copyToPasteboard, UIActivity.ActivityType.assignToContact, UIActivity.ActivityType.saveToCameraRoll, UIActivity.ActivityType.addToReadingList, UIActivity.ActivityType.postToFlickr, UIActivity.ActivityType.postToVimeo,UIActivity.ActivityType.airDrop, UIActivity.ActivityType.postToTencentWeibo]

            activityViewController.excludedActivityTypes = excludedActivities
            activityViewController.popoverPresentationController?.sourceView=self.view      

            //If user on iPad
            if UIDevice.current.userInterfaceIdiom == .pad {
                if activityViewController.responds(to: #selector(getter: UIViewController.popoverPresentationController)) {
                }
            }
            present(activityViewController, animated: true, completion: nil)
        }
        else {
            print("document was not found")
        }
    }

    private func textFieldDidEndEditing(_ textField: UITextField) {
        guard (textField.text?.count ?? 0)>0 else{ return }
    }
}

extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate{
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey :Any]){
        picker.dismiss(animated: true, completion: nil)
        startAnimating()
        self.textView.text = ""
        let image = info[UIImagePickerController.InfoKey.originalImage]as?UIImage
        self.imageView.image = image
        setupVisionTextRecognizeImage(image: image)
    }
}

So basically, what I am after is my ContentView100, calling my Storyboard (which is defined in ViewControlller) when you are on the camera tab of my app. At the moment, when you are on the camera tab of my app, the storyboard is displayed however no action occurs when you click the take photo button.

Tab View not working.
 
 
Q