2017-02-03 2 views
0

Hier ist meine Situation:ios Firebase - segue Daten in einem „Detail veröffentlicht“ Regler

Ich habe einen Controller „Vorschub“, die über eine Tabelle mehr Beiträge Liste (ein Titel und Bild) von Firebase.

enter image description here

Auf Knopfdruck bringen, um es zu einem „Feed-Details“ Controller, wo ich die Daten (Titelbild und Bildunterschrift) möchte von der Post zuvor geklickt (Eltern) sein Display. (Siehe Screenshot 2)

enter image description here

Im Moment ist nichts zu sein holen, wenn ich mit den Speise Details Controller ankommen ...

Wie ist es möglich, die Details aus dem Artikel klicken zu holen vorher? ?

Derzeit ist dies mein Feed-Controller:

// 
// FeedVC.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 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 
{ 
    if let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as? MessageCell 
    { 
     let post = posts[indexPath.row] 
     cell.configureCell(tableView: tableView, post: post) 
     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) 
} 
} 

ich den Code für die feeddetails mit - Was natürlich nicht Füße die Daten

Struktur Meine Datenbank wie folgt aussehen:

enter image description here

Wie ist es möglich, die Daten in dieser Detailansicht abzurufen? Wenn mir jemand den Prozess erklären könnte, wird es wirklich fantastisch !!

Vielen Dank für Ihre Zeit und Hilfe !!

----- EDIT: --------

Dank Retterdesdialogs, habe ich den Code aktualisieren und die App starten, aber wenn ich Linkbutton nothin auf den Button klicken passieren und die App-Absturz:

Die Console-Anzeige: Konnte den Wert des Typs 'UIViewController' (0x1087f6758) nicht in 'MobileAppDemo.FeedDetailsController' (0x104bc34a0) umwandeln.

Ich habe jetzt Code:

feedVC.swift (dort die ganze Post aufgelistet):

// 
// FeedVC.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: "FeedDetailsIdentifier") 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) 
} 
} 

und die FeedDetails.swift (wo das Detail aufgeführt sind, wenn Sie geklickt haben, die Taste, Taste hat Klasse: Linkbutton vom ViewVC Controller:

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

import UIKit 
import FBSDKCoreKit 
import FBSDKLoginKit 
import Firebase 
import FirebaseAuth 
import SwiftKeychainWrapper 



fileprivate struct RegisterInfo 
{ 
let email: String 
let password: String 
} 


class FeedDetailsController: UIViewController 
{ 
@IBOutlet weak var emailField: UITextField! 
@IBOutlet weak var passwordField: UITextField! 

var post: Post! 


override func viewDidLoad() 
{ 
    super.viewDidLoad() 
} 

override func viewDidAppear(_ animated: Bool) 
{ 
    if User.currentUserId != nil 
    { 
     print("AUTH: USING EXISTING KEYCHAIN") 
     User.startTrackingCurrentUser() 
     performSegue(withIdentifier: "ToFeed", sender: nil) 
    } 
    else 
    { 
     print("AUTH: NO EXSTING KEYCHAIN") 
    } 
} 

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

// In a storyboard-based application, you will often want to do a little preparation before navigation 
override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
{ 
    print("AUTH: Preparing for segue \(segue.identifier)") 

    if let registrationVC = segue.destination as? RegisterVC 
    { 
     print("AUTH: Found registration VC") 

     if let info = sender as? RegisterInfo 
     { 
      print("AUTH: Sending email (\(info.email)) and password (\(info.password.characters.count) chars) information: ") 
      registrationVC.setBaseInfo(email: info.email, password: info.password) 
     } 
    } 
} 

@IBAction func signInButtonPressed(_ sender: UIButton) 
{ 
    if let email = emailField.text, let password = passwordField.text 
    { 
     FIRAuth.auth()?.signIn(withEmail: email, password: password) 
     { 
      (user, error) in 

      if let error = error 
      { 
       // TODO: Handle other errors here as well 
       switch FIRAuthErrorCode(rawValue: error._code)! 
       { 
       case .errorCodeUserNotFound: 
        print("AUTH: USER NOT FOUND -> CREATING NEW USER") 
        print("AUTH: Sending email \(email) and password \(password.characters.count) characters") 
        self.performSegue(withIdentifier: "RegisterUser", sender: RegisterInfo(email: email, password: password)) 
       default: print("AUTH: ERROR IN EMAIL LOGIN \(error)") // TODO: Inform user 
       } 
      } 
      else 
      { 
       print("AUTH: EMAIL AUTH SUCCESSFUL") 
       User.currentUserId = user?.uid 
       User.startTrackingCurrentUser() 
       self.performSegue(withIdentifier: "ToFeed", sender: nil) 
      } 
     } 
    } 
    // TODO: Inform user that the field contents are missing 
} 

@IBAction func facebookButtonPressed(_ sender: UIButton) 
{ 
    // (Already logged in to FB) 
    if let fbAccessToken = FBSDKAccessToken.current() 
    { 
     print("AUTH: Already logged in to FB") 
     firebaseAuth(with: FIRFacebookAuthProvider.credential(withAccessToken: fbAccessToken.tokenString)) 
    } 
    else 
    { 
     let facebookLogin = FBSDKLoginManager() 
     facebookLogin.logIn(withReadPermissions: ["public_profile", "email"], from: self) 
     { 
      (result, error) in 

      if let error = error 
      { 
       print("AUTH: UNABLE TO AUTHENTICATE WITH FACEBOOK") 
       print("AUTH: \(error)") 
      } 
      else if let result = result 
      { 
       if result.isCancelled 
       { 
        print("AUTH: USER CANCELLED FACEBOOK AUTH") 
       } 
       else 
       { 
        print("AUTH: FACEBOOK AUTH SUCCESS") 
        let credential = FIRFacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString) 
        self.firebaseAuth(with: credential) 
       } 
      } 
     } 
    } 
} 

fileprivate func firebaseAuth(with credential: FIRAuthCredential) 
{ 
    if FIRAuth.auth() == nil 
    { 
     print("AUTH: NO AUTH SERVICE AVAILABLE") 
    } 

    FIRAuth.auth()?.signIn(with: credential) 
    { 
     (user, error) in 

     if let error = error 
     { 
      print("AUTH: UNABLE TO AUTHENTICATE TO FIREBASE") 
      print("AUTH: \(error)") 
     } 
     else 
     { 
      if let user = user 
      { 
       print("AUTH: SUCCESSFULLY AUTHENTICATED WITH FIREBASE") 

       // Updates current user data 
       var userName = "User" 
       var image: UIImage? 

       if let retrievedName = user.displayName 
       { 
        userName = retrievedName 
       } 
       if let retrievedImageUrl = user.photoURL 
       { 
        if let data = try? Data(contentsOf: retrievedImageUrl) 
        { 
         image = UIImage(data: data) 
        } 
       } 

       User.post(uid: user.uid, provider: user.providerID, userName: userName, image: image) 
       { 
        user in 

        User.currentUser = user 
        User.startTrackingCurrentUser() 

        self.performSegue(withIdentifier: "ToFeed", sender: nil) 
       } 
      } 
     } 
    } 
} 
} 

