diff --git a/src/Projects/BKDesign/Sources/Components/BKLoading/BKLoadingIndicator.swift b/src/Projects/BKDesign/Sources/Components/BKLoading/BKLoadingIndicator.swift index b67813e2..eb05c667 100644 --- a/src/Projects/BKDesign/Sources/Components/BKLoading/BKLoadingIndicator.swift +++ b/src/Projects/BKDesign/Sources/Components/BKLoading/BKLoadingIndicator.swift @@ -1,37 +1,48 @@ // Copyright © 2025 Booket. All rights reserved -import UIKit import SnapKit +import UIKit public final class LoadingIndicator { private static let tag = 999999 + private static var delayedWorkItem: DispatchWorkItem? /// 로딩 인디케이터 보여주기 - public static func show() { + public static func show( + delay: TimeInterval = 0.5 + ) { DispatchQueue.main.async { - guard let window = getKeyWindow() else { return } - - if window.viewWithTag(tag) != nil { - return + guard delayedWorkItem == nil else { return } + + let workItem = DispatchWorkItem { + defer { delayedWorkItem = nil } + guard Self.delayedWorkItem?.isCancelled != true else { return } + guard let window = getKeyWindow() else { return } + guard window.viewWithTag(tag) == nil else { return } + + let loadingIndicatorView = createLoadingView(frame: window.bounds) + loadingIndicatorView.tag = tag + window.addSubview(loadingIndicatorView) + loadingIndicatorView.startAnimating() } - - let loadingIndicatorView = createLoadingView(frame: window.bounds) - loadingIndicatorView.tag = tag - - window.addSubview(loadingIndicatorView) - loadingIndicatorView.startAnimating() + + delayedWorkItem = workItem + DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: workItem) } } /// 로딩 인디케이터 숨기기 public static func hide() { DispatchQueue.main.async { + delayedWorkItem?.cancel() + delayedWorkItem = nil + guard let window = getKeyWindow() else { return } - window.subviews.filter({ $0.tag == tag }).forEach { - $0.removeFromSuperview() - } + window.subviews + .filter{ $0.tag == tag } + .forEach { $0.removeFromSuperview() } } } diff --git a/src/Projects/BKPresentation/Sources/MainFlow/NoteCompletion/View/NoteCompletionViewController.swift b/src/Projects/BKPresentation/Sources/MainFlow/NoteCompletion/View/NoteCompletionViewController.swift index 5a58ef39..9d1cbc9d 100644 --- a/src/Projects/BKPresentation/Sources/MainFlow/NoteCompletion/View/NoteCompletionViewController.swift +++ b/src/Projects/BKPresentation/Sources/MainFlow/NoteCompletion/View/NoteCompletionViewController.swift @@ -60,7 +60,6 @@ final class NoteCompletionViewController: BaseViewController } .store(in: &cancellable) - viewModel.statePublisher .map { $0.isLoading } .removeDuplicates() @@ -77,18 +76,8 @@ final class NoteCompletionViewController: BaseViewController viewModel.statePublisher .receive(on: DispatchQueue.main) .compactMap { $0.error } - .sink { [weak self] error in - // 에러 알림 표시 -> BKStyle로 교체 필요 - let alert = UIAlertController( - title: "오류", - message: "기록을 불러올 수 없습니다.", - preferredStyle: .alert - ) - alert.addAction(UIAlertAction(title: "확인", style: .default) { _ in - self?.viewModel.send(.errorHandled) - self?.dismiss(animated: true) - }) - self?.present(alert, animated: true) + .sink { [weak self] _ in + self?.presentErrorDialog() } .store(in: &cancellable) @@ -175,6 +164,22 @@ final class NoteCompletionViewController: BaseViewController present(dialogViewController, animated: true) } + func presentErrorDialog() { + let dialog = BKDialog( + title: "오류", + config: .init( + leftButtonTitle: "기록을 불러올 수 없습니다.", + leftButtonAction: { [weak self] in + self?.dismiss(animated: true) { [weak self] in + self?.viewModel.send(.errorHandled) + } + } + ) + ) + let dialogViewController = BKDialogViewController(dialog: dialog) + self.present(dialogViewController, animated: true) + } + @objc private func customBackButtonTapped() { dismiss(animated: true) }