Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UserInfoCell 구현 #7

Merged
merged 6 commits into from
Nov 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions DailyQuest/DailyQuest.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
3413139F291E48A100E607E1 /* Realm in Frameworks */ = {isa = PBXBuildFile; productRef = 3413139E291E48A100E607E1 /* Realm */; };
3449AD5B2922164B00B87619 /* Quest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3449AD5A2922164B00B87619 /* Quest.swift */; };
3449AD5D2922197000B87619 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3449AD5C2922197000B87619 /* User.swift */; };
3449AD6029222B3900B87619 /* UserInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3449AD5F29222B3900B87619 /* UserInfoCell.swift */; };
34ACC32D291DE9C000741371 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34ACC32C291DE9C000741371 /* AppDelegate.swift */; };
34ACC32F291DE9C000741371 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34ACC32E291DE9C000741371 /* SceneDelegate.swift */; };
34ACC336291DE9C100741371 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 34ACC335291DE9C100741371 /* Assets.xcassets */; };
Expand Down Expand Up @@ -47,6 +48,7 @@
/* Begin PBXFileReference section */
3449AD5A2922164B00B87619 /* Quest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Quest.swift; sourceTree = "<group>"; };
3449AD5C2922197000B87619 /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = "<group>"; };
3449AD5F29222B3900B87619 /* UserInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInfoCell.swift; sourceTree = "<group>"; };
34ACC329291DE9C000741371 /* DailyQuest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DailyQuest.app; sourceTree = BUILT_PRODUCTS_DIR; };
34ACC32C291DE9C000741371 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
34ACC32E291DE9C000741371 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -106,6 +108,7 @@
3449AD5E292219D600B87619 /* Common */ = {
isa = PBXGroup;
children = (
3449AD5F29222B3900B87619 /* UserInfoCell.swift */,
);
path = Common;
sourceTree = "<group>";
Expand Down Expand Up @@ -344,6 +347,7 @@
3449AD5D2922197000B87619 /* User.swift in Sources */,
34ACC32D291DE9C000741371 /* AppDelegate.swift in Sources */,
3449AD5B2922164B00B87619 /* Quest.swift in Sources */,
3449AD6029222B3900B87619 /* UserInfoCell.swift in Sources */,
34ACC32F291DE9C000741371 /* SceneDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.859",
"green" : "0.859",
"red" : "0.859"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
14 changes: 14 additions & 0 deletions DailyQuest/DailyQuest/Domain/Entities/Quest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ struct Quest {
return currentCount == totalCount
}

/**
현재 목표달성량(currentCount)에 인자값만큼 더합니다.
Note. 현재 목표달성량은 전체량(totalCount)를 넘을 수 없습니다.

- Parameters:
- value: 0보다 큰 정수값입니다. 기본값은 1입니다.
*/
mutating func increaseCount(with value: Int=1) {
guard currentCount + value <= totalCount else {
self.currentCount = totalCount
Expand All @@ -27,6 +34,13 @@ struct Quest {
self.currentCount += value
}

/**
현재 목표달성량(currentCount)에 인자값만큼 뺍니다.
Note. 현재 목표달성량은 0보다 작을 수 없습니다.

- Parameters:
- value: 0보다 큰 정수값입니다. 기본값은 1입니다.
*/
mutating func decreaseCount(with value: Int=1) {
guard currentCount - value >= 0 else {
self.currentCount = 0
Expand Down
145 changes: 145 additions & 0 deletions DailyQuest/DailyQuest/Presentation/Common/UserInfoCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
//
// UserInfoCell.swift
// DailyQuest
//
// Created by jinwoong Kim on 2022/11/14.
//

import UIKit

import SnapKit

final class UserInfoCell: UITableViewCell {
/// dequeuResusable을 위한 아이덴티파이어입니다.
static let reuseIdentifier = "UserInfoCell"

// MARK: - Components
/**
이미지와 유저이름 레이블을 담기 위한 스택뷰입니다.
수평 스택뷰이며, 중앙 정렬을 통해 각 아이템을 수직축 기준으로 중앙에 위치시켰습니다.
Note. Color를 assets에 임의로 등록하였습니다. 동료들이 동일한 이름으로 동일한 색상을 등록할 수도 있으므로,
이는 회고시간에 반드시 언급해야 합니다.
*/
private lazy var container: UIStackView = {
let container = UIStackView()
container.axis = .horizontal
container.alignment = .center
container.backgroundColor = UIColor(named: "LightGray")
container.spacing = 10
container.isLayoutMarginsRelativeArrangement = true
container.layoutMargins = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 0)
container.layer.cornerRadius = 15

return container
}()

/**
유저의 프로필 이미지가 들어갈 UIImageView입니다.
Note. 원형의 틀을 만들기 위해, render loop의 `layoutSubviews()`메서드를 오버라이드하였음에 유념하세요.
*/
private lazy var userImage: UIImageView = {
let userImage = UIImageView()
userImage.image = UIImage(systemName: "heart.fill")
userImage.clipsToBounds = true
userImage.backgroundColor = .white

return userImage
}()

/**
유저의 닉네임이 들어갈 레이블입니다.
*/
private lazy var userName: UILabel = {
let userName = UILabel()
userName.text = " "

return userName
}()

// MARK: - Methods
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")
}

override func layoutSubviews() {
super.layoutSubviews()
userImage.layer.cornerRadius = userImage.frame.height / 2
}

/**
UI의 constraints를 설정하기 위한 메서드입니다.
constraints를 설정하기 전에, 해당 뷰를 먼저 add해야함을 유념하세요.
*/
private func configureUI() {
container.addArrangedSubview(userImage)
container.addArrangedSubview(userName)
addSubview(container)

container.snp.makeConstraints { make in
make.edges.equalToSuperview()
}

userImage.snp.makeConstraints { make in
make.height.equalToSuperview().offset(-40)
make.width.equalTo(userImage.snp.height)
}
}

/**
인자로 받은 Entity User타입을 통해 그 정보를 기반으로 cell에 아이템을 넣습니다.

- Parameters:
- user: User타입의 엔티티입니다.
*/
func setup(with user: User) {
userName.text = user.nickName
guard let image = UIImage(data: user.profile) else { return }
userImage.image = image
}
}

/**
SwiftUI 프리뷰 기능을 사용하기 위한 코드들 입니다.
*/
#if canImport(SwiftUI) && DEBUG
import SwiftUI
struct UIViewPreview<View: UIView>: UIViewRepresentable {
let view: View

init(_ builder: @escaping () -> View) {
view = builder()
}

// MARK: - UIViewRepresentable

func makeUIView(context: Context) -> UIView {
return view
}

func updateUIView(_ view: UIView, context: Context) {
view.setContentHuggingPriority(.defaultHigh, for: .horizontal)
view.setContentHuggingPriority(.defaultHigh, for: .vertical)
}
}
#endif

#if canImport(SwiftUI) && DEBUG
import SwiftUI

struct UserInfoCellPreview: PreviewProvider{
static var previews: some View {
UIViewPreview {
let cell = UserInfoCell(frame: .zero)
cell.setup(with: User(uuid: UUID(), nickName: "jinwoong", profile: Data(), backgroundImage: Data(), description: ""))
return cell
}
.previewLayout(.fixed(width: 350, height: 80))
}
}
#endif