[iOS 5주차] 키오스크 앱 2일차 CardView 만들기

황석범·2024년 11월 26일
0

내일배움캠프_iOS_5기

목록 보기
30/76

내가 구현해야 하는 부분

메뉴 정보가 담긴 카드뷰를 만드는게 내가 맡은 부분이다.

처음 코드

import UIKit
import SnapKit
class CardView{
    
    static func createCardView(name: String, price: Int, image: UIImage?) -> UIView {
        // 카드뷰 생성
        let cardView = UIView()
        cardView.clipsToBounds = true
        cardView.layer.cornerRadius = 12
        cardView.layer.shadowColor = UIColor.black.cgColor
        cardView.layer.shadowOpacity = 0.2
        cardView.layer.shadowOffset = CGSize(width: 0, height: 2)
        cardView.layer.shadowRadius = 4
        cardView.backgroundColor = .white
        
        // 이미지뷰 추가
        let imageView = UIImageView()
        imageView.image = image
        imageView.backgroundColor = .yellow
        imageView.contentMode = .scaleToFill
        imageView.clipsToBounds = true
        cardView.addSubview(imageView)
        
        // 라벨 추가
        let titleLabel = UILabel()
        titleLabel.text = name
        titleLabel.font = UIFont.boldSystemFont(ofSize: 18)
        titleLabel.textColor = .black
        cardView.addSubview(titleLabel)
        
        let priceLabel = UILabel()
        priceLabel.text = String(price)+"원"
        priceLabel.font = UIFont.boldSystemFont(ofSize: 14)
        priceLabel.textColor = .black
        cardView.addSubview(priceLabel)
        
        // 버튼 추가
        let button = UIButton()
        let buttonImage = UIImage(systemName: "plus.circle.fill") // 아이콘 설정
        button.setImage(buttonImage, for: .normal)
        button.tintColor = UIColor(hex: "#F24822")
        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        cardView.addSubview(button)
        
        imageView.snp.makeConstraints { make in
            make.top.equalToSuperview()
            make.leading.equalToSuperview()
            make.trailing.equalToSuperview()
            make.height.equalToSuperview().multipliedBy(0.6)
         }

        
        titleLabel.snp.makeConstraints { make in
            make.top.equalTo(imageView.snp.bottom).offset(10)
            make.leading.equalToSuperview().offset(10)
            make.trailing.equalToSuperview().offset(-50) // 버튼 고려
            make.bottom.lessThanOrEqualToSuperview().offset(-10)
        }
        
        priceLabel.snp.makeConstraints { make in
            make.top.equalTo(titleLabel.snp.bottom).offset(10)
            make.leading.equalToSuperview().offset(10)
            make.trailing.equalToSuperview().offset(-50) // 버튼 고려
            make.bottom.lessThanOrEqualToSuperview().offset(-10)
        }
        
        button.snp.makeConstraints { make in
            make.trailing.equalToSuperview().offset(-10)
            make.centerY.equalTo(priceLabel.snp.centerY) // 라벨과 정렬
            make.width.height.equalTo(30) // 버튼 크기
        }
        
        return cardView
    }
    
    // 버튼 클릭 시 동작 예시
    @objc static func buttonTapped() {
        print("버튼이 클릭되었습니다!")
    }

CardView 클래스 안에 static 메서드인 createCardView로 참조해서 고정된 카드뷰를 생성하게 함
카드뷰의 UI 설정이 변하지 않는다고 생각하여 이렇게 코드를 짰다가 팀원들의 (클래스안에 ............좀 더 생각 정리해서 다시 작성 예정)

UIKit의 UIView를 상속받아 커스텀 뷰 CardView 생성


import UIKit
import SnapKit

class CardView: UIView {
    
    // CardView의 구성요소 이미지, 레이블 2개, 버튼 1개 객체 생성
    private let imageView = UIImageView()
    private let nameLabel = UILabel()
    private let priceLabel = UILabel()
    private let button = UIButton()
    
