0

플로트 단추가있는 headerView가 있습니다. float 버튼의 모든 하위 항목은 프로그래밍 방식으로 생성되며 headerView의 하위보기이므로 performSegue을 호출 할 수 없습니다. 나는 위임 메서드를 만들려고했지만 완전히 엉망이되었습니다. 프로토콜이 문제가 될 수도 있다는 것을 알고 있습니다. 그러나 정확히 어떻게 해결해야하는지에 대해서는 확실히 확신 할 수 없습니다. 내가UICollectionReusableView (머리글) 사용자 지정 단추에서 PerformSegue Swift

headerView 코드 아래 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 
        } 
       } 
      } 

     }) 
    } 
} 
} 

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

코드는 어디에 있습니까? –

+0

어떤 코드를 요청하십니까? 플로트 버튼 핸들러? –

+0

headerView가 –

답변

3

이 문제를 해결하기를, 당신은 위임라는 패턴을 사용한다.

위임자는 대신 HeaderView에 대한 세그먼트 수행 작업, 즉이 작업을 수행 할 수있는 작업 (이 경우에는 ProfileVC)이 필요하다는 의미입니다.

1 - HeaderView 또는 다른 파일에 프로토콜을 작성하면 사용자의 호출입니다.

2 - HeaderView에 프로토콜 변수 유형을 추가하고 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 - 마지막으로, ProfileVCHeaderViewDelegate 프로토콜을 구현하기 위해 편집에 전달하여 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 
} 

이 방법을 편집에 self을 통과하는 것을 잊지 마세요 당신의 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

답변에 많은 감사드립니다! 이 구현을 시도하고'선택 값을 래핑하는 동안 예기치 않게 발견 된 nil '오류를 표시합니다. –

+0

아마 여러분의 대리자가 nill이고, func setDelegate() 메소드를 사용하려고 시도하십시오. –

+0

그래, 시도해 보았습니다. 그러나 그것은'self.delegate.fabItemClicked()'에서 같은 오류를 보여준다. 헤더 클래스를 추가 한 후 ProfileVC에'delegate = self'를 설정해야합니까? –