ISplitViewController: может ли DetailViewController загружать данные из MasterVIewController без обратной передачи? - PullRequest
0 голосов
/ 25 апреля 2019

Любитель здесь. Я создал приложение iOS Swift, используя UISplitViewController. Пока это хорошо работает. Я хотел бы иметь возможность загружать данные, хранящиеся в MasterViewController, во время просмотра представления DetailViewController, не возвращаясь к представлению MasterViewContoler и не выбирая элемент в представленном там UITableView. Фу, какой глоток, надеюсь, это имеет смысл. Это возможно? Я не уверен, как поступить. Эти изображения могут объяснить лучше:

Детальный просмотр

Master View

Я прочитал эти вопросы: получение MasterViewController из DetailViewController в приложении UISplitViewController и SplitView - перезагрузка данных в master tableView на основе данных, измененных в swift , но они не совсем что я ищу.

Это мой код DetailViewController:

import UIKit
import SafariServices

class DetailViewController: UIViewController {

    @IBOutlet weak var scrollView: UIScrollView!

    @IBOutlet weak var stackView: UIStackView!

    @IBOutlet weak var detailDescriptionLabel: UILabel!

    @IBOutlet weak var compareToButton: UIButton!

    @IBAction func compareToButtonTapped(_ sender: Any) {
        //do something here?
    }


    @IBOutlet weak var pathologyImageViewOne: UIImageView!

    @IBOutlet weak var pathologyImageViewTwo: UIImageView!

    @IBOutlet weak var detailUsedLabel: UILabel!

    @IBOutlet weak var detailReferenceLabel: UILabel!

    @IBOutlet weak var detailPhotoOneCaptionLabel: UILabel!

    @IBOutlet weak var detailPhotoTwoCaptionLabel: UILabel!

    var caseIDOne = 0
    var caseIDTwo = 0
    var compareToButtonString = "Hello"


    func configureView() {
        // Update the user interface for the detail item.
        if let detail = detailItem {
            if let detailDescriptionLabel = detailDescriptionLabel,
                let compareToButton = compareToButton,
                let detailUsedLabel = detailUsedLabel,
                let pathologyImageViewOne = pathologyImageViewOne,
                let pathologyImageViewTwo = pathologyImageViewTwo,
                let detailReferenceLabel = detailReferenceLabel,
                let detailPhotoOneCaptionLabel = detailPhotoOneCaptionLabel,
                let detailPhotoTwoCaptionLabel = detailPhotoTwoCaptionLabel {

                title = detail.name
                caseIDOne = detail.caseIDOne
                caseIDTwo = detail.caseIDTwo!

                detailDescriptionLabel.text = detail.description
                compareToButtonString = detail.compareTo!

                UIView.performWithoutAnimation {
                    compareToButton.setTitle("\(compareToButtonString)", for: .normal)
                }

                detailUsedLabel.text = detail.used
                detailReferenceLabel.text = detail.reference

                pathologyImageViewOne.image = UIImage(named: detail.photoOne)
                pathologyImageViewOne.layer.cornerRadius = 4
                pathologyImageViewOne.contentMode = .scaleAspectFill
                pathologyImageViewOne.clipsToBounds = true

                pathologyImageViewTwo.image = UIImage(named: detail.photoTwo!)
                pathologyImageViewTwo.layer.cornerRadius = 4
                pathologyImageViewTwo.contentMode = .scaleAspectFill
                pathologyImageViewTwo.clipsToBounds = true

                // The image in the foreground
                let frontImage = UIImage(named: "tap-icon")
                // Create the view holding the image
                let frontImageViewOne = UIImageView(image: frontImage)
                // The size and position of the front image
                frontImageViewOne.frame = CGRect(x: 0 , y: 0, width: 34, height: 42)
                // turn off AutoresingMask
                frontImageViewOne.translatesAutoresizingMaskIntoConstraints = false

                // change alpha
                frontImageViewOne.alpha = 0.8

                // Create the view holding the image again
                let frontImageViewTwo = UIImageView(image: frontImage)
                // The size and position of the front image again
                frontImageViewTwo.frame = CGRect(x: 0 , y: 0, width: 34, height: 42)
                // turn off AutoresingMask again
                frontImageViewTwo.translatesAutoresizingMaskIntoConstraints = false

                // change alpha again
                frontImageViewTwo.alpha = 0.8



                //MARK: Image One
                // Add the front image on top of the background
                pathologyImageViewOne.addSubview(frontImageViewOne)

                NSLayoutConstraint.activate([
                    //place the tap icon at the bottom right of parent
                    frontImageViewOne.bottomAnchor.constraint(equalTo: pathologyImageViewOne.bottomAnchor, constant: -10),
                    frontImageViewOne.centerXAnchor.constraint(equalTo: pathologyImageViewOne.rightAnchor, constant: -24)
                    ])


                let tapGestureRecognizerOne = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizerOne:)))
                pathologyImageViewOne.isUserInteractionEnabled = true
                pathologyImageViewOne.addGestureRecognizer(tapGestureRecognizerOne)