    // 메뉴 이름, 가격, 이미지를 가지는 객체 생성하고 초기화
    init(name: String, price: Int, image: UIImage?) {
        super.init(frame: .zero)
        setupView() // 뷰
        configure(name: name, price: price, image: image) // 데이터 바인딩 호출
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 카드 뷰 UI 설정
    private func setupView() {
        // 카드뷰 스타일 설정
        self.clipsToBounds = true
        self.layer.cornerRadius = 12
        self.layer.shadowColor = UIColor.black.cgColor
        self.layer.shadowOpacity = 0.2
        self.layer.shadowOffset = CGSize(width: 0, height: 2)
        self.layer.shadowRadius = 4
        self.backgroundColor = .white
        
        // 이미지뷰 설정
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true
        imageView.backgroundColor = .yellow
        addSubview(imageView)
        
        // 메뉴이름 레이블 설정
        nameLabel.font = UIFont.boldSystemFont(ofSize: 30)
        nameLabel.textColor = .black
        nameLabel.numberOfLines = 0 // 여러 줄로 표시 가능
        nameLabel.lineBreakMode = .byWordWrapping // 단어 단위로 줄바꿈
        addSubview(nameLabel)
        
        // 가격 레이블 설정
        priceLabel.font = UIFont.systemFont(ofSize: 20)
        priceLabel.textColor = .darkGray
        addSubview(priceLabel)
        
        // 버튼 설정
        let buttonImage = UIImage(systemName: "plus.circle.fill",
                                  withConfiguration: UIImage.SymbolConfiguration(pointSize: 50, weight: .bold, scale: .large))
        button.setImage(buttonImage, for: .normal)
        button.tintColor = UIColor(named: "PersonalColor")
        //button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        addSubview(button)
        
        // 제약 조건 설정
        setupConstraints()
        
    }
    
    // 카드뷰의 요소 이미지뷰, 메뉴이름, 가격, 버튼 제약 조건 설정 메서드
    private func setupConstraints() {
        imageView.snp.makeConstraints { make in
            make.top.leading.trailing.equalToSuperview()
            make.height.equalToSuperview().multipliedBy(0.6) // 이미지뷰 높이: 카드뷰 높이의 60%
        }

        nameLabel.snp.makeConstraints { make in
            make.top.equalTo(imageView.snp.bottom).offset(30)
            make.leading.equalToSuperview().offset(20)
            make.trailing.lessThanOrEqualTo(button.snp.leading).offset(-10) // 버튼과 겹치지 않도록 설정
        }

        priceLabel.snp.makeConstraints { make in
            make.top.equalTo(nameLabel.snp.bottom).offset(20)
            make.leading.equalToSuperview().offset(20)
            make.trailing.lessThanOrEqualTo(button.snp.leading).offset(-10) // 버튼과 겹치지 않도록 설정
            make.bottom.lessThanOrEqualToSuperview().offset(-10)
        }

        button.snp.makeConstraints { make in
            make.trailing.equalToSuperview().offset(-20) // 카드뷰 오른쪽에서 20pt
            make.bottom.equalToSuperview().offset(-10) // 카드뷰 아래에서 10pt
            make.width.equalToSuperview().multipliedBy(0.3) // 카드뷰 너비의 30%
            make.height.equalToSuperview().multipliedBy(0.3) // 카드뷰 높이의 30%
        }
    }
    
    // 데이터 바인딩해주는 메서드
    private func configure(name: String, price: Int, image: UIImage?) {
        nameLabel.text = name
        priceLabel.text = "\(price)원"
        imageView.image = image
    }
    
}

카테고리는 데이터 바인딩에서 제외 시켰다. CardView 내에서는 카테고리에 따라 변경되는 결과가 없음으로
요것도 생각 정리해서 다시 작성 예정......


CardView 만들면서 배운 내용 정리

UIButton의 이미지 크기 조정 및 레이아웃 제어

1. equalToSuperview().multipliedBy

  • SnapKit에서 부모 뷰의 크기에 비례하여 제약 조건을 설정할 때 사용.

    button.snp.makeConstraints { make in
        make.width.equalToSuperview().multipliedBy(0.2) // 부모 뷰의 20% 너비
        make.height.equalToSuperview().multipliedBy(0.2) // 부모 뷰의 20% 높이
    }

2. UIImage.SymbolConfiguration

  • UIImage(systemName:)로 가져온 시스템 심볼 이미지의 크기, 두께, 스케일 등을 설정하는 데 사용
let buttonImage = UIImage(
    systemName: "plus.circle.fill",
    withConfiguration: UIImage.SymbolConfiguration(pointSize: 50, weight: .bold, scale: .large)
)
button.setImage(buttonImage, for: .normal)
  • 주요 옵션
    • pointSize: 심볼 이미지의 크기 (포인트 단위).
    • weight: 심볼 이미지의 선 두께 (.ultraLight, .light, .regular, .bold 등).
    • scale: 심볼 이미지의 스케일 (.small, .medium, .large).

추가 버튼을 구현할 때 SFSymbols에 있는 이미지를 사용하였는데 버튼의 설정과 제약조건과 다르게 독립적으로 설정해주어야 했다

3. self.clipsToBounds

  • 뷰의 경계를 초과하는 하위 뷰의 콘텐츠를 잘라내는 속성
self.clipsToBounds = true
  • true: 부모 뷰의 경계를 넘어가는 하위 뷰의 콘텐츠는 잘려서 보이지 않음
  • false: 하위 뷰가 부모 뷰의 경계를 넘어도 보임
profile
iOS 공부중...

0개의 댓글

관련 채용 정보