2017-10-18 26 views
0

J'ai un headerView dans lequel j'ai un bouton flottant. Puisque tous les sous-éléments du bouton float sont générés par programme et qu'il s'agit d'une sous-vue de headerView, je ne peux pas appeler performSegue. J'ai essayé de créer une méthode de délégué, mais j'ai complètement foiré. Je sais que les protocoles pourraient être la solution, mais je ne suis pas sûr de la façon de le faire. Je joins l'image du headerView ci-dessousPerformSegue à partir du bouton personnalisé UICollectionReusableView (En-tête) Swift

Code headerView:

class ProfileHeader: UICollectionReusableView, FloatyDelegate { 

@IBOutlet weak var pname: UILabel! 
@IBOutlet weak var pusername: UILabel! 
@IBOutlet weak var profilePic: UIImageView! 
@IBOutlet weak var userDesc: UILabel! 
@IBOutlet weak var allviews: UILabel! 
@IBOutlet weak var allphotos: UILabel! 



var user : User! 
var userposts = [String]() 
var currentViewUser: String! 
var floaty = Floaty() 

let uid = KeychainWrapper.standard.string(forKey: KEY_UID) 

override func awakeFromNib() { 
    super.awakeFromNib() 

    user = User() 

    fetchCurrentUser() 
    profilePic.addBlackGradientLayer(frame: profilePic.bounds) 
    layoutFAB() 
} 




func layoutFAB() { 

    floaty.openAnimationType = .slideDown 
    floaty.hasShadow = false 
    floaty.addItem("Edit Profile", icon: UIImage(named: "")) { item in 
     // here is where the segue is to be performed. 
    } 

    floaty.paddingY = (frame.height - 50) - floaty.frame.height/2 
    floaty.fabDelegate = self 
    floaty.buttonColor = UIColor.white 
    floaty.hasShadow = true 
    floaty.size = 45 

    addSubview(floaty) 

} 


func fetchCurrentUser(){ 
    if uid != nil { 
     FBDataservice.ds.REF_CURR_USER.observeSingleEvent(of: .value, with: { (snapshot) in 
      if let allData = snapshot.value as? Dictionary<String, Any> { 
       if let cred = allData["credentials"] as? Dictionary<String, Any> { 
        let user = User(userid: snapshot.key, userData: cred) 
        self.pusername.text = user.username 
        self.pname.text = user.name 
        self.userDesc.text = user.aboutme 
        self.allphotos.text = String(user.photos) 
        self.allviews.text = String(user.views) 
        if user.userPic != nil { 
         let request = URL(string: user.userPic) 
         Nuke.loadImage(with: request!, into: self.profilePic) 
        } else { 
         return 
        } 
       } 
      } 

     }) 
    } 
} 
} 

Code CollectionViewController:

class ProfileVC: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { 


@IBOutlet weak var collectionView: UICollectionView! 

var user : User! 
var userposts = [String]() 
var post = [Posts]() 
var currentViewUser: String! 
var imagePicker: UIImagePickerController! 
var fetcher: Fetcher! 
var imageFromImagePicker = UIImage() 


let uid = KeychainWrapper.standard.string(forKey: KEY_UID) 

override func viewDidLoad() { 
    super.viewDidLoad() 

    user = User() 
    fetcher = Fetcher() 
    imagePicker = UIImagePickerController() 
    imagePicker.delegate = self 

    collectionView.delegate = self 
    collectionView.dataSource = self 



    initializeUserPost() 



    let nib = UINib(nibName: "ProfileCell", bundle: nil) 
    collectionView.register(nib, forCellWithReuseIdentifier: "ProfileCell") 





} 


func editProfileTapped() { 
    performSegue(withIdentifier: "manageconnections", sender: nil) 
} 

@IBAction func manageConnections(_ sender: Any) { 
    performSegue(withIdentifier: "manageconnections", sender: nil) 
} 


override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(true) 
    collectionView.reloadData() 
} 


@IBAction func gotoSettings(_ sender: Any) { 
    performSegue(withIdentifier: "openSettings", sender: nil) 
} 



@IBAction func newPost(_ sender: Any) { 
    uploadNewPost() 
} 

@IBAction func backToFeed(_ sender: Any) { 
    performSegue(withIdentifier: "feedroute", sender: nil) 
} 

@IBAction func searchUsers(_ sender: Any) { 
    performSegue(withIdentifier: "searchNow", sender: nil) 
} 


