-
Notifications
You must be signed in to change notification settings - Fork 1
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
[Design] 사용자 등록 뷰 디자인 #60
Changes from all commits
1d028a5
289ca01
20894b9
088a81a
c13d518
1cc3130
f683a7a
5696fa6
28175ad
b847890
ec8e722
6ac2b56
e5f23ba
ba72a78
368b9fa
60092b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import Combine | ||
|
||
protocol ViewModelType { | ||
associatedtype Input | ||
associatedtype Output | ||
|
||
func transform(input: AnyPublisher<Input, Never>) -> AnyPublisher<Output, Never> | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,176 @@ | ||||||||
import UIKit | ||||||||
import MHFoundation | ||||||||
import Combine | ||||||||
|
||||||||
public final class RegisterViewController: UIViewController { | ||||||||
// MARK: - Property | ||||||||
private var viewModel = RegisterViewModel() | ||||||||
private let input = PassthroughSubject<RegisterViewModel.Input, Never>() | ||||||||
private var cancellables = Set<AnyCancellable>() | ||||||||
|
||||||||
// MARK: - UI Components | ||||||||
private let coverImageView: UIImageView = { | ||||||||
let backgroundImageView = UIImageView() | ||||||||
backgroundImageView.image = UIImage.pinkBook | ||||||||
|
||||||||
return backgroundImageView | ||||||||
}() | ||||||||
private let registerTextLabel: UILabel = { | ||||||||
let registerFont = UIFont.ownglyphBerry(size: 24) | ||||||||
|
||||||||
let textLabel = UILabel() | ||||||||
textLabel.text = """ | ||||||||
추억을 간직할 | ||||||||
기록소 이름을 작성해주세요 | ||||||||
""" | ||||||||
textLabel.textAlignment = .center | ||||||||
textLabel.font = registerFont | ||||||||
textLabel.numberOfLines = 2 | ||||||||
|
||||||||
return textLabel | ||||||||
}() | ||||||||
private let registerTextField: UITextField = { | ||||||||
let registerFont = UIFont.ownglyphBerry(size: 12) | ||||||||
|
||||||||
let textField = UITextField() | ||||||||
textField.font = registerFont | ||||||||
|
||||||||
var attributedText = AttributedString(stringLiteral: "기록소") | ||||||||
attributedText.font = registerFont | ||||||||
textField.attributedPlaceholder = NSAttributedString(attributedText) | ||||||||
|
||||||||
return textField | ||||||||
}() | ||||||||
private let registerButton: UIButton = { | ||||||||
let registerButton = UIButton(type: .custom) | ||||||||
|
||||||||
var attributedString = AttributedString(stringLiteral: "다음") | ||||||||
attributedString.font = UIFont.ownglyphBerry(size: 16) | ||||||||
attributedString.foregroundColor = UIColor.black | ||||||||
registerButton.setAttributedTitle(NSAttributedString(attributedString), for: .normal) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
버튼의 그림자를 주는 것보단 이런식으로 disabled일 때 글자 색을 회색? 정도로 해주면 더.. 이쁠 것 같숩니당...ㅎㅅㅎ (해당 부분 디자인을 안만들어놔서 죄송함돠..) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ㅎㅎ 수정 완! 글자가 작은 거 같아서 그것도 좀 키웠습니다. |
||||||||
|
||||||||
var disabledAttributedString = AttributedString(stringLiteral: "다음") | ||||||||
disabledAttributedString.font = UIFont.ownglyphBerry(size: 16) | ||||||||
disabledAttributedString.foregroundColor = UIColor.gray | ||||||||
registerButton.setAttributedTitle(NSAttributedString(disabledAttributedString), for: .disabled) | ||||||||
|
||||||||
registerButton.backgroundColor = .mhSection | ||||||||
registerButton.layer.borderColor = UIColor.mhBorder.cgColor | ||||||||
registerButton.layer.borderWidth = 1 | ||||||||
registerButton.layer.cornerRadius = 12 | ||||||||
|
||||||||
return registerButton | ||||||||
}() | ||||||||
|
||||||||
// MARK: - Initializer | ||||||||
public init(viewModel: RegisterViewModel) { | ||||||||
self.viewModel = viewModel | ||||||||
super.init(nibName: nil, bundle: nil) | ||||||||
} | ||||||||
|
||||||||
required init?(coder: NSCoder) { | ||||||||
self.viewModel = RegisterViewModel() | ||||||||
super.init(coder: coder) | ||||||||
} | ||||||||
|
||||||||
// MARK: - Lifecycle | ||||||||
public override func viewDidLoad() { | ||||||||
super.viewDidLoad() | ||||||||
|
||||||||
setup() | ||||||||
bind() | ||||||||
configureAddSubview() | ||||||||
configureConstraints() | ||||||||
Comment on lines
+80
to
+83
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: 꼭 그래야하는 건 아닌데 가독성 측면에서 아래 메서드 순서와 함수 호출 순서를 맞추면 좋을 것 같아요 ! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 순서 맞추는 게 좋을 것 같네요! |
||||||||
} | ||||||||
|
||||||||
private func setup() { | ||||||||
view.backgroundColor = .baseBackground | ||||||||
|
||||||||
addTouchEventToRegisterButton(registerButton) | ||||||||
addEditingChangedEventToRegisterTextField(registerTextField) | ||||||||
coverImageView.isUserInteractionEnabled = true | ||||||||
registerButton.isEnabled = false | ||||||||
} | ||||||||
|
||||||||
private func bind() { | ||||||||
let output = viewModel.transform(input: input.eraseToAnyPublisher()) | ||||||||
|
||||||||
output.sink { [weak self] event in | ||||||||
switch event { | ||||||||
case .registerButtonEnabled(let isEnabled): | ||||||||
self?.registerButton.isEnabled = isEnabled | ||||||||
case .moveToHome(let houseName): | ||||||||
let homeViewController = HomeViewController(viewModel: HomeViewModel(houseName: houseName)) | ||||||||
self?.navigationController?.pushViewController(homeViewController, animated: false) | ||||||||
self?.navigationController?.viewControllers.removeFirst() | ||||||||
} | ||||||||
}.store(in: &cancellables) | ||||||||
} | ||||||||
|
||||||||
private func configureAddSubview() { | ||||||||
view.addSubview(coverImageView) | ||||||||
view.addSubview(registerTextLabel) | ||||||||
view.addSubview(registerTextField) | ||||||||
view.addSubview(registerButton) | ||||||||
} | ||||||||
|
||||||||
private func configureConstraints() { | ||||||||
coverImageView.setCenter(view: view) | ||||||||
coverImageView.setWidth(view.frame.width - 50) | ||||||||
coverImageView.setHeight(240) | ||||||||
|
||||||||
registerTextLabel.setAnchor( | ||||||||
top: coverImageView.topAnchor, | ||||||||
leading: coverImageView.leadingAnchor, constantLeading: 80, | ||||||||
trailing: coverImageView.trailingAnchor, constantTrailing: 40, | ||||||||
height: 96 | ||||||||
) | ||||||||
|
||||||||
let registerTextFieldBackground = registerTextField.embededInDefaultBackground( | ||||||||
with: UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 5) | ||||||||
) | ||||||||
coverImageView.addSubview(registerTextFieldBackground) | ||||||||
registerTextFieldBackground.setAnchor( | ||||||||
top: registerTextLabel.bottomAnchor, | ||||||||
leading: coverImageView.leadingAnchor, constantLeading: 80, | ||||||||
trailing: coverImageView.trailingAnchor, constantTrailing: 40, | ||||||||
height: 44 | ||||||||
) | ||||||||
|
||||||||
let registerButtonBackground = UIView() | ||||||||
registerButtonBackground.backgroundColor = .mhSection | ||||||||
registerButtonBackground.layer.cornerRadius = 12 + 1 | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: 12 + 1은 무슨뜻인가요?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. registerbutton의 cornerradius가 12이고 registerbuttonbackground의 cornerradius가 12 + 1입니다. |
||||||||
registerButtonBackground.clipsToBounds = true | ||||||||
registerButtonBackground.addSubview(registerButton) | ||||||||
registerButton.setAnchor( | ||||||||
top: registerButtonBackground.topAnchor, constantTop: 3, | ||||||||
leading: registerButtonBackground.leadingAnchor, constantLeading: 4, | ||||||||
bottom: registerButtonBackground.bottomAnchor, constantBottom: 3, | ||||||||
trailing: registerButtonBackground.trailingAnchor, constantTrailing: 4 | ||||||||
) | ||||||||
|
||||||||
coverImageView.addSubview(registerButtonBackground) | ||||||||
registerButtonBackground.setAnchor( | ||||||||
top: registerTextFieldBackground.bottomAnchor, constantTop: 10, | ||||||||
leading: view.leadingAnchor, constantLeading: 260, | ||||||||
width: 60, | ||||||||
height: 36 | ||||||||
) | ||||||||
} | ||||||||
|
||||||||
private func addTouchEventToRegisterButton(_ button: UIButton) { | ||||||||
let uiAction = UIAction { [weak self] _ in | ||||||||
guard let self, let text = self.registerTextField.text else { return } | ||||||||
self.input.send(.registerButtonTapped(text: text)) | ||||||||
} | ||||||||
registerButton.addAction(uiAction, for: .touchUpInside) | ||||||||
} | ||||||||
|
||||||||
private func addEditingChangedEventToRegisterTextField(_ textfield: UITextField) { | ||||||||
let uiAction = UIAction { [weak self] _ in | ||||||||
guard let self else { return } | ||||||||
self.input.send(.registerTextFieldEdited(text: textfield.text)) | ||||||||
} | ||||||||
registerTextField.addAction(uiAction, for: .editingChanged) | ||||||||
} | ||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import MHFoundation | ||
import Combine | ||
|
||
public final class RegisterViewModel: ViewModelType { | ||
enum Input { | ||
case registerTextFieldEdited(text: String?) | ||
case registerButtonTapped(text: String) | ||
} | ||
|
||
enum Output { | ||
case registerButtonEnabled(isEnabled: Bool) | ||
case moveToHome(destination: String) | ||
} | ||
|
||
private let output = PassthroughSubject<Output, Never>() | ||
private var cancellables = Set<AnyCancellable>() | ||
|
||
public init() { } | ||
|
||
func transform(input: AnyPublisher<Input, Never>) -> AnyPublisher<Output, Never> { | ||
input.sink { [weak self] event in | ||
switch event { | ||
case .registerTextFieldEdited(let text): | ||
self?.validateTextField(text: text) | ||
case .registerButtonTapped(let text): | ||
self?.registerButtonTapped(text: text) | ||
} | ||
}.store(in: &cancellables) | ||
|
||
return output.eraseToAnyPublisher() | ||
} | ||
|
||
private func validateTextField(text: String?) { | ||
guard let text else { | ||
output.send(.registerButtonEnabled(isEnabled: false)) | ||
return | ||
} | ||
output.send(.registerButtonEnabled(isEnabled: !text.isEmpty && text.count < 11)) | ||
} | ||
|
||
private func registerButtonTapped(text: String) { | ||
UserDefaults.standard.set( | ||
text, | ||
forKey: Constant.houseNameUserDefaultKey | ||
) | ||
output.send(.moveToHome(destination: text)) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p3
private let 으로는 못 쓰나용 ??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: 생성자에서 viewmodel을 받고있는데 프로퍼티가 뷰모델 객체를 들고있는게 어색하게 느껴집니다..
이게 더 낫지 않을까요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
옹 인정합니다