2017-11-20 7 views
0

Swiftには新しいが、これまでのところ挑戦を楽しんでいる。私はいくつかのコードを作ったが、コントローラを説明に移すためにSwiftのfirebase配列の選択肢をどのように渡すことができるのだろうか?私はベースとしてクリスとコードをしてきましたが、配列はそれでカバーされていません。スウィフトアレイの結果をSegueから説明に引き渡す

ここでは、検索配列とsegueのコードを示します。配列は正常に機能しますが、セルが選択されると、セグは発生しますが、詳細は表示されません。つまり、テキストラベルは空です。

ありがとうございます。ここ

は、Array

import UIKit 
import Firebase 
class LocateTableViewController: UITableViewController, UISearchResultsUpdating { 

@IBOutlet var locateTableView: UITableView! 
let searchController = UISearchController(searchResultsController: nil) 

var firManager:FirebaseManager? 
var placesArray = [NSDictionary?]() 
var filtersPlaces = [NSDictionary?]() 

override func viewDidLoad() { 

    super.viewDidLoad() 

    searchController.searchResultsUpdater = self 
    self.searchController.searchBar.placeholder = "Search bars, brewpubs, shops..." 
    searchController.dimsBackgroundDuringPresentation = false 
    definesPresentationContext = true 
    tableView.tableHeaderView = searchController.searchBar 
    tableView.tableHeaderView = searchController.searchBar 


    let databaseRef = Database.database().reference() 
    // search based on name of place 
    databaseRef.child("places").queryOrdered(byChild: "name").observe(.childAdded, with: { (snapshot) in 

     self.placesArray.append(snapshot.value as? NSDictionary) 
     // insert rows 
     self.locateTableView.insertRows(at: [IndexPath(row:self.placesArray.count-1,section:0)], with: UITableViewRowAnimation.automatic) 


    }) { (error) in 
     print(error.localizedDescription) 
    } 
    // Uncomment the following line to preserve selection between presentations 
    // self.clearsSelectionOnViewWillAppear = false 

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 
    // self.navigationItem.rightBarButtonItem = self.editButtonItem 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

// MARK: - Table view data source 

override func numberOfSections(in tableView: UITableView) -> Int { 
    // #warning Incomplete implementation, return the number of sections 
    return 1 

} 

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    // #warning Incomplete implementation, return the number of rows 

    if searchController.isActive && searchController.searchBar.text != ""{ 
     return filtersPlaces.count 
    } 
    return self.placesArray.count 
} 


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


    // Configure the cell... 
    let place : NSDictionary? 
    if searchController.isActive && searchController.searchBar.text != ""{ 
     place = filtersPlaces[indexPath.row] 
    } 
    else { 
     place = self.placesArray[indexPath.row] 
    } 

    cell.textLabel?.text = place?["type"] as? String 
    cell.detailTextLabel?.text = place?["name"] as? String 

    return cell 
} 

// MARK: - Navigation 

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

    // Check if there's a selection first 
    if let actualIndexPath = tableView.indexPathForSelectedRow { 

     if segue.identifier == "detailSegue" { 

      // Get the selected place 
      let selectedPlace = getPlaceForIndex(indexPath: actualIndexPath) 

      // Create the detail model and set the place 
      let detailModel = DetailModel() 
      detailModel.place = selectedPlace 

      // Set the detail model for the Detail View Controller 
      let detailVC = segue.destination as! DetailViewController 
      detailVC.model = detailModel 

     } 
    } 
} 

func updateSearchResults(for searchController: UISearchController) { 

    filterContent(searchText: self.searchController.searchBar.text!) 
    // Update search results 
} 

func filterContent(searchText: String) 
{ 
    self.filtersPlaces = self.placesArray.filter { place in 
     let placename = place!["name"] as? String 
     return(placename?.lowercased().contains(searchText.lowercased()))! 
    } 
    tableView.reloadData() 
} 

func getPlaceForIndex(indexPath:IndexPath) -> Place { 
    return places[indexPath.row] 
    } 

}

にFirebase情報を解析するためのコードだと、この情報が入るされるべき詳細ビューコントローラのコードである:

import UIKit 

class DetailViewController: UIViewController, DetailModelDelegate, WriteReviewChildViewControllerDelegate { 

// MARK: - Properties 

var place:Place? 
var model:DetailModel? 
var currentViewController:UIViewController? 

@IBOutlet weak var placeImageView: UIImageView! 

@IBOutlet weak var nameLabel: UILabel! 
@IBOutlet weak var categoryLabel: UILabel! 

@IBOutlet weak var faveButton: UIButton! 

@IBOutlet weak var descriptionSectionButton: UIButton! 
@IBOutlet weak var reviewsSectionButton: UIButton! 
@IBOutlet weak var writeReviewSectionButton: UIButton! 

@IBOutlet weak var containerView: UIView! 


@IBOutlet weak var viewTopConstraint: NSLayoutConstraint! 

@IBOutlet weak var viewBottomConstraint: NSLayoutConstraint! 

// MARK: - View Controller Lifecycle 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // Register to listen for keyboard notifications 
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardIsShowing(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil) 

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardIsHiding(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil) 