func initializeUserPost() { 

     FBDataservice.ds.REF_POSTS.observe(.value, with: { (snapshot) in 
      if let snap = snapshot.value as? Dictionary<String, Any> { 
       for snapy in snap { 
        if let userimages = snapy.value as? Dictionary<String, Any> { 
         let author = userimages["author"] as? String 
         if author! == self.uid! { 
          let images = userimages["imageurl"] as? String 
          self.userposts.append(images!) 

         } 
        } 
       } 
      } 
      self.collectionView.reloadData() 
     }) 


} 

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    let userImages = userposts[indexPath.row] 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ProfileCell", for: indexPath) as! ProfileCell 
    cell.fillCells(uid: uid!, userPost: userImages) 
    return cell 
} 


func numberOfSections(in collectionView: UICollectionView) -> Int { 
    return 1 
} 


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
    return userposts.count 


} 

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 


     let selecteditem : String! 
     selecteditem = userposts[indexPath.row] 
     performSegue(withIdentifier: "lol", sender: selecteditem) 

} 

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if segue.identifier == "lol" { 
     if let detailvc = segue.destination as? PhotoDetailVC { 
      if let bro = sender as? String { 
       detailvc.image = bro 
      } 
     } 
    } 
} 


func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { 

    let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "ProfileHeader", for: indexPath) as! ProfileHeader 
    return view 
} 




func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 

     let width = (collectionView.bounds.size.width/3) - 1 
     print(width) 
     let size = CGSize(width: width, height: width) 
     return size 

} 

func collectionView(_ collectionView: UICollectionView, 
        layout collectionViewLayout: UICollectionViewLayout, 
        minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { 
    return 1.0 
} 

func collectionView(_ collectionView: UICollectionView, layout 
    collectionViewLayout: UICollectionViewLayout, 
        minimumLineSpacingForSectionAt section: Int) -> CGFloat { 
    return 1.0 
} 
+0

où est votre code? –

+0

Quel code demandez-vous? Gestionnaire pour le bouton Float? –

+0

votre headerView nous aidera –

Répondre

3

Pour résoudre votre problème, vous devez utiliser un modèle appelé délégué. Delegate signifie que vous avez besoin de quelque chose pour faire le travail d'effectuer une segue pour votre HeaderView à la place, quelque chose qui peut le faire, dans ce cas, votre ProfileVC.

1 - Créez un protocole à l'intérieur de votre HeaderView ou d'un autre fichier, c'est votre appel.

2 - Ajoutez également un type de variable de protocole dans votre HeaderView et transmettez-le à votre viewController.

class ProfileHeader: UICollectionReusableView, FloatyDelegate { 

@IBOutlet weak var pname: UILabel! 
@IBOutlet weak var pusername: UILabel! 
@IBOutlet weak var profilePic: UIImageView! 
@IBOutlet weak var userDesc: UILabel! 
@IBOutlet weak var allviews: UILabel! 
@IBOutlet weak var allphotos: UILabel! 

var user : User! 
var userposts = [String]() 
var currentViewUser: String! 
var floaty = Floaty() 

var delegate: HeaderViewDelegate! 

let uid = KeychainWrapper.standard.string(forKey: KEY_UID) 

override func awakeFromNib() { 
    super.awakeFromNib() 

    user = User() 
    fetchCurrentUser() 
    profilePic.addBlackGradientLayer(frame: profilePic.bounds) 
    layoutFAB() 
} 

func setDelegate(delegate: HeaderViewDelegate) { 
    self.delegate = delegate 
} 

func layoutFAB() { 

    floaty.openAnimationType = .slideDown 
    floaty.hasShadow = false 
    floaty.addItem("Edit Profile", icon: UIImage(named: "")) { item in 

     delegate.fabItemClicked() 
    } 

    floaty.paddingY = (frame.height - 50) - floaty.frame.height/2 
    floaty.fabDelegate = self 
    floaty.buttonColor = UIColor.white 
    floaty.hasShadow = true 
    floaty.size = 45 

    addSubview(floaty) 

} 

func fetchCurrentUser(){ 
    if uid != nil { 
     FBDataservice.ds.REF_CURR_USER.observeSingleEvent(of: .value, with: { (snapshot) in 
      if let allData = snapshot.value as? Dictionary<String, Any> { 
       if let cred = allData["credentials"] as? Dictionary<String, Any> { 
        let user = User(userid: snapshot.key, userData: cred) 
        self.pusername.text = user.username 
        self.pname.text = user.name 
        self.userDesc.text = user.aboutme 
        self.allphotos.text = String(user.photos) 
        self.allviews.text = String(user.views) 
        if user.userPic != nil { 
         let request = URL(string: user.userPic) 
         Nuke.loadImage(with: request!, into: self.profilePic) 
        } else { 
         return 
        } 
       } 
      } 

     }) 
    } 
} 

public protocol HeaderViewDelegate { 
    func fabItemClicked() 
} 

}

3 - Enfin, modifiez votre ProfileVC pour mettre en œuvre le protocole HeaderViewDelegate et le transmettre à votre HeaderView

class ProfileVC: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, HeaderViewDelegate { 

@IBOutlet weak var collectionView: UICollectionView! 

var user : User! 
var userposts = [String]() 
var post = [Posts]() 
var currentViewUser: String! 
var imagePicker: UIImagePickerController! 
var fetcher: Fetcher! 
var imageFromImagePicker = UIImage() 

let uid = KeychainWrapper.standard.string(forKey: KEY_UID) 

override func viewDidLoad() { 
    super.viewDidLoad() 

    user = User() 
    fetcher = Fetcher() 
    imagePicker = UIImagePickerController() 
    imagePicker.delegate = self 

    collectionView.delegate = self 
    collectionView.dataSource = self 

    initializeUserPost() 


    let nib = UINib(nibName: "ProfileCell", bundle: nil) 
    collectionView.register(nib, forCellWithReuseIdentifier: "ProfileCell") 

} 

//Method from the new protocol 
func fabItemClicked(){ 
//Perform your segue here. 
} 

func editProfileTapped() { 
    performSegue(withIdentifier: "manageconnections", sender: nil) 
} 

@IBAction func manageConnections(_ sender: Any) { 
    performSegue(withIdentifier: "manageconnections", sender: nil) 
} 


override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(true) 
    collectionView.reloadData() 
} 


@IBAction func gotoSettings(_ sender: Any) { 
    performSegue(withIdentifier: "openSettings", sender: nil) 
} 



@IBAction func newPost(_ sender: Any) { 
    uploadNewPost() 
} 

@IBAction func backToFeed(_ sender: Any) { 
    performSegue(withIdentifier: "feedroute", sender: nil) 
} 

@IBAction func searchUsers(_ sender: Any) { 
    performSegue(withIdentifier: "searchNow", sender: nil) 
} 


func initializeUserPost() { 

     FBDataservice.ds.REF_POSTS.observe(.value, with: { (snapshot) in 
      if let snap = snapshot.value as? Dictionary<String, Any> { 
       for snapy in snap { 
        if let userimages = snapy.value as? Dictionary<String, Any> { 
         let author = userimages["author"] as? String 
         if author! == self.uid! { 
          let images = userimages["imageurl"] as? String 
          self.userposts.append(images!) 

         } 
        } 
       } 
      } 
      self.collectionView.reloadData() 
     }) 


} 

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    let userImages = userposts[indexPath.row] 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ProfileCell", for: indexPath) as! ProfileCell 
    cell.fillCells(uid: uid!, userPost: userImages) 
    return cell 
} 


