apple/iOS, UIKit, Documentation

[iOS] FlexLayout을 Cell에서 사용할 때 주의할 점

lgvv 2022. 9. 2. 18:49

FlexLayout을 Cell에서 사용할 때 주의할 점 

 

나만 안되더라 ㅠ


flexlayout이 뭔가 rootContainer를 사용하는 형태의 일종의 rule? 명확한 코드 스타일에 대한 가이드라인이 없어서 스타일을 맞춰가는 과정에서 휴먼에러 .. 발생

 

 

해결방법

🌿 flex를 cell에 잡을 때 contentView에 잡아주어야 한다.

 

삭제하기 버튼을 누르면 삭제되어야 하는데 이벤트가 왜 방출되지 않냐고요 ㅠㅠ

 

🚨실패한 코드

//
//  NoteCell.swift
//  AppleCollectionView
//
//  Created by Hamlit Jason on 2022/09/01.
//

import UIKit
import FlexLayout
import PinLayout
import RealmSwift
import RxSwift
import RxCocoa

class NoteCell: UICollectionViewCell {
    let disposeBag = DisposeBag()

    /// 셀의 노트 객체
    private var note: Note = Note()
    
    let realm = try! Realm()
    
    // MARK: - Views
    let titleLabel = UILabel()
    let contentLabel = UILabel()
    let deleteButton = UIButton()

    // MARK: - FlexLayout
    let rootFlexContainer: UIView = UIView()

    // MARK: - Life Cycle
    override init(frame: CGRect) {
        super.init(frame: .zero)
        
        addSubview(rootFlexContainer)
        rootFlexContainer.flex
            .padding(10)
            .justifyContent(.spaceBetween)
            .define { flex in

            flex.addItem().alignItems(.center)
                .define { flex in
                    flex.addItem(titleLabel)
                        .marginBottom(10)
                    flex.addItem(contentLabel)
                }
            
            flex.addItem(deleteButton)
        }
        
        setupContentView()
        setupTitleLabel()
        setupContentLabel()
        setupDeleteButton()
        
        bind()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()

        rootFlexContainer.pin.all(safeAreaInsets)
        rootFlexContainer.flex.layout()
    }
    
    /// NoteCell을 세팅
    func configureCell(with item: Note) {
        self.note = item
        
        titleLabel.text = "제목: " + item.title
        contentLabel.text = "컨텐츠: " + item.content
    }
    
    func bind() {
        deleteButton.rx.tap
            .debug(" 🫓 delete")
            .withUnretained(self)
            .bind { owner, _ in
                try! owner.realm.write {
                    owner.realm.delete(owner.note)
                    print("삭제 후 : \(owner.note)")
                }
                print("삭제 후 : \(owner.note)")
            }
            .disposed(by: disposeBag)
    }
}

extension NoteCell {
    /// 셀의 상태 정의
    func setupContentView() {
        contentView.layer.borderWidth = 2
        contentView.layer.borderColor = UIColor.black.cgColor
        contentView.layer.cornerRadius = 12
    }
    
    func setupTitleLabel() {
        titleLabel.font = .systemFont(ofSize: 22, weight: .bold)
        titleLabel.adjustsFontSizeToFitWidth = true
    }

    func setupContentLabel() {
        contentLabel.font = .systemFont(ofSize: 12, weight: .regular)
        contentLabel.textColor = .gray
        contentLabel.numberOfLines = 0
    }

    func setupDeleteButton() {
        deleteButton.setTitle("삭제하기", for: .normal)
        deleteButton.setTitleColor(.red, for: .normal)
    }
}

 

✅ 성공한 코드

//
//  NoteCell.swift
//  AppleCollectionView
//
//  Created by Hamlit Jason on 2022/09/01.
//

import UIKit
import FlexLayout
import PinLayout
import RealmSwift
import RxSwift
import RxCocoa

class NoteCell: UICollectionViewCell {
    let disposeBag = DisposeBag()

    /// 셀의 노트 객체
    private var note: Note = Note()
    
    let realm = try! Realm()
    
    // MARK: - Views
    let titleLabel = UILabel()
    let contentLabel = UILabel()
    let deleteButton = UIButton()

    // MARK: - FlexLayout
    let rootFlexContainer: UIView = UIView()

    // MARK: - Life Cycle
    override init(frame: CGRect) {
        super.init(frame: .zero)
        
//        addSubview(rootFlexContainer)
        contentView.flex
            .padding(10)
            .justifyContent(.spaceBetween)
            .define { flex in

            flex.addItem().alignItems(.center)
                .define { flex in
                    flex.addItem(titleLabel)
                        .marginBottom(10)
                    flex.addItem(contentLabel)
                }
            
            flex.addItem(deleteButton)
        }
        
        setupContentView()
        setupTitleLabel()
        setupContentLabel()
        setupDeleteButton()
        
        bind()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()

        contentView.pin.all(safeAreaInsets)
        contentView.flex.layout()
    }
    
    /// NoteCell을 세팅
    func configureCell(with item: Note) {
        self.note = item
        
        titleLabel.text = "제목: " + item.title
        contentLabel.text = "컨텐츠: " + item.content
    }
    
    func bind() {
        deleteButton.rx.tap
            .debug(" 🫓 delete")
            .withUnretained(self)
            .bind { owner, _ in
                try! owner.realm.write {
                    owner.realm.delete(owner.note)
                    print("삭제 후 : \(owner.note)")
                }
                print("삭제 후 : \(owner.note)")
            }
            .disposed(by: disposeBag)
    }
}

extension NoteCell {
    /// 셀의 상태 정의
    func setupContentView() {
        contentView.layer.borderWidth = 2
        contentView.layer.borderColor = UIColor.black.cgColor
        contentView.layer.cornerRadius = 12
    }
    
    func setupTitleLabel() {
        titleLabel.font = .systemFont(ofSize: 22, weight: .bold)
        titleLabel.adjustsFontSizeToFitWidth = true
    }

    func setupContentLabel() {
        contentLabel.font = .systemFont(ofSize: 12, weight: .regular)
        contentLabel.textColor = .gray
        contentLabel.numberOfLines = 0
    }

    func setupDeleteButton() {
        deleteButton.setTitle("삭제하기", for: .normal)
        deleteButton.setTitleColor(.red, for: .normal)
    }
}