    // Check if there's a model 
    // If so, then fetch the meta data for that place 
    if let actualModel = model { 

     // Set delegate to self 
     actualModel.delegate = self 

     // Call the get meta function 
     actualModel.getMeta() 

    } 
} 

override func viewWillDisappear(_ animated: Bool) { 

    if let actualModel = model { 
     actualModel.closeObserver() 
    } 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

// MARK: - Display 

func displayMetaData() { 

    // Check if there's a place object in the property 
    if place == nil { 
     return 
    } 

    // Set image 
    model?.getImage(imageName: place!.detailImageName) 

    // Set name label 
    nameLabel.text = place!.name 

    // Set the category label 
    categoryLabel.text = place!.type 

    // Set description 
    if type(of: currentViewController!) == DescriptionChildViewController.self { 
     (currentViewController as? DescriptionChildViewController)?.setDescriptionLabel(text: place!.desc) 
    } 


    else if type(of: currentViewController!) == ReviewsChildViewController.self { 

     // In case the Reviews Child View Controller is already displayed, 
     // We call this function to set the new data and refresh the table 
     let reviewsVC = currentViewController as! ReviewsChildViewController 
     reviewsVC.reloadReviewsData(newReviewData: place!.reviews) 
    } 

    // See if this place is faved 
    setFaveButtonIcon() 

} 



// MARK: - Navigation 

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

    // Set the currentViewController property to the Description Child View Controller 
    // because that's the first one that is shown in the container view 
    currentViewController = segue.destination 
} 

@IBAction func sectionButtonTapped(_ sender: UIButton) { 

    // Declare a variable to hold the destination VC 
    var toVC:UIViewController? 

    // Set section button colors to white 
    descriptionSectionButton.setTitleColor(UIColor.white, for: .normal) 
    reviewsSectionButton.setTitleColor(UIColor.white, for: .normal) 
    writeReviewSectionButton.setTitleColor(UIColor.white, for: .normal) 

    // Set active button color 
    sender.setTitleColor(UIColor.blue, for: .normal) 

    // See which tag triggered this 
    switch sender.tag { 
    case 1: 
     // Description button tapped 

     // Create an instance of the Description Child View Controller 
     toVC = storyboard?.instantiateViewController(withIdentifier: "DescriptionChildVC") 

     if let descVC = toVC, let actualPlace = place { 
      (descVC as! DescriptionChildViewController).descText = actualPlace.desc 
     } 

    case 2: 
     // Reviews button tapped 

     // Create an instance of the Description Child View Controller 
     toVC = storyboard?.instantiateViewController(withIdentifier: "ReviewsChildVC") 

     if let reviewsVC = toVC, let actualPlace = place { 
      (reviewsVC as! ReviewsChildViewController).reviews = actualPlace.reviews 
     } 

    case 3: 
     // Write a review button tapped 

     // Create an instance of the Description Child View Controller 
     toVC = storyboard?.instantiateViewController(withIdentifier: "WriteReviewChildVC") 

     if let writeReviewsVC = toVC { 
      (writeReviewsVC as! WriteReviewChildViewController).delegate = self 
     } 

    default: 
     // Description button tapped 

     // Create an instance of the Description Child View Controller 
     toVC = storyboard?.instantiateViewController(withIdentifier: "DescriptionChildVC") 
    } 

    // Call SwitchChildViewControllers if currentViewController and toVC are not nil 
    if let destinationVC = toVC, let currentVC = currentViewController { 
     switchChildViewControllers(fromVC: currentVC, toVC: destinationVC) 
    } 

} 

func switchChildViewControllers(fromVC:UIViewController, toVC:UIViewController) { 

    // Tell the current VC that its transitioning 
    fromVC.willMove(toParentViewController: nil) 

    // Add the new VC 
    self.addChildViewController(toVC) 
    containerView.addSubview(toVC.view) 

    // Size the frame of the toVC 
    toVC.view.frame = containerView.bounds 

    // Set the new VC alpha to 0 
    toVC.view.alpha = 0 

    // Animate the new VC alpha to 1 and the old VC alpha to 0 
    UIView.animate(withDuration: 0.5, animations: { 

     toVC.view.alpha = 1 
     fromVC.view.alpha = 0 

    }) { (Bool) in 

     // Remove the old VC 
     fromVC.view.removeFromSuperview() 
     fromVC.removeFromParentViewController() 

     // Tell the new VC that it has transitioned 
     toVC.didMove(toParentViewController: self) 

     // Set the currentViewController property to toVC 
     self.currentViewController = toVC 

    } 

} 


// MARK: - Button Action Functions 