func numberOfSections(in collectionView: UICollectionView) -> Int { 
    return 1 
} 


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
    return userposts.count 


} 

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 


     let selecteditem : String! 
     selecteditem = userposts[indexPath.row] 
     performSegue(withIdentifier: "lol", sender: selecteditem) 

} 

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if segue.identifier == "lol" { 
     if let detailvc = segue.destination as? PhotoDetailVC { 
      if let bro = sender as? String { 
       detailvc.image = bro 
      } 
     } 
    } 
} 


func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { 

    let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "ProfileHeader", for: indexPath) as! ProfileHeader 
    view.delegate = self 
    return view 
} 




func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 

     let width = (collectionView.bounds.size.width/3) - 1 
     print(width) 
     let size = CGSize(width: width, height: width) 
     return size 

} 

func collectionView(_ collectionView: UICollectionView, 
        layout collectionViewLayout: UICollectionViewLayout, 
        minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { 
    return 1.0 
} 

func collectionView(_ collectionView: UICollectionView, layout 
    collectionViewLayout: UICollectionViewLayout, 
        minimumLineSpacingForSectionAt section: Int) -> CGFloat { 
    return 1.0 
} 

Ne pas oublier de modifier cette méthode et passer self à votre HeaderView:

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { 

    let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "ProfileHeader", for: indexPath) as! ProfileHeader 
    view.delegate = self 
    return view 
} 
+0

Un grand merci pour la réponse! J'ai essayé de l'implémenter et cela me montre l'erreur «inattendue trouvée lors du déballage d'une valeur optionnelle». –

+0

probablement votre délégué est nill, essayez d'utiliser la méthode func setDelegate() –

+0

Oui, j'ai essayé cela. Pourtant, il me montre la même erreur sur 'self.delegate.fabItemClicked()'. Dois-je définir 'delegate = self' dans ProfileVC après avoir ajouté la classe d'en-tête. –