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

Toast 위치 및 layout 수정 #250

Merged
merged 8 commits into from
Feb 14, 2024
4 changes: 2 additions & 2 deletions KCS/KCS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1405,7 +1405,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = 7CQAR4CYZX;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = KCS/Resource/Info.plist;
Expand Down Expand Up @@ -1444,7 +1444,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = 7CQAR4CYZX;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = KCS/Resource/Info.plist;
Expand Down
58 changes: 26 additions & 32 deletions KCS/KCS/Presentation/Extension/UIViewController+Alert.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,45 +42,39 @@ extension UIViewController {
}
}

func showToast(message: String) {
func makeToastView(message: String) -> UIStackView {
let toastImageView = UIImageView(
image: SystemImage.toast?.withTintColor(.white, renderingMode: .alwaysOriginal)
)
toastImageView.translatesAutoresizingMaskIntoConstraints = false

let toastLabel = UILabel()
toastLabel.translatesAutoresizingMaskIntoConstraints = false
toastLabel.backgroundColor = .black.withAlphaComponent(0.6)
toastLabel.backgroundColor = .clear
toastLabel.textColor = .white
toastLabel.font = .pretendard(size: 14, weight: .medium)
toastLabel.textAlignment = .center
toastLabel.font = .pretendard(size: 14, weight: .regular)
toastLabel.text = message
toastLabel.alpha = 0
toastLabel.setLayerCorner(cornerRadius: 12)
toastLabel.clipsToBounds = true
view.addSubview(toastLabel)

let toastView = UIStackView()
toastView.translatesAutoresizingMaskIntoConstraints = false
toastView.backgroundColor = .black.withAlphaComponent(0.65)
toastView.alpha = 0
toastView.setLayerCorner(cornerRadius: 20)
toastView.isLayoutMarginsRelativeArrangement = true
toastView.layoutMargins = UIEdgeInsets(top: 11, left: 15, bottom: 10, right: 13)
toastView.spacing = 8
toastView.alignment = .center
toastView.distribution = .fill

toastView.addArrangedSubview(toastImageView)
toastView.addArrangedSubview(toastLabel)

NSLayoutConstraint.activate([
toastLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
toastLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
toastLabel.widthAnchor.constraint(equalToConstant: 150),
toastLabel.heightAnchor.constraint(equalToConstant: 30)
toastImageView.widthAnchor.constraint(equalToConstant: 16),
toastImageView.heightAnchor.constraint(equalToConstant: 16)
])

UIView.animate(
withDuration: 0.4,
delay: 0,
options: .curveEaseIn,
animations: {
toastLabel.alpha = 1.0
},
completion: { _ in
UIView.animate(
withDuration: 0.8,
delay: 1.4,
options: .curveEaseOut,
animations: {
toastLabel.alpha = 0.0
}, completion: { _ in
toastLabel.removeFromSuperview()
}
)
}
)
return toastView
}

}
39 changes: 37 additions & 2 deletions KCS/KCS/Presentation/Home/View/HomeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ private extension HomeViewController {
}
storeInformationViewDismiss()
if stores.isEmpty {
showToast(message: "가게가 없습니다.")
showToast(message: "검색 결과가 존재하지 않습니다.")
storeListViewController.updateCountLabel(text: "검색 결과가 존재하지 않습니다")
storeListViewController.emptyStoreList()
} else {
Expand Down Expand Up @@ -885,7 +885,7 @@ private extension HomeViewController {
))
}
if stores.isEmpty {
showToast(message: "가게가 없습니다.")
showToast(message: "검색 결과가 존재하지 않습니다.")
storeListViewController.updateCountLabel(text: "검색 결과가 존재하지 않습니다")
storeListViewController.emptyStoreList()
} else {
Expand All @@ -894,6 +894,41 @@ private extension HomeViewController {
}
}

func showToast(message: String) {
let toastView = makeToastView(message: message)

let windows = UIApplication.shared.connectedScenes
let scene = windows.first { $0.activationState == .foregroundActive }
if let windowScene = scene as? UIWindowScene, let windowView = windowScene.windows.first {
windowView.addSubview(toastView)
NSLayoutConstraint.activate([
toastView.centerXAnchor.constraint(equalTo: windowView.safeAreaLayoutGuide.centerXAnchor),
toastView.bottomAnchor.constraint(equalTo: windowView.safeAreaLayoutGuide.bottomAnchor, constant: -61)
])
}

UIView.animate(
withDuration: 0.4,
delay: 0,
options: .curveEaseIn,
animations: {
toastView.alpha = 1.0
},
completion: { _ in
UIView.animate(
withDuration: 0.6,
delay: 2.0,
options: .curveEaseOut,
animations: {
toastView.alpha = 0.0
}, completion: { _ in
toastView.removeFromSuperview()
}
)
}
)
}

}

