Swift

Swift 인스타그램 앱 클론 코딩(3)

지용빡 2022. 5. 4. 23:40
반응형
Swift 인스타그램 앱 클론 코딩(3)
 

Swift 인스타그램 앱 클론 코딩(2)

Swift 인스타그램 UI 클론 코딩(2) Swift 인스타그램 UI 클론 코딩(1) Swift 인스타그램UI 클론 코딩 프로젝트 생성 프로젝트를 생성합니다. Interface는 Storyboard로 선택해줍니다. Storyboard 삭제 Interfa..

wlqkr.tistory.com

TableView 만들기
  • FeedViewController에서 리스트를 만들어 줄 tableView를 구현해줍니다.
  • setupTableView라는 메서드를 extension에 따로 빼주고 addSubView를 해주고 스냅킷으로 Superview에 맞춰주겠습니다.
    private lazy var tableView: UITableView = {
        let tableView = UITableView(frame: .zero)
        tableView.backgroundColor = .systemBackground
        tableView.separatorStyle = .none // CollectionView처럼 사용할 것이기 때문에 separator 제거
        
        return tableView
    }()
    func setupTableView() {
        view.addSubview(tableView)
        tableView.snp.makeConstraints { $0.edges.equalToSuperview() }
    }
  • 테이블뷰가 잘 만들어졌는지 확인하기 위해 임의의 값을 줘보겠습니다.
  • 실행을 해보면 검은색 cell들이 나오는 걸 볼 수 있습니다. saparator를 제거해서 하나로 보이지만 10개의 cell입니다. 
extension FeedViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.backgroundColor = .black
        
        return cell 
    }
}
FeedTableViewCell
  • Custom Cell을 만들기 위해 FeedTableViewCell이란 Swift File을 생성하겠습니다.
import UIKit
import SnapKit

final class FeedTableViewCell: UITableViewCell {
    
}
  • custom cell을 불러오기 위해 소스를 수정하겠습니다.
    private lazy var tableView: UITableView = {
        let tableView = UITableView(frame: .zero)
        tableView.backgroundColor = .systemBackground
        tableView.separatorStyle = .none // CollectionView처럼 사용할 것이기 때문에 separator 제거
        tableView.dataSource = self
        
        tableView.register(FeedTableViewCell.self , forCellReuseIdentifier: "FeedTableViewCell")
        
        return tableView
    }()
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "FeedTableViewCell", for: indexPath) as? FeedTableViewCell
        cell?.selectionStyle = .none
        
        return cell ?? UITableViewCell()
    }
  • 실행을 하면 아무것도 안보이지만 Debug View Hierarchy를 보시면 잘 작동하는걸 보실 수 있습니다.

cell 커스텀하기
  • 화면에 표시 될 좋아요 버튼, 레이블 등 컴포넌트를 추가하겠습니다.
import UIKit
import SnapKit

final class FeedTableViewCell: UITableViewCell {
    private lazy var postImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.backgroundColor = .tertiaryLabel
        