                //MARK: Image two
                // Add the front image on top of the background
                pathologyImageViewTwo.addSubview(frontImageViewTwo)

                NSLayoutConstraint.activate([
                    //place the tap icon at the bottom right of parent
                    frontImageViewTwo.bottomAnchor.constraint(equalTo: pathologyImageViewTwo.bottomAnchor, constant: -10),
                    frontImageViewTwo.centerXAnchor.constraint(equalTo: pathologyImageViewTwo.rightAnchor, constant: -24)
                    ])


                let tapGestureRecognizerTwo = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizerTwo:)))
                pathologyImageViewTwo.isUserInteractionEnabled = true
                pathologyImageViewTwo.addGestureRecognizer(tapGestureRecognizerTwo)

                detailPhotoOneCaptionLabel.text = detail.photoOneCaption

                detailPhotoTwoCaptionLabel.text = detail.photoTwoCaption

            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()


        configureView()

        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.layoutMargins  = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
        stackView.isLayoutMarginsRelativeArrangement = true
        scrollView.addSubview(stackView)

        stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        stackView.topAnchor.constraint(equalTo: self.scrollView.topAnchor).isActive = true
        stackView.bottomAnchor.constraint(equalTo: self.scrollView.bottomAnchor).isActive = true


    }

    var detailItem: Descriptor? {
        didSet {
            // Update the view.
           configureView()
        }
    }


    func showWebsite(_ whichCase: Int) {
        if let url = URL(string: "https://digitalpathology.uct.ac.za/case_detail.php?case_id=\(whichCase)") {
            let config = SFSafariViewController.Configuration()
            config.entersReaderIfAvailable = true

            let vc = SFSafariViewController(url: url, configuration: config)
            present(vc, animated: true)
        }
    }



    @objc func imageTapped(tapGestureRecognizerOne: UITapGestureRecognizer)
    {

       showWebsite(caseIDOne)
       print("Image tapped")
       print("CaseOne ID = \(caseIDOne)")
    }

    @objc func imageTapped(tapGestureRecognizerTwo: UITapGestureRecognizer)
    {

        showWebsite(caseIDTwo)
        print("Image tapped")
        print("CaseTwo ID = \(caseIDTwo)")
    }


}

Мой отредактированный (для краткости) код MasterViewController:

import UIKit

class MasterViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!

    @IBOutlet weak var searchFooter: SearchFooter!

    var detailViewController: DetailViewController? = nil

    var descriptors = [Descriptor]()

    var filteredDescriptors = [Descriptor]()

    let searchController = UISearchController(searchResultsController: nil)

    fileprivate var collapseDetailViewController = true

    // MARK: - view setup
    override func viewDidLoad() {
        super.viewDidLoad()

        // Setup the Search Controller
        searchController.searchResultsUpdater = self
        searchController.obscuresBackgroundDuringPresentation = false
        searchController.searchBar.placeholder = "Search Descriptors"
        navigationItem.searchController = searchController

        definesPresentationContext = true

        //delagate and data source commented out, connected in storyboard
        //tableView.delegate = self
        //tableView.dataSource = self

        // The data
        descriptors = [
            Descriptor(name:"Friable", description:"Easily crumbled. Said of tissue that readily tears, fragments, or bleeds when gently palpated or manipulated.", photoOne: "Friable", photoOneCaption:"Subacute bacterial edocarditis",  used:"Used in relation to – heart valve vegetations, brittle carcinomatous tissue esp. of cervix.", reference: "Ref: DMD", caseIDOne:769),           
            Descriptor(name:"Hypertrophic / Hypertrophied", description:"An enlarged, overgrown or bulky organ or part, on account of an increase in the size of its cells (compare ‘hyperplastic’).", compareTo: "Hyperplastic", photoOne: "Hypertrophic1", photoOneCaption:"The heart in hypertension", photoTwo: "Hypertrophic2", photoTwoCaption:"The heart in hypertension", used:"Used in relation to – over-exercised muscles or muscular organs such as heart, bladder, stomach.", reference: "Ref: FPMD", caseIDOne:833, caseIDTwo:833),
            Descriptor(name:"Hyperplastic", description:"An enlarged or expanded organ or part, on account of an increase in the formation and number of normal cells (compare ‘hypertrophy’). Hyperplastic expansion may be uniform or nodular.",  compareTo: "Hypertrophy", photoOne: "Hyperplastic", photoOneCaption:"Hyperplastic gastropathy in Zollinger-Ellison syndrome", used:"Used in relation to - a benign expansion of the prostate, an endo- or epithelium, lymph node, gums or endocrine glands, usually reflecting hyper-stimulation of some cause.", reference: "Ref: MKEDMNAH", caseIDOne:555),]

        if let split = splitViewController {
            let controllers = split.viewControllers
           detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
        }
        //splitViewController?.delegate = self as? UISplitViewControllerDelegate
        splitViewController?.delegate = self

    }

    override func viewWillAppear(_ animated: Bool) {

        if splitViewController!.isCollapsed {
            if let selectionIndexPath = self.tableView.indexPathForSelectedRow {
                self.tableView.deselectRow(at: selectionIndexPath, animated: animated)
            }
         }



        //lets sort the array of objects so A comes before Z
        descriptors.sort { $0.name.compare($1.name) == .orderedAscending }
        self.tableView.reloadData()

        super.viewWillAppear(animated)
    }


    // MARK: - Segues

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {


        if segue.identifier == "showDetail" {
            if let indexPath = tableView.indexPathForSelectedRow {
                let descriptor: Descriptor
                if isFiltering() {
                    descriptor = filteredDescriptors[indexPath.row]
                } else {
                    descriptor = descriptors[indexPath.row]
                }
                let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
                controller.detailItem = descriptor

                collapseDetailViewController = false

                controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
                controller.navigationItem.leftItemsSupplementBackButton = true

                let backItem = UIBarButtonItem()
                backItem.title = "Pathology A-Z"
                navigationItem.backBarButtonItem = backItem
            }
        }
    }

    // MARK: - Table View
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if isFiltering() {
            searchFooter.setIsFilteringToShow(filteredItemCount: filteredDescriptors.count, of: descriptors.count)
            return filteredDescriptors.count
        }
        searchFooter.setNotFiltering()
        return descriptors.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

        let descriptor: Descriptor
        if isFiltering() {
            descriptor = filteredDescriptors[indexPath.row]
        } else {
            descriptor = descriptors[indexPath.row]
        }
        cell.textLabel!.text = descriptor.name
        cell.detailTextLabel!.text = descriptor.description
        return cell
    }

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the specified item to be editable.
        return false
    }

extension MasterViewController: UISplitViewControllerDelegate {

    func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
        return collapseDetailViewController
    }
}

1 Ответ

0 голосов
/ 25 апреля 2019

Вы должны подготовить метод для случая по умолчанию. Скажем, объявите detailDefaultItem в вашем DetailViewController и присвойте detailItem в viewDidLoad до configureView() (просто удалите его, потому что он уже будет вызывать didSet из detailItem):

override func viewDidLoad() {
    super.viewDidLoad()


    var detailDefaultItem = Descriptor()
    // set/configure needed default values in `Descriptor` class or here below
    // detailDefaultItem.property = someValue
    // ...
    detailItem = detailDefaultItem
    // configureView()
...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...