본문 바로가기

IOS Swift/Festagram

Swift 프로젝트 : FestaGram 03 메인(피드)화면 02

이제 데이터를 받아서 tableview와 collectionview에 반영할 준비를 해봅시다.

일단 프로젝트를 만들 때마다 하나씩 있는 AppDelegate파일로 들어가주세요

이 프로젝트를 만들면서 생각한건데 제가 포트폴리오라지만 엄~~청나게 욕심이 많은 플젝이었습니다...

입력된 코드라던가 사용할게 너무 많아서 작업시간이 엄청 길어지고 플젝자체가 비대해진걸 나중에 알았지만 되돌릴 수 없기에...

그래도 하다보면 된다더니 하다보면 되더군요 오래 걸렸지만..

저건 모두 여기저기 사용될 전역변수라서 일단 입력만 해주세요

 

그리고 didFinish함수 안에 데이터가 중첩이 되지 않도록 removeAll()해주셔야합니다.

맨 처음 할땐 중첩이고 뭐고 아무것도 몰라서 왜 같은게 2개씩 뜨지????? 이랬었는데....

sleep는 입력된 시간 동안 앱을 실행을 지연시키는 기능입니다 단위는 초로 되어있어요

 

이렇게 마무리하고

 

빈 swift파일 하나를 만들어서 구조체 struct를 만들어 주세요

이 파일은 사용자 자신의 정보를 받을 구조체입니다.

 

그 다음에도 파일 하나를 새로 만들어주세요

이번 파일의 용도는 포스팅된 데이터를 받을 struct입니다.

 

명칭을 지어줄 때 명칭의 용도가 명확하게 보이도록 지어주시면 나중에 편하답니다.

uid나 named, postDate은 말 안해도 뭘 담을 변수인지 아시겠죠?

userPostImage는 게시글에 올라온 이미지가 여러개일 수도 있으니 배열로 선언해주었습니다.

goodmark는 좋아요 여부

viewconut는 조회수

likecount는 좋아요수

urlkey는 게시물의 주소입니다.

 

또 하나 만들어보면

타 유저들과 구분을 짓기 위해 팔로우한 유저들의 데이터를 담을 struct입니다.

그 다음에 갑작스럽지만 xcode를 종료하시고 firebase를 pod install한것 처럼 다른 라이브러리 사용을 위해 프로젝트 폴더 내의

PodFile을 열어서

이렇게 추가로 더 입력해 주시고

 해당 폴더 터미널에서 pod install을 입력해줍시다.

firebase말고 가장 많이 쓸건 SDWebImage입니다 url로 이미지를 받아올 때 코드를 간소화 시켜주는 유용한 라이브러리입니다.

 

이제 인스톨이 끝나고 다시 wordspace형식의 프로젝트를 열면

ListViewController(메인/피드 클래스 파일)에 설치한 라이브러리 사용을 위해 아래 사진처럼 import해주세요

 

두번째와 다섯번째에 있는 것은 마지막 쯔음에 쓸것이니 적고 무시하시면 됩니다.

그 다음에는  외부 변수/상수들을 선언할겁니다 좀 많지만.......

왔다갔다 코딩하는 것보단 한꺼번에 입력하는게 더 편할거 같아서 그냥 다 첨부합니다.

저번 포스팅에 만든 해당 클래스에 있는 피드용 tableview와 연결 되있는 tableviewcell이 있는 파일로 가서 

import도 해주고 fileprivate을 만들어 주세요 

같은 파일에 외부 변수/상수를 또 만들겁니다(한도 끝도 없어..ㅜㅜㅜㅜ)

didset이라는 메소드가 보이시는데 이건 tableview 재사용 셀을 만들 때 데이터가 작업이 완료 된 후의 작용하라는 유용한 메소드입니다.

맨 밑의 actionControlOption은 tableviewcell전용 함수로 사용되도록 제가 만든거에요

import UIKit

extension UITableViewCell {
    func actionControlOption(_ festaData: Posts,
                             _ pageControl: UIPageControl) {
        pageControl.numberOfPages = festaData.userPostImage.count
        if festaData.userPostImage.count == 1 {
            pageControl.isHidden = true
        }else {
            pageControl.isHidden = false
        }
    }
    
    func postingDateCalculation(_ stringDate: String,
                                _ dateFomatter: DateFormatter,
                                _ today: Date,
                                _ calendar: Calendar) -> String {
        let dateString = dateFomatter.string(from: today)
        let nowToday = dateFomatter.date(from: dateString) ?? today
        let postdates = dateFomatter.date(from: stringDate) ?? today
        let calendarC = calendar.dateComponents([.year,.month,.day,.hour,.minute,.second], from: postdates,to: nowToday)
        
        if case let (y?, m?, d?, h?, mi?, s?) = (calendarC.year, calendarC.month, calendarC.day, calendarC.hour,calendarC.minute,calendarC.second) {
            if y == 0, m == 0, d == 0, h == 0, mi == 0  {
                return "\(s)초 전"
            } else if y == 0, m == 0, d == 0, h == 0, mi >= 1 {
                return "\(mi)분 전"
            } else if y == 0, m == 0, d == 0, h >= 1 {
                return "\(h)시간 전"
            }else if  y == 0, m == 0, d >= 1{
                return "\(d)일 전"
            }else if y == 0, m >= 1 {
                return "\(m)개월 전"
            }else if y >= 1, m >= 12 {
                return "\(y)년 전"
            }
        }
        return "\(today)"
    }
    
}

코드가 너무 길고 중복으로 사용되어 UITableCell을 확장하여 거기에 함수를 만들어두어 다른 UITableCell에도 사용할 수 있게 작업했습니다.

 

