Skip to content
Open
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
Binary file modified .DS_Store
Binary file not shown.
16 changes: 15 additions & 1 deletion CombineStudy.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
213B87742BECD2290071BD65 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 213B87732BECD2290071BD65 /* SnapKit */; };
213B87772BECD2320071BD65 /* Then in Frameworks */ = {isa = PBXBuildFile; productRef = 213B87762BECD2320071BD65 /* Then */; };
213B877A2BECD4520071BD65 /* CombineCocoa in Frameworks */ = {isa = PBXBuildFile; productRef = 213B87792BECD4520071BD65 /* CombineCocoa */; };
219964272C08ECCA00EDD523 /* CreateNickNameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 219964252C08ECCA00EDD523 /* CreateNickNameView.swift */; };
219964282C08ECCA00EDD523 /* CreateNickNameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 219964262C08ECCA00EDD523 /* CreateNickNameViewController.swift */; };
2199642A2C08EDFC00EDD523 /* CreateNickNameViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 219964292C08EDFC00EDD523 /* CreateNickNameViewModel.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -35,6 +38,9 @@
213B876C2BECD2060071BD65 /* LoginView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; };
213B876D2BECD2060071BD65 /* LoginViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginViewModel.swift; sourceTree = "<group>"; };
213B876E2BECD2060071BD65 /* LoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = "<group>"; };
219964252C08ECCA00EDD523 /* CreateNickNameView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateNickNameView.swift; sourceTree = "<group>"; };
219964262C08ECCA00EDD523 /* CreateNickNameViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateNickNameViewController.swift; sourceTree = "<group>"; };
219964292C08EDFC00EDD523 /* CreateNickNameViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateNickNameViewModel.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -75,6 +81,9 @@
213B876C2BECD2060071BD65 /* LoginView.swift */,
213B876E2BECD2060071BD65 /* LoginViewController.swift */,
213B876D2BECD2060071BD65 /* LoginViewModel.swift */,
219964252C08ECCA00EDD523 /* CreateNickNameView.swift */,
219964262C08ECCA00EDD523 /* CreateNickNameViewController.swift */,
219964292C08EDFC00EDD523 /* CreateNickNameViewModel.swift */,
213B87612BECD1F60071BD65 /* Extensions */,
213B87562BECD1900071BD65 /* Assets.xcassets */,
213B87582BECD1900071BD65 /* LaunchScreen.storyboard */,
Expand Down Expand Up @@ -126,7 +135,7 @@
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1430;
LastUpgradeCheck = 1430;
LastUpgradeCheck = 1540;
TargetAttributes = {
213B87492BECD18E0071BD65 = {
CreatedOnToolsVersion = 14.3.1;
Expand Down Expand Up @@ -174,11 +183,14 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
219964282C08ECCA00EDD523 /* CreateNickNameViewController.swift in Sources */,
213B876F2BECD2060071BD65 /* LoginView.swift in Sources */,
213B87692BECD1F60071BD65 /* UITextField+Extension.swift in Sources */,
213B87682BECD1F60071BD65 /* UIView+Extension.swift in Sources */,
213B87672BECD1F60071BD65 /* UIButton+Extension.swift in Sources */,
219964272C08ECCA00EDD523 /* CreateNickNameView.swift in Sources */,
213B87712BECD2060071BD65 /* LoginViewController.swift in Sources */,
2199642A2C08EDFC00EDD523 /* CreateNickNameViewModel.swift in Sources */,
213B876B2BECD1F60071BD65 /* AppDelegate.swift in Sources */,
213B876A2BECD1F60071BD65 /* SceneDelegate.swift in Sources */,
213B87702BECD2060071BD65 /* LoginViewModel.swift in Sources */,
Expand Down Expand Up @@ -235,6 +247,7 @@
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
Expand Down Expand Up @@ -295,6 +308,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
Expand Down
Binary file not shown.
79 changes: 79 additions & 0 deletions CombineStudy/CreateNickNameView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//
// CreateNickNameView.swift
// 2nd assignment
//
// Created by 왕정빈 on 2024/04/09.
//

import UIKit
import Then
import SnapKit

class CreateNickNameView: UIView {

private let titleLabel = UILabel()
let nickNameTextField = UITextField()
lazy var saveButton = UIButton()

override init(frame: CGRect) {
super.init(frame: frame)

backgroundColor = .white
setUI()
setLayout()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: - set UI components attribute
private func setUI() {
[titleLabel, nickNameTextField, saveButton]
.forEach { addSubview($0) }

titleLabel.do {
$0.text = "닉네임을 입력해주세요"
$0.textColor = .black
$0.font = .boldSystemFont(ofSize: 20)
$0.textAlignment = .left
}

nickNameTextField.do {
$0.backgroundColor = .lightGray
$0.textColor = .black
$0.layer.cornerRadius = 3
$0.addPadding(left: 12, right: 12)
}

saveButton.do {
$0.setTitle("저장하기", for: .normal)
$0.setTitleColor(.lightGray, for: .normal)
$0.backgroundColor = .white
$0.layer.borderColor = UIColor.black.cgColor
$0.layer.borderWidth = 0.5
$0.layer.cornerRadius = 15
$0.isEnabled = false
}
}

// MARK: - set UI layout
private func setLayout() {
titleLabel.snp.makeConstraints {
$0.top.equalToSuperview().offset(50)
$0.leading.trailing.equalToSuperview().inset(20)
}

nickNameTextField.snp.makeConstraints {
$0.top.equalTo(titleLabel.snp.bottom).offset(20)
$0.leading.trailing.equalToSuperview().inset(20)
$0.height.equalTo(52)
}

saveButton.snp.makeConstraints {
$0.leading.trailing.equalToSuperview().inset(20)
$0.bottom.equalToSuperview().offset(-50)
$0.height.equalTo(52)
}
}
}
78 changes: 78 additions & 0 deletions CombineStudy/CreateNickNameViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//
// CreateNickNameView.swift
// 2nd assignment
//
// Created by 왕정빈 on 2024/04/09.
//

import UIKit


class CreateNickNameViewController: UIViewController {

// MARK: - properties
private let createNickNameView = CreateNickNameView()
private let viewModel: CreateNickNameViewModel?

var dataBind: ((String) -> Void)?

// MARK: - initialize

init(viewModel: CreateNickNameViewModel?) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func viewDidLoad() {
super.viewDidLoad()

setSaveButton()
setInitialSetting()
}

override func loadView() {
view = createNickNameView
}

// MARK: - set Initial Setting
private func setInitialSetting() {
view.roundCorners(cornerRadius: 15, maskedCorners: [.layerMinXMinYCorner, .layerMaxXMinYCorner])

createNickNameView.nickNameTextField.delegate = self
}

// MARK: - set SaveButton setting
private func setSaveButton() {
let saveButton = createNickNameView.saveButton
saveButton.addTarget(self, action: #selector(tappedSaveButton), for: .touchUpInside)
}

@objc private func tappedSaveButton() {
let nickName = createNickNameView.nickNameTextField.text!
// dataBind?(nickName)
viewModel?.setNickName(nickName)
dismiss(animated: true)
}

private func setButtonAttribute(button: UIButton, isEnabled: Bool, backgroundColor: UIColor?, titleColor: UIColor) {
button.isEnabled = isEnabled
button.backgroundColor = backgroundColor
button.setTitleColor(titleColor, for: .normal)
}
}

extension CreateNickNameViewController: UITextFieldDelegate {
func textFieldDidChangeSelection(_ textField: UITextField) {
let nickName = createNickNameView.nickNameTextField.text ?? ""
let isEnabled = !nickName.isEmpty

setButtonAttribute(button: createNickNameView.saveButton,
isEnabled: isEnabled,
backgroundColor: isEnabled ? .red : .white,
titleColor: isEnabled ? .white : .lightGray)
}
}
18 changes: 18 additions & 0 deletions CombineStudy/CreateNickNameViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// CreateNickNameViewModel.swift
// CombineStudy
//
// Created by 왕정빈 on 5/31/24.
//

import Foundation
import Combine

final class CreateNickNameViewModel {

let nickNameSubject = PassthroughSubject<String, Never>()

func setNickName(_ nickName: String) {
nickNameSubject.send(nickName)
}
}
14 changes: 13 additions & 1 deletion CombineStudy/LoginView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class LoginView: UIView {
private let forResizeView = UIView()
private let findStackView = UIStackView()
private let createAccountStackView = UIStackView()
let combineLabel = UILabel()

// MARK: - initialize
override init(frame: CGRect) {
Expand All @@ -52,7 +53,7 @@ class LoginView: UIView {
[createAccountSubsLabel, createNickNameButton]
.forEach { createAccountStackView.addArrangedSubview($0) }

[titleLabel, idTextField, passwordField, clearTextButtonForID, clearTextButtonForPW, passwordEyeButton, loginButton, warningMessage, findStackView, createAccountStackView]
[titleLabel, idTextField, passwordField, clearTextButtonForID, clearTextButtonForPW, passwordEyeButton, loginButton, warningMessage, findStackView, createAccountStackView, combineLabel]
.forEach { addSubview($0) }

titleLabel.do {
Expand Down Expand Up @@ -154,6 +155,12 @@ class LoginView: UIView {
forResizeView.do { $0.backgroundColor = .none }

borderLine.do { $0.backgroundColor = .darkGray }

combineLabel.do {
$0.text = "dsafsdfasd"
$0.textColor = .white
$0.font = .boldSystemFont(ofSize: 20)
}
}

// MARK: - set components layout
Expand Down Expand Up @@ -216,6 +223,11 @@ class LoginView: UIView {
$0.top.equalTo(findStackView.snp.bottom).offset(30)
$0.leading.trailing.equalToSuperview().inset(45)
}

combineLabel.snp.makeConstraints {
$0.top.equalTo(createAccountStackView.snp.bottom).offset(50)
$0.centerX.equalToSuperview()
}
}
}

36 changes: 36 additions & 0 deletions CombineStudy/LoginViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class LoginViewController: UIViewController {
let loginView = LoginView()
let viewModel = LoginViewModel()
private var subsscriptions = Set<AnyCancellable>()
let nickNameViewModel = CreateNickNameViewModel()

var nickName: String?

Expand All @@ -23,6 +24,7 @@ class LoginViewController: UIViewController {
setDelegate()
setAdditionalTextFieldSetting()
setLoginButton()
createNickName()

loginView.idTextField.textPublisher
.receive(on: RunLoop.main)
Expand All @@ -35,6 +37,14 @@ class LoginViewController: UIViewController {
print(isMatched ? "유효한 이메일 형식입니다." : "유효하지 않은 이메일 형식입니다.")
}
.store(in: &subsscriptions)

nickNameViewModel.nickNameSubject
.receive(on: RunLoop.main)
.sink { [weak self] nickName in
guard let self else { return }
self.loginView.combineLabel.text = nickName
}
.store(in: &subsscriptions)
}

override func loadView() {
Expand Down Expand Up @@ -67,6 +77,32 @@ class LoginViewController: UIViewController {
button.setTitleColor(titleColor, for: .normal)
}

// MARK: - set createNickName
private func createNickName() {
loginView.createNickNameButton.addTarget(self, action: #selector(showModalView), for: .touchUpInside)
}

@objc private func showModalView() {
let createNickNameVC = CreateNickNameViewController(viewModel: nickNameViewModel)

if let sheet = createNickNameVC.sheetPresentationController {
sheet.detents = [.medium(), .large()]
}

createNickNameVC.dataBind = { [weak self] nickName in
guard let self = self else { return }
self.nickName = nickName
}

self.present(createNickNameVC, animated: true)
}

private func toMakeNickNameAlert() {
let alert = UIAlertController(title: nil, message: "닉네임을 생성하세요", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "확인", style: .default))
self.present(alert, animated: true)
}

// MARK: - additional setting
private func setDelegate() {
loginView.idTextField.delegate = self
Expand Down