2017-02-06 3 views
0

Firebase의 테이블 (제목 및 이미지)을 통해 여러 게시물을 나열하는 컨트롤러 "Feed"가 있습니다. 버튼의 터치에Firebase - iOs : Tableview에서 DetailsView로 데이터를 전달하는 방법?

enter image description here

는, 내가 게시물 이전에 클릭의 데이터 (제목 이미지 및 캡션) (부모) 인 표시를하고 싶습니다 "세부 피드"컨트롤러로 제공합니다. 클릭에 순간

enter image description here enter image description here

을 (스크린 샷 2 참조), 난 그냥 정보의 아무도는 중포 기지에서 인출되는되지 않으며, 정적 인 정보를 얻었다. 그러나 주 화면에서는 모두 올바르게 호출됩니다. 따라서 문제는 "DetailsController"와 구별 될 때입니다.

이전에 항목을 클릭하여 세부 정보를 가져 오는 방법은 무엇입니까 ??

// 
// Feed.swift 
// MobileAppDemo 
// 
// Created by Mikko Hilpinen on 31.10.2016. 
// Copyright © 2016 Mikkomario. All rights reserved. 
// 

import UIKit 
import FirebaseAuth 
import FirebaseDatabase 
import FirebaseStorage 
import SwiftKeychainWrapper 
import SwiftyJSON 