        return imageView
    }()
    
    private lazy var likeButton: UIButton = {
        let button = UIButton()
        button.setImage(UIImage(systemName: "heart"), for: .normal)
        
        return button
    }()
    
    private lazy var commentButton: UIButton = {
        let button = UIButton()
        button.setImage(UIImage(systemName: "message"), for: .normal)
        
        return button
    }()
    
    private lazy var directMessageButton: UIButton = {
        let button = UIButton()
        button.setImage(UIImage(systemName: "paperplane"), for: .normal)
        
        return button
    }()
    
    private lazy var bookMarkButton: UIButton = {
        let button = UIButton()
        button.setImage(UIImage(systemName: "bookmark"), for: .normal)
        
        return button
    }()
    
    private lazy var currentLikeCountLabel: UILabel = {
        let label = UILabel()
        label.textColor = .label
        label.font = .systemFont(ofSize: 13.0, weight: .semibold)
        label.text = "OOO님 외 32명이 좋아합니다."
        
        return label
    }()
    
    private lazy var contentsLabel: UILabel = {
        let label = UILabel()
        label.textColor = .label
        label.font = .systemFont(ofSize: 13.0, weight: .semibold)
        label.numberOfLines = 5 // 줄 수 제한
        label.text = "So keep your head high, keep your chin up, and most importantly, keep smiling, because life’s a beautiful thing and there’s so much to smile about."
        
        return label
    }()
    
    private lazy var dateLabel: UILabel = {
        let label = UILabel()
        label.textColor = .label
        label.font = .systemFont(ofSize: 11.0, weight: .medium)
        label.text = "33분전"
        
        return label
    }()
}
  • addSubView를 해줘야 하는데 하나씩 따로 넣으면 코드 유지보수에도 안좋고 보기도 안좋기 때문에 배열을 활용해서 forEach문으로 addSubView를 해줬습니다. 이러면 나중에 필요없는 것들은 배열에서 삭제만 해주면 되기 때문에 편리합니다.
    func setup() {
        [
            postImageView,
            likeButton,
            commentButton,
            directMessageButton,
            bookMarkButton,
            currentLikeCountLabel,
            contentsLabel,
            dateLabel
        ].forEach { addSubview($0) }
    }
  • SnapKit으로 오토레이아웃도 잡아줍니다.
// 1:1 비율
        postImageView.snp.makeConstraints {
            $0.leading.equalToSuperview()
            $0.trailing.equalToSuperview()
            $0.top.equalToSuperview()
            $0.height.equalTo(postImageView.snp.width)
        }
        
        // 버튼들의 사이 간격은 동일하게 줄 것이기 때문에 만듦
        let buttonWidth: CGFloat = 24.0
        let buttonInset: CGFloat = 16.0
        
        likeButton.snp.makeConstraints {
            $0.leading.equalToSuperview().inset(buttonInset)
            $0.top.equalTo(postImageView.snp.bottom).offset(buttonInset)
            $0.width.equalTo(buttonWidth)
            $0.height.equalTo(buttonWidth)
        }
        
        commentButton.snp.makeConstraints {
            $0.leading.equalTo(likeButton.snp.trailing).offset(12.0)
            $0.top.equalTo(likeButton.snp.top)
            $0.width.equalTo(buttonWidth)
            $0.height.equalTo(buttonWidth)
        }
        
        directMessageButton.snp.makeConstraints {
            $0.leading.equalTo(commentButton.snp.trailing).offset(12.0)
            $0.top.equalTo(likeButton.snp.top)
            $0.width.equalTo(buttonWidth)
            $0.height.equalTo(buttonWidth)
        }
        
        bookMarkButton.snp.makeConstraints {
            $0.trailing.equalToSuperview().inset(buttonInset)
            $0.top.equalTo(likeButton.snp.top)
            $0.width.equalTo(buttonWidth)
            $0.height.equalTo(buttonWidth)
        }
        
        // Label
        currentLikeCountLabel.snp.makeConstraints {
            $0.leading.equalTo(likeButton.snp.leading)
            $0.trailing.equalTo(bookMarkButton.snp.trailing)
            $0.top.equalTo(likeButton.snp.bottom).offset(14.0)
        }
        
        contentsLabel.snp.makeConstraints {
            $0.leading.equalTo(likeButton.snp.leading)
            $0.trailing.equalTo(bookMarkButton.snp.trailing)
            $0.top.equalTo(currentLikeCountLabel.snp.bottom).offset(8.0)
        }
        
        dateLabel.snp.makeConstraints {
            $0.leading.equalTo(likeButton.snp.leading)
            $0.trailing.equalTo(bookMarkButton.snp.trailing)
            $0.top.equalTo(contentsLabel.snp.bottom).offset(8.0)
            $0.bottom.equalToSuperview().inset(16.0)
        }
  • 이제 FeedViewController에서 setup메서드를 불러줍니다.

반응형