extension HomeViewController: CLLocationManagerDelegate {
Expand Down
46 changes: 43 additions & 3 deletions KCS/KCS/Presentation/Search/View/SearchViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,7 @@ final class SearchViewController: UIViewController {
.tapGesture()
.when(.ended)
.subscribe(onNext: { [weak self] _ in
if let text = view.searchTextField.text {
self?.search(text: text)
}
view.searchTextField.becomeFirstResponder()
})
.disposed(by: disposeBag)

Expand Down Expand Up @@ -284,6 +282,12 @@ private extension SearchViewController {
}
.disposed(by: disposeBag)

viewModel.noKeywordToastOutput
.bind { [weak self] _ in
self?.showToast(message: "검색어를 입력하세요.")
}
.disposed(by: disposeBag)

RxKeyboard.instance.visibleHeight
.asObservable()
.bind { [weak self] keyboardHeight in
Expand Down Expand Up @@ -316,6 +320,42 @@ private extension SearchViewController {
searchObserver.accept(text)
viewModel.action(input: .searchButtonTapped(text: text))
}

func showToast(message: String) {
let toastView = makeToastView(message: message)

view.addSubview(toastView)
NSLayoutConstraint.activate([
toastView.centerXAnchor.constraint(
equalTo: view.safeAreaLayoutGuide.centerXAnchor
),
toastView.bottomAnchor.constraint(
equalTo: view.bottomAnchor,
constant: -view.frame.maxY + recentHistoryTableView.frame.maxY - 24
)
])

UIView.animate(
withDuration: 0.4,
delay: 0,
options: .curveEaseIn,
animations: {
toastView.alpha = 1.0
},
completion: { _ in
UIView.animate(
withDuration: 0.6,
delay: 2.0,
options: .curveEaseOut,
animations: {
toastView.alpha = 0.0
}, completion: { _ in
toastView.removeFromSuperview()
}
)
}
)
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ protocol SearchViewModelOutput {
var recentSearchKeywordsOutput: PublishRelay<[String]> { get }
var autoCompleteKeywordsOutput: PublishRelay<[String]> { get }
var searchOutput: PublishRelay<String> { get }
var noKeywordToastOutput: PublishRelay<Void> { get }

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ final class SearchViewModelImpl: SearchViewModel {
let recentSearchKeywordsOutput = PublishRelay<[String]>()
let autoCompleteKeywordsOutput = PublishRelay<[String]>()
let searchOutput = PublishRelay<String>()
var noKeywordToastOutput = PublishRelay<Void>()

init(
fetchRecentSearchKeywordUseCase: FetchRecentSearchKeywordUseCase,
Expand Down Expand Up @@ -57,7 +58,7 @@ private extension SearchViewModelImpl {
emitRecentHistory()
} else {
// TODO: autoCompletion usecase 실행(debounce) 후 generateDataOutput.accept([]) (자동완성으로 전환)
autoCompleteKeywordsOutput.accept([text])
emitRecentHistory()
}
}

Expand Down Expand Up @@ -88,6 +89,8 @@ private extension SearchViewModelImpl {
func returnKeyTapped(text: String) {
if !text.trimmingCharacters(in: .whitespaces).isEmpty {
searchOutput.accept(text)
} else {
noKeywordToastOutput.accept(())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ final class StoreListViewController: UIViewController {
}()

private let emptyListImageView: UIImageView = {
let imageView = UIImageView(image: SystemImage.exclamationmark)
let imageView = UIImageView(image: SystemImage.toast)
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.tintColor = .placeholderText

Expand Down
2 changes: 1 addition & 1 deletion KCS/KCS/Util/SystemImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ enum SystemImage {
static let refresh = UIImage(systemName: "arrow.clockwise")
static let remove = UIImage(systemName: "xmark.circle.fill")
static let search = UIImage(systemName: "magnifyingglass")
static let exclamationmark = UIImage(systemName: "exclamationmark.circle")
static let toast = UIImage(systemName: "exclamationmark.circle")

}