diff --git a/iBox/Sources/BoxList/AddBookmark/AddBookmarkView.swift b/iBox/Sources/BoxList/AddBookmark/AddBookmarkView.swift index 9bc6fd1..aaafe67 100644 --- a/iBox/Sources/BoxList/AddBookmark/AddBookmarkView.swift +++ b/iBox/Sources/BoxList/AddBookmark/AddBookmarkView.swift @@ -181,7 +181,6 @@ class AddBookmarkView: UIView { selectedFolderLabel.snp.makeConstraints { make in make.trailing.equalTo(chevronImageView.snp.leading).offset(-10) make.centerY.equalTo(button.snp.centerY) - make.width.equalTo(100) make.height.equalTo(40) } diff --git a/iBox/Sources/BoxList/AddBookmark/AddBookmarkViewController.swift b/iBox/Sources/BoxList/AddBookmark/AddBookmarkViewController.swift index 07e46bb..4199e98 100644 --- a/iBox/Sources/BoxList/AddBookmark/AddBookmarkViewController.swift +++ b/iBox/Sources/BoxList/AddBookmark/AddBookmarkViewController.swift @@ -7,26 +7,30 @@ import UIKit +protocol AddBookmarkViewControllerProtocol: AnyObject { + func addFolderDirect(_ folder: Folder) + func addBookmarkDirect(_ bookmark: Bookmark, at folderIndex: Int) +} + final class AddBookmarkViewController: UIViewController { + weak var delegate: AddBookmarkViewControllerProtocol? + var haveValidInput = false var selectedFolder: Folder? - private let coreDataManager = CoreDataManager.shared + var selectedFolderIndex: Int? + var folders = [Folder]() + private let addBookmarkView = AddBookmarkView() - override func loadView() { super.loadView() setupAddBookmarkView() } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - updateSelectedFolder() - } override func viewDidLoad() { super.viewDidLoad() setupNavigationBar() + updateSelectedFolder() } private func setupNavigationBar() { @@ -57,19 +61,39 @@ final class AddBookmarkViewController: UIViewController { self?.openFolderSelection() } addBookmarkView.onTextChange = { [weak self] isEnabled in - self?.navigationItem.rightBarButtonItem?.isEnabled = isEnabled + self?.haveValidInput = isEnabled + + if let haveValidInput = self?.haveValidInput, + haveValidInput, + let _ = self?.selectedFolder { + self?.navigationItem.rightBarButtonItem?.isEnabled = true + } else { + self?.navigationItem.rightBarButtonItem?.isEnabled = false + } } view = addBookmarkView } private func updateSelectedFolder() { - selectedFolder = UserDefaultsManager.selectedFolder + let selectedFolderId = UserDefaultsManager.selectedFolderId - if selectedFolder?.name == "" { - selectedFolder = CoreDataManager.shared.getFolders().first + for (index, folder) in folders.enumerated() { + if folder.id == selectedFolderId { + selectedFolder = folder + selectedFolderIndex = index + } } - addBookmarkView.selectedFolderName = selectedFolder?.name + if selectedFolder == nil && !folders.isEmpty { + selectedFolder = folders[0] + selectedFolderIndex = 0 + } + + if let selectedFolder { + addBookmarkView.selectedFolderName = selectedFolder.name + } else { + addBookmarkView.selectedFolderName = "선택된 폴더가 없습니다." + } } @objc private func cancelButtonTapped() { @@ -105,9 +129,10 @@ final class AddBookmarkViewController: UIViewController { let newBookmark = Bookmark(id: UUID(), name: name, url: url) - if let selectedFolder = selectedFolder { - coreDataManager.addBookmark(newBookmark, folderId: selectedFolder.id) - print("북마크 저장 완료: \(newBookmark.name)") + if let selectedFolder = selectedFolder, + let selectedFolderIndex = selectedFolderIndex { + CoreDataManager.shared.addBookmark(newBookmark, folderId: selectedFolder.id) + delegate?.addBookmarkDirect(newBookmark, at: selectedFolderIndex) } else { print("선택된 폴더가 없습니다.") } @@ -116,57 +141,29 @@ final class AddBookmarkViewController: UIViewController { } private func openFolderSelection() { - let folderListViewController = FolderListViewController() + let folderListViewController = FolderListViewController(folders: folders, selectedId: selectedFolder?.id) folderListViewController.title = "목록" - - let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addFolderAction)) - folderListViewController.navigationItem.rightBarButtonItem = addButton + folderListViewController.delegate = self navigationController?.pushViewController(folderListViewController, animated: true) } - @objc func addFolderAction() { - let controller = UIAlertController(title: "새로운 폴더", message: "이 폴더의 이름을 입력하십시오.", preferredStyle: .alert) - - controller.addTextField { textField in - textField.placeholder = "폴더 이름" - textField.autocorrectionType = .no - textField.spellCheckingType = .no - } - - let cancelAction = UIAlertAction(title: "취소", style: .cancel, handler: nil) - let addAction = UIAlertAction(title: "추가", style: .default) { [unowned controller, weak self] _ in - guard let textField = controller.textFields?.first, - let folderName = textField.text, !folderName.trimmingCharacters(in: .whitespaces).isEmpty else { - return - } - - let newFolder = Folder(id: UUID(), name: folderName, bookmarks: []) - self?.coreDataManager.addFolder(newFolder) - - self?.updateFolderList() - } - - controller.addAction(cancelAction) - controller.addAction(addAction) +} + +extension AddBookmarkViewController: FolderListViewControllerDelegate { + func addFolder(_ folder: Folder) { + delegate?.addFolderDirect(folder) + } + + func selectFolder(_ folder: Folder, at index: Int) { + selectedFolder = folder + selectedFolderIndex = index - NotificationCenter.default.addObserver(forName: UITextField.textDidChangeNotification, object: controller.textFields?.first, queue: .main) { notification in - if let textField = notification.object as? UITextField, - let text = textField.text, !text.trimmingCharacters(in: .whitespaces).isEmpty { - addAction.isEnabled = true - } else { - addAction.isEnabled = false - } + if haveValidInput { + navigationItem.rightBarButtonItem?.isEnabled = true } - addAction.isEnabled = false - - present(controller, animated: true) - } - - func updateFolderList() { - if let folderListVC = navigationController?.viewControllers.first(where: { $0 is FolderListViewController }) as? FolderListViewController { - folderListVC.folderListView.reloadFolderList() - } + addBookmarkView.selectedFolderName = selectedFolder?.name } + } diff --git a/iBox/Sources/BoxList/AddBookmark/FolderListView.swift b/iBox/Sources/BoxList/AddBookmark/FolderListView.swift index 9bc0aad..77edf93 100644 --- a/iBox/Sources/BoxList/AddBookmark/FolderListView.swift +++ b/iBox/Sources/BoxList/AddBookmark/FolderListView.swift @@ -7,11 +7,16 @@ import UIKit +protocol FolderListViewDelegate: AnyObject { + func selectFolder(_ folder: Folder, at index: Int) +} + class FolderListView: UIView { + weak var delegate: FolderListViewDelegate? let coreDataManager = CoreDataManager.shared var folders: [Folder] = [] - var onFolderSelected: ((Folder) -> Void)? + var selectedFolderId: UUID? // MARK: - UI Components @@ -24,10 +29,9 @@ class FolderListView: UIView { private let tableView = UITableView().then { $0.backgroundColor = .clear - $0.translatesAutoresizingMaskIntoConstraints = false } - private lazy var stackView = UIStackView(arrangedSubviews: [infoLabel, tableView]).then { + private let stackView = UIStackView().then { $0.axis = .vertical $0.spacing = 20 } @@ -63,18 +67,18 @@ class FolderListView: UIView { make.leading.equalTo(self.snp.leading) make.trailing.equalTo(self.snp.trailing) } + + stackView.addArrangedSubview(infoLabel) + stackView.addArrangedSubview(tableView) } func setupTableView() { self.tableView.dataSource = self self.tableView.delegate = self self.tableView.register(FolderListCell.self, forCellReuseIdentifier: FolderListCell.reuseIdentifier) - - folders = coreDataManager.getFolders() } func reloadFolderList() { - folders = coreDataManager.getFolders() tableView.reloadData() } } @@ -88,7 +92,7 @@ extension FolderListView: UITableViewDataSource { let cell = tableView.dequeueReusableCell(withIdentifier: FolderListCell.reuseIdentifier, for: indexPath) as! FolderListCell let folder = folders[indexPath.row] - let isSelectedFolder = UserDefaultsManager.selectedFolder.id == folder.id + let isSelectedFolder = selectedFolderId == folder.id cell.configureWith(folder: folder, isSelected: isSelectedFolder) return cell @@ -98,6 +102,7 @@ extension FolderListView: UITableViewDataSource { extension FolderListView: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let selectedFolder = folders[indexPath.row] - onFolderSelected?(selectedFolder) + UserDefaultsManager.selectedFolderId = selectedFolder.id + delegate?.selectFolder(selectedFolder, at: indexPath.row) } } diff --git a/iBox/Sources/BoxList/AddBookmark/FolderListViewController.swift b/iBox/Sources/BoxList/AddBookmark/FolderListViewController.swift index bbccafa..3fd25c3 100644 --- a/iBox/Sources/BoxList/AddBookmark/FolderListViewController.swift +++ b/iBox/Sources/BoxList/AddBookmark/FolderListViewController.swift @@ -7,8 +7,24 @@ import UIKit +protocol FolderListViewControllerDelegate: AnyObject { + func selectFolder(_ folder: Folder, at index: Int) + func addFolder(_ folder: Folder) +} + class FolderListViewController: UIViewController { + weak var delegate: FolderListViewControllerDelegate? + let folderListView = FolderListView() + + init(folders: [Folder], selectedId: UUID?) { + super.init(nibName: nil, bundle: nil) + setupFolderListView(folders, selectedId: selectedId) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } override func loadView() { view = folderListView @@ -17,16 +33,63 @@ class FolderListViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - folderListView.onFolderSelected = { [weak self] folder in - - guard let self = self else { return } + setupNavigationBar() + } + + private func setupNavigationBar() { + let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addFolder)) + navigationItem.rightBarButtonItem = addButton + } + + @objc private func addFolder() { + let controller = UIAlertController(title: "새로운 폴더", message: "이 폴더의 이름을 입력하십시오.", preferredStyle: .alert) + + controller.addTextField { textField in + textField.placeholder = "폴더 이름" + textField.autocorrectionType = .no + textField.spellCheckingType = .no + } + + let cancelAction = UIAlertAction(title: "취소", style: .cancel, handler: nil) + let addAction = UIAlertAction(title: "추가", style: .default) { [unowned controller, weak self] _ in + guard let textField = controller.textFields?.first, + let folderName = textField.text, !folderName.trimmingCharacters(in: .whitespaces).isEmpty else { return } - if let addBookmarkVC = self.navigationController?.viewControllers.first as? AddBookmarkViewController { - addBookmarkVC.selectedFolder = folder - UserDefaultsManager.selectedFolder = folder - - self.navigationController?.popViewController(animated: true) + let newFolder = Folder(id: UUID(), name: folderName, bookmarks: []) + CoreDataManager.shared.addFolder(newFolder) + self?.folderListView.folders.append(newFolder) + self?.folderListView.reloadFolderList() + self?.delegate?.addFolder(newFolder) + } + + controller.addAction(cancelAction) + controller.addAction(addAction) + + NotificationCenter.default.addObserver(forName: UITextField.textDidChangeNotification, object: controller.textFields?.first, queue: .main) { notification in + if let textField = notification.object as? UITextField, + let text = textField.text, !text.trimmingCharacters(in: .whitespaces).isEmpty { + addAction.isEnabled = true + } else { + addAction.isEnabled = false } } + + addAction.isEnabled = false + + present(controller, animated: true) + } + + private func setupFolderListView(_ folders: [Folder], selectedId: UUID?) { + folderListView.delegate = self + folderListView.folders = folders + folderListView.selectedFolderId = selectedId + } +} + +extension FolderListViewController: FolderListViewDelegate { + func selectFolder(_ folder: Folder, at index: Int) { + delegate?.selectFolder(folder, at: index) + self.navigationController?.popViewController(animated: true) } + } diff --git a/iBox/Sources/BoxList/BoxListViewController.swift b/iBox/Sources/BoxList/BoxListViewController.swift index 46c5376..04f3506 100644 --- a/iBox/Sources/BoxList/BoxListViewController.swift +++ b/iBox/Sources/BoxList/BoxListViewController.swift @@ -51,7 +51,12 @@ class BoxListViewController: BaseViewController, BaseViewController // MARK: - Action Functions @objc private func addButtonTapped() { + guard let contentView = contentView as? BoxListView else { return } + let addBookmarkViewController = AddBookmarkViewController() + addBookmarkViewController.delegate = self + addBookmarkViewController.folders = contentView.viewModel?.folders ?? [] + let navigationController = UINavigationController(rootViewController: addBookmarkViewController) navigationController.modalPresentationStyle = .pageSheet @@ -73,6 +78,19 @@ class BoxListViewController: BaseViewController, BaseViewController } +extension BoxListViewController: AddBookmarkViewControllerProtocol { + func addFolderDirect(_ folder: Folder) { + guard let contentView = contentView as? BoxListView else { return } + contentView.viewModel?.addFolderDirect(folder) + } + + func addBookmarkDirect(_ bookmark: Bookmark, at folderIndex: Int) { + guard let contentView = contentView as? BoxListView else { return } + contentView.viewModel?.addBookmarkDirect(bookmark, at: folderIndex) + } + +} + extension BoxListViewController: BoxListViewDelegate { func presentEditBookmarkController(at indexPath: IndexPath) { guard let contentView = contentView as? BoxListView else { return } diff --git a/iBox/Sources/BoxList/BoxListViewModel.swift b/iBox/Sources/BoxList/BoxListViewModel.swift index fd7a820..f341d7e 100644 --- a/iBox/Sources/BoxList/BoxListViewModel.swift +++ b/iBox/Sources/BoxList/BoxListViewModel.swift @@ -161,5 +161,16 @@ class BoxListViewModel { let mover = boxList.remove(at: from) boxList.insert(mover, at: to) } + + func addFolderDirect(_ folder: Folder) { + let boxListSectionViewModel = BoxListSectionViewModel(folder: folder) + boxList.append(boxListSectionViewModel) + output.send(.sendBoxList(boxList: boxList)) + } + + func addBookmarkDirect(_ bookmark: Bookmark, at index: Int) { + boxList[index].boxListCellViewModels.append(BoxListCellViewModel(bookmark: bookmark)) + output.send(.sendBoxList(boxList: boxList)) + } } diff --git a/iBox/Sources/Shared/UserDefaultsManager.swift b/iBox/Sources/Shared/UserDefaultsManager.swift index a66b7e3..e8de7dc 100644 --- a/iBox/Sources/Shared/UserDefaultsManager.swift +++ b/iBox/Sources/Shared/UserDefaultsManager.swift @@ -24,8 +24,8 @@ final class UserDefaultsManager { @UserDefaultsData(key: "isPreload", defaultValue: false) static var isPreload: Bool - @UserDefaultsData(key: "selectedFolder", defaultValue: Folder(id: UUID(), name: "", bookmarks: [])) - static var selectedFolder: Folder + @UserDefaultsData(key: "selectedFolderId", defaultValue: nil) + static var selectedFolderId: UUID? }