actionCotrolOption함수는 pageControl UI를 제어하는 함수르 포스팅에 올라간 이미지가 1개이면 숨기고 2개 이상이면 이미지 갯수만큼 늘어나서 표시해주는 제어함수입니다.

 

postingDateCalculation은 날짜계산 초/분/시/일/월/년 단위로 오늘날짜와 비교해서 반환해주는 함수입니다. 많이 쓰여서 확장시켜서 작업했어요.

 

FeedCell클래스에 넣을 마지막 코드는 아래와 같습니다.

override func awakeFromNib() {
        super.awakeFromNib()
        goodBtn.setImage(UIImage(named: "likeBefore.png"), for: .normal)
        goodBtn.setImage(UIImage(named: "likeAfter.png"), for: .selected)
        postImageScrollView.delegate = self
        scrollContentView.isHidden = true
        postUserProfileImg.layer.cornerRadius = postUserProfileImg.frame.height/2
        mySelfImgView.layer.cornerRadius = mySelfImgView.frame.height/2
        mySelfImgView.isUserInteractionEnabled = false
        pageControl.currentPage = 0
        appDelegate.tableCellHeight = self.frame.height
    }
    
    

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        pageControl.currentPage = Int(floor(scrollView.contentOffset.x / UIScreen.main.bounds.width))
    }

 

이제 TableViewDelegate/TableViewDatasource를 다룰 겁니다 

아래처럼 입력해주세요 맨 밑의 adScrollImageView는 아주 멋지고 좋은 포스팅을 해주신 블로거님이 만든 코드를 가져와 조금 바꾼 것입니다.

https://baked-corn.tistory.com/35

 

[ios] Horizontal Scroll View

Horizontal Scroll View 안녕하세요. 오늘은 Scroll View 의 구현 방법 중 하나인 Horizontal Scroll View 에 대해서 알아보는 시간을 갖도록 하겠습니다. Horizontal Scroll View 의 예로는 인스타그램이나 페이..

baked-corn.tistory.com

출처입니다

 

이 출처의 코드를 토대로

import UIKit
import Firebase

fileprivate let firestoreRef = Firestore.firestore()


extension UIViewController {
    //MARK:-스크롤뷰 위의 복수의 이미지 뷰 생성 Func
    func adScrollImageView(_ scrollview: UIScrollView,
                           _ festaData: Posts,
                           _ contentModeCheck: Bool) {
        
        let scrollEdgeInsets = UIEdgeInsets(top: 0, left: 70, bottom: 10, right: 70)
        scrollview.horizontalScrollIndicatorInsets = scrollEdgeInsets
        for i in 0 ..< festaData.userPostImage.count {
            let imageView = UIImageView()
            let scrollFrame = scrollview.frame
            let xPosition = scrollview.frame.width * CGFloat(i)
            
            imageView.isUserInteractionEnabled = true
            if contentModeCheck == false {
                imageView.contentMode = .scaleAspectFit
            }else {
                imageView.contentMode = .scaleAspectFill
            }
            imageView.frame = CGRect(x: xPosition, y: 0, width: scrollFrame.width, height: scrollFrame.height)
            imageView.sd_setImage(with: URL(string: festaData.userPostImage[i]))
            scrollview.contentSize.width = scrollFrame.width * CGFloat(1 + i)
            
            scrollview.addSubview(imageView)
        }
    }
}

이렇게....개조하였습니다. 

사용할일이 3~4번 정도 있어 중복입력이 되지 않게 UIViewController을 확장하여 그 안에 작업했습니다.

 

이제 ListViewController(메인/피드 클래스)로 돌아와 

 

이렇게 적어주면 UITableView 기본 뼈대는 다 만들었습니다. 

다만 아직 포스팅된 게시물이 없어서 정상적으로 실행되지만 안내 UILabel만 뜰거에요 차차 해봅시다.

 

이제 UICollectionView를 다룰겁니다

//MARK: FollowingListDelegate
extension ListViewController : UICollectionViewDataSource {
   
   func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
      return following.count
   }
   
   func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
      guard following.count > 0 else { return UICollectionViewCell() }
      guard let cell = self.follwingCollectionView.dequeueReusableCell(withReuseIdentifier: "follwingcell", for: indexPath) as? ListFollwingCell else { return UICollectionViewCell() }
      cell.followingData = following[indexPath.row]
      return cell
   }
}

extension ListViewController : UICollectionViewDelegate,UICollectionViewDelegateFlowLayout {
   func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
      guard let currentUID = appDelegate.currentUID else { return }
      guard let vc = storyboard?.instantiateViewController(withIdentifier: "MyFestaStoryViewController") as? MyFestaStoryViewController else { return }
      vc.firstMyView.myUID = currentUID
      vc.secondMyview.yourUID = following[indexPath.row].userUID
      vc.firstMyView.yourUID = following[indexPath.row].userUID
      vc.yourName = following[indexPath.row].userName
      navigationController?.pushViewController(vc, animated: true)
   }
   
   func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
      return CGSize(width: self.userProfileImageView.frame.width, height: 71)
   }
   
   func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
      return 15
   }
}

쭉 코드를 보다보면 currentUID가 보일텐데 이건 사용자 자신의 UID입니다 다음과 다다음에 올라갈 포스팅에 데이터 로드를 해서 담게될 변수인데 이미 완성해 놓은 상태서 포스팅 할려니 순서라던가 샘플이라던가 좀 시원스럽게 진행하기가 어렵네요ㅜㅜㅜ

 

빨리 올려서 안내 UILabel이 사라지도록 해볼게요!