메뉴 정보가 담긴 카드뷰를 만드는게 내가 맡은 부분이다.
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 설정이 변하지 않는다고 생각하여 이렇게 코드를 짰다가 팀원들의 (클래스안에 ............좀 더 생각 정리해서 다시 작성 예정)
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 내에서는 카테고리에 따라 변경되는 결과가 없음으로
요것도 생각 정리해서 다시 작성 예정......
equalToSuperview().multipliedBy
SnapKit
에서 부모 뷰의 크기에 비례하여 제약 조건을 설정할 때 사용.
button.snp.makeConstraints { make in
make.width.equalToSuperview().multipliedBy(0.2) // 부모 뷰의 20% 너비
make.height.equalToSuperview().multipliedBy(0.2) // 부모 뷰의 20% 높이
}
let buttonImage = UIImage(
systemName: "plus.circle.fill",
withConfiguration: UIImage.SymbolConfiguration(pointSize: 50, weight: .bold, scale: .large)
)
button.setImage(buttonImage, for: .normal)
추가 버튼을 구현할 때 SFSymbols에 있는 이미지를 사용하였는데 버튼의 설정과 제약조건과 다르게 독립적으로 설정해주어야 했다
self.clipsToBounds = true