class FeedVC: UIViewController, UITableViewDataSource,  UIImagePickerControllerDelegate, UINavigationControllerDelegate 
{ 
@IBOutlet weak var addImageView: UIImageView! 
@IBOutlet weak var feedTableView: UITableView! 
@IBOutlet weak var titleInputView: InputTextView! 
@IBOutlet weak var linkbutton: UIButton! 

@IBOutlet weak var captionInputView: InputTextView! 


private var posts = [Post]() 
private var imagePicker = UIImagePickerController() 
private var imageSelected = false 

private var readPosts: ObserveTask? 

override func viewDidLoad() 
{ 
    super.viewDidLoad() 

    imagePicker.delegate = self 
    imagePicker.allowsEditing = true 

    feedTableView.dataSource = self 

    feedTableView.rowHeight = UITableViewAutomaticDimension 
    feedTableView.estimatedRowHeight = 320 

    readPosts = Post.observeList(from: Post.parentReference.queryOrdered(byChild: Post.PROPERTY_CREATED)) 
    { 
     posts in 

     self.posts = posts.reversed() 
     self.feedTableView.reloadData() 
    } 



} 

func numberOfSections(in tableView: UITableView) -> Int 
{ 
    return 1 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
{ 
    return posts.count 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 


// here you need to add 
{ 


    if let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as? MessageCell 
    { 

     let post = posts[indexPath.row] 
     cell.configureCell(tableView: tableView, post: post) 
     cell.linkbutton.tag = indexPath.row 
     cell.linkbutton.addTarget(self, action: #selector(FeedVC.toFeedDetailAction(_:)), for: .touchUpInside) 
     return cell 

    } 
    else 
    { 
     fatalError() 
    } 
} 

func toFeedDetailAction(_ sender: UIButton) { 

    let FeedDetailsController = self.storyboard?.instantiateViewController(withIdentifier: "FeedDetailsController") as! FeedDetailsController 
    FeedDetailsController.post = posts[sender.tag] 
    self.navigationController?.pushViewController(FeedDetailsController, animated: true) 
} 

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) 
{ 
    if let image = info[UIImagePickerControllerEditedImage] as? UIImage 
    { 
     addImageView.image = image 

     imageSelected = true 
    } 
    picker.dismiss(animated: true, completion: nil) 
} 

@IBAction func selectImagePressed(_ sender: AnyObject) 
{ 
    present(imagePicker, animated: true, completion: nil) 
} 

@IBAction func postButtonPressed(_ sender: AnyObject) 
{ 
    guard let caption = captionInputView.text, !caption.isEmpty else 
    { 
     // TODO: Inform the user 
     print("POST: Caption must be entered") 
     return 
    } 

    guard let title = titleInputView.text, !title.isEmpty else 
    { 
     // TODO: Inform the user 
     print("POST: title must be entered") 
     return 
    } 

    guard let image = addImageView.image, imageSelected else 
    { 
     print("POST: Image must be selected") 
     return 
    } 

    guard let currentUserId = User.currentUserId else 
    { 
     print("POST: Can't post before logging in") 
     return 
    } 

    imageSelected = false 
    addImageView.image = UIImage(named: "add-image") 
    captionInputView.text = nil 
    titleInputView.text = nil 

    // Uploads the image 
    if let imageData = UIImageJPEGRepresentation(image, 0.2) 
    { 
     let imageUid = NSUUID().uuidString 
     let metadata = FIRStorageMetadata() 
     metadata.contentType = "image/jpeg" 

     Storage.REF_POST_IMAGES.child(imageUid).put(imageData, metadata: metadata) 
     { 
      (metadata, error) in 

      if let error = error 
      { 
       print("STORAGE: Failed to upload image to storage \(error)") 
      } 

      if let downloadURL = metadata?.downloadURL()?.absoluteString 
      { 
       // Caches the image for faster display 
       Storage.imageCache.setObject(image, forKey: downloadURL as NSString) 

       print("STORAGE: Successfully uploaded image to storage") 
       _ = Post.post(caption: caption, title: title, imageUrl: downloadURL, creatorId: currentUserId) 
      } 
     } 
    } 
} 

@IBAction func signOutButtonPressed(_ sender: AnyObject) 
{ 
    // Doesn't listen to posts anymore 
    readPosts?.stop() 

    try! FIRAuth.auth()?.signOut() 
    User.currentUserId = nil 
    dismiss(animated: true, completion: nil) 
} 
} 

내 피드 상세 사항 :

현재이 내 피드 컨트롤러

당신은 당신의 테이블보기에서 prepare(for:sender:) (A UITableViewDelegate 방법)를 구현하고 필요한 데이터를 추가 할 필요가
// 
// FeedDetails.swift 
// MobileAppDemo 
// 
// Created by Mikko Hilpinen on 31.10.2016. 
// Copyright © 2016 Mikkomario. All rights reserved. 
// 

import UIKit 
import FirebaseAuth 
import FirebaseDatabase 
import FirebaseStorage 
import SwiftKeychainWrapper 
import SwiftyJSON 

class FeedDetailsController: UIViewController, UITableViewDataSource, UIImagePickerControllerDelegate, UINavigationControllerDelegate 
{ 
@IBOutlet weak var addImageView: UIImageView! 
@IBOutlet weak var feedTableView: UITableView! 
@IBOutlet weak var titleInputView: InputTextView! 
@IBOutlet weak var linkbutton: UIButton! 

@IBOutlet weak var captionInputView: InputTextView! 

var post: Post! 

private var posts = [Post]() 
private var imagePicker = UIImagePickerController() 
private var imageSelected = false 

private var readPosts: ObserveTask? 

override func viewDidLoad() 
{ 
    super.viewDidLoad() 

    imagePicker.delegate = self 
    imagePicker.allowsEditing = true 


    readPosts = Post.observeList(from: Post.parentReference.queryOrdered(byChild: Post.PROPERTY_CREATED)) 
    { 
     posts in 

     self.posts = posts.reversed() 
    } 



} 

func numberOfSections(in tableView: UITableView) -> Int 
{ 
    return 1 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
{ 
    return posts.count 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 


    // here you need to add 
{ 


    if let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as? MessageCell 
    { 

     let post = posts[indexPath.row] 
     cell.configureCell(tableView: tableView, post: post) 
     cell.linkbutton.tag = indexPath.row 
     cell.linkbutton.addTarget(self, action: #selector(FeedVC.toFeedDetailAction(_:)), for: .touchUpInside) 
     return cell 

    } 
    else 
    { 
     fatalError() 
    } 
} 


func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) 
{ 
    if let image = info[UIImagePickerControllerEditedImage] as? UIImage 
    { 
     addImageView.image = image 

     imageSelected = true 
    } 
    picker.dismiss(animated: true, completion: nil) 
} 

@IBAction func selectImagePressed(_ sender: AnyObject) 
{ 
    present(imagePicker, animated: true, completion: nil) 
} 

@IBAction func postButtonPressed(_ sender: AnyObject) 
{ 
    guard let caption = captionInputView.text, !caption.isEmpty else 
    { 
     // TODO: Inform the user 
     print("POST: Caption must be entered") 
     return 
    } 

    guard let title = titleInputView.text, !title.isEmpty else 
    { 
     // TODO: Inform the user 
     print("POST: title must be entered") 
     return 
    } 

    guard let image = addImageView.image, imageSelected else 
    { 
     print("POST: Image must be selected") 
     return 
    } 

    guard let currentUserId = User.currentUserId else 
    { 
     print("POST: Can't post before logging in") 
     return 
    } 

    imageSelected = false 
    addImageView.image = UIImage(named: "add-image") 
    captionInputView.text = nil 
    titleInputView.text = nil 

    // Uploads the image 
    if let imageData = UIImageJPEGRepresentation(image, 0.2) 
    { 
     let imageUid = NSUUID().uuidString 
     let metadata = FIRStorageMetadata() 
     metadata.contentType = "image/jpeg" 

     Storage.REF_POST_IMAGES.child(imageUid).put(imageData, metadata: metadata) 
     { 
      (metadata, error) in 

      if let error = error 
      { 
       print("STORAGE: Failed to upload image to storage \(error)") 
      } 

      if let downloadURL = metadata?.downloadURL()?.absoluteString 
      { 
       // Caches the image for faster display 
       Storage.imageCache.setObject(image, forKey: downloadURL as NSString) 

       print("STORAGE: Successfully uploaded image to storage") 
       _ = Post.post(caption: caption, title: title, imageUrl: downloadURL, creatorId: currentUserId) 
      } 
     } 
    } 
} 

@IBAction func signOutButtonPressed(_ sender: AnyObject) 
{ 
    // Doesn't listen to posts anymore 
    readPosts?.stop() 

    try! FIRAuth.auth()?.signOut() 
    User.currentUserId = nil 
    dismiss(animated: true, completion: nil) 
} 
} 
+0

어쩌면이 답변은'prepare (for : sender :)'를 사용하는 방법을 안내하는 데 도움이 될 것입니다. http://stackoverflow.com/a/39930180/5327882 – ronatory

+0

[this] (https : // www.youtube.com/watch?v=nqY5JJptGsc) 비디오. 설명에는 프로젝트를 다운로드하고 데이터를 전달하는 방법을 볼 수있는 링크가 있습니다. 가장 쉬운 방법이지만 실제로는 위임을 제안합니다. 하지만 더 쉬운 방법입니다. –

답변

0

거기에 세부보기 컨트롤러에 표시 할 수 있습니다.

+0

안녕하세요 Mundi, 고마워요, 저는 ios에서 시작합니다. 개발, 혹시 도움이 될만한 가이드가 있습니까? 재정 FUNC 준비 (SEGUE을 위해 : UIStoryboardSegue를 보낸 사람 : 모두) 덕분에 많은 – tibewww

0

좋아, 코드를 사용해 보았지만 너무 많은 요소가 누락되어 오류를 반환 했으므로 컴파일되지 않을지 몰라도해야한다.

첫째 :

나는 두 클래스에서하여 private var posts = [Post]()

번째 게시물의 같은 값을 유지 가정 : 당신이 당신의 슈퍼 클래스에 UITableViewDelegate를 추가 할 필요가

class FeedVC: UIViewController, UITableViewDataSource, UITableViewDelegate, ... 

셋째 :

private var selectedIndexPath: Int = 0 

이 FeedVC에 FeedDetailsController

var selectedIndexPath: Int = 0 // cannot be private to get accessed from FeedVC 

이 위임 기능에 :

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
     selectedIndexPath = indexPath.row 
    } 

이 당신의 FeedVC에 다음을 추가 그대를 위해 준비하다 FeedVC에 GUE는 :

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     let newViewController = segue.destination as! FeedDetailsController 

     newViewController.selectedIndexPath = selectedIndexPath 
    } 

마지막으로 당신은 지금 선택한 후에게이 도움이

let post = posts[selectedIndexPath] 

희망을 얻을 수 postsselectedIndexPath을 사용할 수 있습니다!

+0

안녕 멘토스가, 감사는 모든 시간을, 내가 다음을 시도하고있다 { 경우 segue.identifier == "액션 "{ FeedDetailsController = segue.destination을 다음과 같이 설정하십시오. FeedDetailsController //이 당신이 클래스에 미리 정의 FeedDetailsController.post = 게시물 } } 변수는하지만 난에 값 유형 [포스트]를 지정 cannto 말하는 FeedDetailsController.post = 게시물 에 오류가 '게시'를 입력하십시오. – tibewww

+0

나는 또한 FeedDetailsController.titleInputView = InputTextView를 시도했다! 대신 동일한 유형의 오류가 발생합니다. .. 어떤 생각? 놀랍습니다, 많이 고마워요 !! – tibewww

+0

@tibewww, 시도하십시오'FeedDetailsController.post.insert (, at : )' – Mentos

관련 문제