본문 바로가기
Swift/오류 개발자

Swift | TableViewCell의 이미지의 크기가 다르게 적용되는 경우 해결하기

by UDDT 2025. 4. 22.

 오늘 만든 신상 오류

    CoreData를 사용해서 데이터를 저장하고, 저장한 이미지를 불러와서 TableView에 반영해주고 싶었다.

  TableViewCell에 imageView를 만들어두고, imageView에 저장한 이미지를 불러왔더니

   크기와 위치가 제각각인 오류가 있었다.

 

  도통 나의 머리로는 이해할 수가 없는 오류였다.

        imageView.snp.makeConstraints {
            $0.height.width.equalTo(50)
            $0.centerY.equalTo(contentView.snp.centerY)
            $0.leading.equalTo(contentView.snp.leading).offset(20)
        }

  imageView의 제약이 heigtht.width를 고정하고 있고,

        let imageView: UIImageView = {
            let imageView = UIImageView()
            imageView.contentMode = .scaleAspectFit
            imageView.layer.borderColor = UIColor.black.cgColor
            imageView.layer.borderWidth = 1
            imageView.layer.cornerRadius = 25
            return imageView
        }()

 

  다음과 같이 .scaleAspectFit을 해줬으니,

 데이터 소스의 이미지 크기와 상관없이 이미지는 동일해야 한다.(화질이 깨지는 한이 있더라도)

 

  그런데 어떻게 이미지 크기가 다 다를 수가 있을까?

 이미지 크기는 똑같은데 내 눈이 이상한걸까?

 

프로그램에도 착시가 있나요?

 

 이미지 크기가 달라진 이유

    아주 허술한 이유(n번째 허술한 이유...)인데, 이미지 크기가 달라진 이유는 다음과 같다.

 

    이를 설명하려면 바야흐로 초기 UI 세팅 때로 돌아가야 한다.

   TableViewCell에 속성으로 imageView를 추가하려고 하니, 다음과 같은 에러가 나왔다

Cannot override with a stored property 'imageView'

 

  하... 이때 알아차렸어야 했는데.....

안돼.....

 

   스포하자면, 이 오류는 TableViewCell이 자체적으로 imageView라는 프로퍼티를 가지고 있기 때문에

  해당 프로퍼티에 override할 수 없다는 오류였다.

 

  나는 그런 줄도 모르고

  순진하게 '아 ! TableViewCell에는 imageView를 바로 넣을 수가 없구나?' 생각하고는

  내 맘대로 configureUI()라는 메서드에 얘(imageView)를 포함시켰다.

 

   그렇게 나온 코드가 이 코드...

class TableViewCell: UITableViewCell {

    static let id = "TableViewCell"

    let nameLabel: UILabel = {
        let label = UILabel()
        label.text = ""
        label.textColor = .black
        label.font = .systemFont(ofSize: 16)
        label.textAlignment = .center
        return label
    }()

    let phoneNumLabel: UILabel = {
        let label = UILabel()
        label.text = ""
        label.textColor = .black
        label.font = .systemFont(ofSize: 16)
        label.textAlignment = .center
        return label
    }()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        configureUI()
        
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func configureUI() {

        let imageView: UIImageView = {
            let imageView = UIImageView()
            imageView.contentMode = .scaleAspectFit
            imageView.layer.borderColor = UIColor.black.cgColor
            imageView.layer.borderWidth = 1
            imageView.layer.cornerRadius = 25
            return imageView
        }()

        [imageView, nameLabel, phoneNumLabel].forEach { contentView.addSubview($0) }

        imageView.snp.makeConstraints {
            $0.height.width.equalTo(50)
            $0.centerY.equalTo(contentView.snp.centerY)
            $0.leading.equalTo(contentView.snp.leading).offset(20)
        }

        nameLabel.snp.makeConstraints {
            $0.centerY.equalTo(imageView.snp.centerY)
            $0.leading.equalTo(imageView.snp.trailing).offset(20)
        }

        phoneNumLabel.snp.makeConstraints {
            $0.centerY.equalTo(imageView.snp.centerY)
            $0.trailing.equalTo(contentView.snp.trailing).offset(-20)
        }
    }

    public func configureCell(phoneBookData: PhoneBook) {
        self.nameLabel.text = phoneBookData.name
        self.phoneNumLabel.text = phoneBookData.phoneNumber
        guard let profileImage = phoneBookData.image else { return }
        self.imageView?.image = UIImage(data: profileImage)
    }
}

 

  configureUI에서 imageView 관련 부분만 보면,

private func configureUI() {

    let imageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFit
        imageView.layer.borderColor = UIColor.black.cgColor
        imageView.layer.borderWidth = 1
        imageView.layer.cornerRadius = 25
        return imageView
        }()
      
      {  ...  }
    public func configureCell(phoneBookData: PhoneBook) {
        self.nameLabel.text = phoneBookData.name
        self.phoneNumLabel.text = phoneBookData.phoneNumber
        guard let profileImage = phoneBookData.image else { return }
        self.imageView?.image = UIImage(data: profileImage)
    }

 

   이렇게 되는데,

  imageView를 하나 만들어두고, configureCell로 imageView에 이미지를 집어넣으니

 imageView가 2개 생성되어버린 것이다...

 

   뷰 계층을 보면, 아니나 다를까 imageView가 2개가 되어버린 모습.....을 발견할 수 있다...

 

   하.... 얼탱이 없는 실수.....

   파송송 이마탁이다.

 

 해결

class TableViewCell: UITableViewCell {

    static let id = "TableViewCell"

    let nameLabel: UILabel = {
        let label = UILabel()
        label.text = ""
        label.textColor = .black
        label.font = .systemFont(ofSize: 16)
        label.textAlignment = .center
        return label
    }()

    let phoneNumLabel: UILabel = {
        let label = UILabel()
        label.text = ""
        label.textColor = .black
        label.font = .systemFont(ofSize: 16)
        label.textAlignment = .center
        return label
    }()

    let profileImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFit
        imageView.layer.borderColor = UIColor.black.cgColor
        imageView.layer.borderWidth = 1
        imageView.layer.cornerRadius = 25
        return imageView
    }()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        configureUI()
        
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func configureUI() {

        [profileImageView, nameLabel, phoneNumLabel].forEach { contentView.addSubview($0) }

        profileImageView.snp.makeConstraints {
            $0.height.width.equalTo(50)
            $0.centerY.equalTo(contentView.snp.centerY)
            $0.leading.equalTo(contentView.snp.leading).offset(20)
        }

        nameLabel.snp.makeConstraints {
            $0.centerY.equalTo(profileImageView.snp.centerY)
            $0.leading.equalTo(profileImageView.snp.trailing).offset(20)
        }

        phoneNumLabel.snp.makeConstraints {
            $0.centerY.equalTo(profileImageView.snp.centerY)
            $0.trailing.equalTo(contentView.snp.trailing).offset(-20)
        }
    }

    public func configureCell(phoneBookData: PhoneBook) {
        self.nameLabel.text = phoneBookData.name
        self.phoneNumLabel.text = phoneBookData.phoneNumber
        guard let profileImage = phoneBookData.image else { return }
        self.profileImageView.image = UIImage(data: profileImage)
    }
}

 

  코드를 다음과 같이 수정해주고나서 문제를 해결할 수 있었다.

 

결론

    - 컴퓨터는 거짓말을 하지 않는다.

    - 만약 TableViewCell의 이미지 크기가 다르다면, 제약과 선언 위치를 다시 한번 확인하자

 

최근댓글

최근글

skin by © 2024 ttuttak