@IBAction func backButtonTapped(_ sender: UIButton) { 

    // Navigate back to the list 
    presentingViewController?.dismiss(animated: true, completion: nil) 
} 

@IBAction func shareButtonTapped(_ sender: UIButton) { 

    if place == nil { 
     return 
    } 

    // Data items array 
    var activityItems = [Any]() 

    // Get the image 
    let imageData = CacheManager.getImageFromCache(imageName: place!.detailImageName) 

    if let actualImageData = imageData { 

     // Since we have the image data, create a UIImage 
     let image = UIImage(data: actualImageData) 

     if image != nil { 
      activityItems.append(image!) 
     } 
    } 

    // Add the description to the activity items 
    activityItems.append(place!.desc) 

    // Create a UIActivityViewController 
    let activityVC = UIActivityViewController(activityItems: activityItems, applicationActivities: nil) 

    // Present it 
    present(activityVC, animated: true, completion: nil) 

} 

@IBAction func routeButtonTapped(_ sender: UIButton) { 

    if place == nil { 
     return 
    } 

    // Create a url 
    let modifiedAddress = place!.addr.replacingOccurrences(of: " ", with: "+") 
    let url = URL(string: "http://maps.apple.com/?address=" + modifiedAddress) 

    if let actualURL = url { 


    // Open url 
    UIApplication.shared.open(actualURL, options: [:], completionHandler: nil) 
    } 

} 

@IBAction func favButtonTapped(_ sender: UIButton) { 

    if place != nil { 
     CacheManager.toggleFave(placeId: place!.id) 
     setFaveButtonIcon() 
    } 

} 

// MARK: - Helper Functions 

func setFaveButtonIcon() { 

    if CacheManager.isFave(placeId: place!.id) { 
     faveButton.setImage(#imageLiteral(resourceName: "Bookmark Ribbon Filled"), for: .normal) 
    } 
    else { 
     faveButton.setImage(#imageLiteral(resourceName: "Bookmark Ribbon"), for: .normal) 
    } 

} 

// MARK: - DetailModelDelegate methods 

func detailModel(metaDataFor place: Place) { 

    // Set the place property 
    self.place = place 

    // Display the meta data in the views 
    displayMetaData() 

} 

func detailModel(imageName: String, imageData: Data) { 

    // Detail model has returned with image data 
    // Now can set image view 

    let image = UIImage(data: imageData) 

    if let actualImage = image { 
     placeImageView.image = actualImage 
    } 
} 

func detailModelSaveReviewError() { 

    // Show the error alert 

    let alertController = UIAlertController(title: "Error", message: "There was an error saving your review", preferredStyle: .alert) 

    let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil) 
    alertController.addAction(okAction) 

    present(alertController, animated: false, completion: nil) 
} 

func detailModelSaveReviewSuccess() { 

    // Show the reviews child vc 
    sectionButtonTapped(reviewsSectionButton) 
} 

// MARK: - WriteReviewChildViewControllerDelegate Methods 

func saveReview(name: String, text: String) { 

    // Child view controller is calling save review 
    // Pass that data to the detail model 
    if let actualModel = model { 

     // Call saveReview of the detailmodel 
     actualModel.saveReview(name, text) 
    } 
} 

@objc func keyboardIsShowing(notification:NSNotification) { 

    let userInfo = notification.userInfo 

    if let userInfoDictionary = userInfo { 

     let keyboardRect = userInfoDictionary["UIKeyboardFrameEndUserInfoKey"] as! CGRect 

     // Animate the constraints 
     view.layoutIfNeeded() 

     UIView.animate(withDuration: 0.25) { 

      self.viewTopConstraint.constant = keyboardRect.height * -1 
      self.viewBottomConstraint.constant = keyboardRect.height 

      self.view.layoutIfNeeded() 
     } 

    } 
} 

@objc func keyboardIsHiding(notification:NSNotification) { 

    // Animate the constraints 
    view.layoutIfNeeded() 

    UIView.animate(withDuration: 0.25) { 

     self.viewTopConstraint.constant = 0 
     self.viewBottomConstraint.constant = 0 

     self.view.layoutIfNeeded() 
    } 

} 

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    // Call the "hide keyboard" function of the write reviews child view controller 
    if type(of: currentViewController!) == WriteReviewChildViewController.self { 
     (currentViewController as! WriteReviewChildViewController).hideKeyboard() 
    } 
} 

}

答えて

0

過去の頭痛の原因は何ですか?

  1. コンセントが正しく接続されていることを確認してください。私は削除して再接続しなければならなかった。
  2. セルスタイルが詳細に設定されていることを確認してください。
  3. セル識別子が「セル」に設定されていることを確認します。

時々問題を解決するためにセルを削除して再作成する必要がありました。

これが役に立ちます。

+0

ありがとうございます - segueはまだ動作していますが、今度は "スレッド1:致命的なエラー:インデックスが範囲外です" –

関連する問題