Antwort

0

1) müssen Sie die Taste durch IBOutlet zugreifen können oder programmatisch

2) Stellen Sie die Schaltfläche auf die Zellen indexPath.Zeile und fügen Sie eine Aktion es

let post = posts[indexPath.row] 
cell.configureCell(tableView: tableView, post: post) 
// here you need to add 
cell.yourButton.tag = indexPath.row 
cell.yourButton.addTarget(self, action: #selector(FeedViewController.toFeedDetailAction(_:)), for: .touchUpInside) 
return cell 

3), wenn Sie dann die Taste drücken Sie Ihren Feed identifizieren können, weil Sie auf die Schaltfläche Tag haben, so dass Sie den Feed von Ihrem Beiträge-Array

func toFeedDetailAction(_ sender: UIButton) { 

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

4) in Ihrem FeedDetailsViewController hinzufügen

var post: Post! 

5) in FeedDetailsViewController tun, was immer Sie mit der Post wollen

Hoffe, das hilft :)

+0

Hallo Terrerdesdialogs, Danke für Ihre Zeit, die ich wirklich schätze! 1/ist es ok in meinem feedVC.swift, um @IBOutlet hinzuzufügen, schwach var linkbutton: UIButton! so? Linkbutton ist die Klasse der Schaltfläche 2/Wo gebe ich diesen Code? noch im feedVC.swift? Welcher Teil des obigen Codes? Vielen Dank, im gerade erst mit Xcode und iOS :) :) – tibewww

+0

edit: beim Hinzufügen cell.linkbutton.tag = indexPath.row cell.linkbutton.addTarget (self, Aktion: #selector (FeedViewController.toFeedDetailAction (_ :)), für: .touchUpInside) return Zelle i get ‚Wert vom Typ 'MessageCell' hat kein Mitglied 'Linkbutton' ich schaffe es nicht, um es :( – tibewww

+0

bearbeiten 3 fix zu bekommen, ok ich habe 1 und 2 in 3/Ich habe diesen Fehler: Wert des Typs 'FeedDetailsController.post hat keine Mitgliedspost? ich habe var post: Post! in meinem FeedDetailsController so verstehe ich nicht wirklich warum? – tibewww

Verwandte Themen