Skip to content

Commit

Permalink
Merge pull request #250 from Korea-Certified-Store/feature/toast-layout(
Browse files Browse the repository at this point in the history
#247)

Toast 위치 및 layout 수정
  • Loading branch information
SungMinCho-Kor authored Feb 14, 2024
2 parents bacd9b4 + 6525630 commit 2f14685
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 42 deletions.
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")

}

0 comments on commit 2f14685

Please sign in to comment.