diff --git a/MLS/MLS.xcodeproj/project.pbxproj b/MLS/MLS.xcodeproj/project.pbxproj
index 4f150d4e..3ad0da22 100644
--- a/MLS/MLS.xcodeproj/project.pbxproj
+++ b/MLS/MLS.xcodeproj/project.pbxproj
@@ -51,6 +51,7 @@
779A490E2E1AD26700ABDE4F /* BookmarkFeature.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 779A490C2E1AD26700ABDE4F /* BookmarkFeature.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
779A49102E1AD26D00ABDE4F /* BookmarkFeatureInterface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 779A490F2E1AD26D00ABDE4F /* BookmarkFeatureInterface.framework */; };
779A49112E1AD26D00ABDE4F /* BookmarkFeatureInterface.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 779A490F2E1AD26D00ABDE4F /* BookmarkFeatureInterface.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 77B1F9952EE06A4E00AE4B4D /* RxGesture in Frameworks */ = {isa = PBXBuildFile; productRef = 77B1F9942EE06A4E00AE4B4D /* RxGesture */; };
77EB18D62DED9256004FB380 /* AuthFeature.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77EB18D52DED9256004FB380 /* AuthFeature.framework */; };
77EB18D72DED9256004FB380 /* AuthFeature.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 77EB18D52DED9256004FB380 /* AuthFeature.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
@@ -166,6 +167,7 @@
08ED492C2DCFDED4002C21A2 /* RxSwift in Frameworks */,
7721A5042E0EE7AE00A7B58C /* BaseFeature.framework in Frameworks */,
08DA58AA2E1E5BEB009097A6 /* DictionaryFeatureInterface.framework in Frameworks */,
+ 77B1F9952EE06A4E00AE4B4D /* RxGesture in Frameworks */,
7721A5082E0EE7F100A7B58C /* ReactorKit in Frameworks */,
0801759F2DCD27E600D0919F /* DomainInterface.framework in Frameworks */,
7777F7022E9EAB8400F53D68 /* BookmarkFeature.framework in Frameworks */,
@@ -323,6 +325,7 @@
08DA51B32E1B9827009097A6 /* FirebaseFirestore */,
08DA51B52E1B9827009097A6 /* FirebaseMessaging */,
770ADB1E2E433EDA00270506 /* RxKeyboard */,
+ 77B1F9942EE06A4E00AE4B4D /* RxGesture */,
);
productName = MLS;
productReference = 087D3EE82DA7972C002F924D /* MLS.app */;
@@ -386,6 +389,7 @@
7721A5062E0EE7F100A7B58C /* XCRemoteSwiftPackageReference "ReactorKit" */,
08DA51B22E1B9827009097A6 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
770ADB1D2E433EDA00270506 /* XCRemoteSwiftPackageReference "RxKeyboard" */,
+ 77B1F9932EE06A4E00AE4B4D /* XCRemoteSwiftPackageReference "RxGesture" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = 087D3EE92DA7972C002F924D /* Products */;
@@ -810,6 +814,14 @@
kind = branch;
};
};
+ 77B1F9932EE06A4E00AE4B4D /* XCRemoteSwiftPackageReference "RxGesture" */ = {
+ isa = XCRemoteSwiftPackageReference;
+ repositoryURL = "https://github.com/RxSwiftCommunity/RxGesture.git";
+ requirement = {
+ kind = upToNextMajorVersion;
+ minimumVersion = 4.0.4;
+ };
+ };
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
@@ -863,6 +875,11 @@
package = 77660AD32DD0D3DD007A4EF3 /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */;
productName = KakaoSDKUser;
};
+ 77B1F9942EE06A4E00AE4B4D /* RxGesture */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = 77B1F9932EE06A4E00AE4B4D /* XCRemoteSwiftPackageReference "RxGesture" */;
+ productName = RxGesture;
+ };
/* End XCSwiftPackageProductDependency section */
};
rootObject = 087D3EE02DA7972C002F924D /* Project object */;
diff --git a/MLS/Presentation/BaseFeature/BaseFeature/SharedView/BaseListView.swift b/MLS/Presentation/BaseFeature/BaseFeature/SharedView/BaseListView.swift
index 5bee442c..033df7e2 100644
--- a/MLS/Presentation/BaseFeature/BaseFeature/SharedView/BaseListView.swift
+++ b/MLS/Presentation/BaseFeature/BaseFeature/SharedView/BaseListView.swift
@@ -13,7 +13,6 @@ open class BaseListView: UIView {
static let iconSize: CGFloat = 24
static let stackViewSpacing: CGFloat = 12
static let topMargin: CGFloat = 12
- static let nonFilterTopMargin: CGFloat = 20
static let cellSpacing: CGFloat = 10
static let cellWidth: CGFloat = 343
static let cellHeight: CGFloat = 104
@@ -80,8 +79,7 @@ private extension BaseListView {
func setupConstraints(isFilterHidden: Bool) {
if isFilterHidden {
listCollectionView.snp.makeConstraints { make in
- make.top.equalToSuperview().inset(Constant.nonFilterTopMargin)
- make.horizontalEdges.bottom.equalToSuperview()
+ make.edges.equalToSuperview()
}
} else {
filterStackView.snp.makeConstraints { make in
@@ -118,7 +116,7 @@ public extension BaseListView {
if hasFilter {
make.top.equalTo(filterStackView.snp.bottom).offset(Constant.topMargin)
} else {
- make.top.equalToSuperview().inset(Constant.nonFilterTopMargin)
+ make.top.equalToSuperview()
}
make.horizontalEdges.bottom.equalToSuperview()
}
diff --git a/MLS/Presentation/BaseFeature/BaseFeature/UICollectionReusableViews/CollectionViewCells/DictionaryListCell.swift b/MLS/Presentation/BaseFeature/BaseFeature/UICollectionReusableViews/CollectionViewCells/DictionaryListCell.swift
index a040c941..21c7d543 100644
--- a/MLS/Presentation/BaseFeature/BaseFeature/UICollectionReusableViews/CollectionViewCells/DictionaryListCell.swift
+++ b/MLS/Presentation/BaseFeature/BaseFeature/UICollectionReusableViews/CollectionViewCells/DictionaryListCell.swift
@@ -9,7 +9,6 @@ public final class DictionaryListCell: UICollectionViewCell {
// MARK: - Components
public let cellView = CardList()
- private var imageDownloadTask: URLSessionDataTask?
// MARK: - init
override init(frame: CGRect) {
@@ -23,6 +22,16 @@ public final class DictionaryListCell: UICollectionViewCell {
required init?(coder: NSCoder) {
fatalError("\(#file), \(#function) Error")
}
+
+ override public func prepareForReuse() {
+ super.prepareForReuse()
+
+ onBookmarkTapped = nil
+ cellView.onIconTapped = nil
+ cellView.setMainText(text: "")
+ cellView.setSubText(text: nil)
+ cellView.setSelected(isSelected: false)
+ }
}
// MARK: - SetUp
@@ -55,15 +64,32 @@ public extension DictionaryListCell {
}
}
- func inject(type: CardList.CardListType, input: Input, onBookmarkTapped: @escaping (Bool) -> Void) {
+ func inject(
+ type: CardList.CardListType,
+ input: Input,
+ indexPath: IndexPath,
+ collectionView: UICollectionView,
+ isMap: Bool = false,
+ onBookmarkTapped: @escaping (Bool) -> Void
+ ) {
cellView.setType(type: type)
- // URL이 유효할 때만 요청
+ cellView.setImage(image: UIImage(), backgroundColor: input.type.backgroundColor) // 초기화
+
if let url = URL(string: input.imageUrl) {
- ImageLoader.shared.loadImage(url: url) { image in
- guard let image = image else { return }
- self.cellView.setImage(image: image, backgroundColor: input.type.backgroundColor)
+ ImageLoader.shared.loadImage(url: url) { [weak self] image in
+ guard let self = self else { return }
+ // ⚠️ 셀이 재사용된 경우, indexPath가 다르면 무시
+ if let currentIndex = collectionView.indexPath(for: self),
+ currentIndex == indexPath {
+ if isMap {
+ self.cellView.setMapImage(image: image ?? UIImage(), backgroundColor: input.type.backgroundColor)
+ } else {
+ self.cellView.setImage(image: image ?? UIImage(), backgroundColor: input.type.backgroundColor)
+ }
+ }
}
}
+
cellView.setMainText(text: input.mainText)
cellView.setSubText(text: input.subText)
cellView.setSelected(isSelected: input.isBookmarked)
diff --git a/MLS/Presentation/BaseFeature/BaseFeature/Utills/CompositionalLayoutBuilder/LayoutFactory.swift b/MLS/Presentation/BaseFeature/BaseFeature/Utills/CompositionalLayoutBuilder/LayoutFactory.swift
index 6c83082c..12af8d7f 100644
--- a/MLS/Presentation/BaseFeature/BaseFeature/Utills/CompositionalLayoutBuilder/LayoutFactory.swift
+++ b/MLS/Presentation/BaseFeature/BaseFeature/Utills/CompositionalLayoutBuilder/LayoutFactory.swift
@@ -36,13 +36,13 @@ public class LayoutFactory {
.contentInsets(.init(top: 12, leading: 16, bottom: 32, trailing: 16))
}
- public func getDictionaryListLayout() -> CompositionalSectionBuilder {
+ public func getDictionaryListLayout(isFilterHidden: Bool = true) -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .fractionalWidth(1.0), height: .absolute(104))
.group(.horizontal, width: .fractionalWidth(1.0), height: .absolute(104))
.buildSection()
.interGroupSpacing(10)
- .contentInsets(.init(top: 0, leading: 16, bottom: 0, trailing: 16))
+ .contentInsets(.init(top: isFilterHidden ? 20 : 0, leading: 16, bottom: 0, trailing: 16))
}
public func getTagChipLayout() -> CompositionalSectionBuilder {
diff --git a/MLS/Presentation/BookmarkFeature/BookmarkFeature/BookmarkList/BookmarkListViewController.swift b/MLS/Presentation/BookmarkFeature/BookmarkFeature/BookmarkList/BookmarkListViewController.swift
index b76516fc..4c3f4973 100644
--- a/MLS/Presentation/BookmarkFeature/BookmarkFeature/BookmarkList/BookmarkListViewController.swift
+++ b/MLS/Presentation/BookmarkFeature/BookmarkFeature/BookmarkList/BookmarkListViewController.swift
@@ -86,9 +86,10 @@ private extension BookmarkListViewController {
}
func createListLayout() -> UICollectionViewLayout {
+ guard let isHidden = reactor?.currentState.type.isBookmarkSortHidden else { return UICollectionViewLayout() }
let layoutFactory = LayoutFactory()
let layout = CompositionalLayoutBuilder()
- .section { _ in layoutFactory.getDictionaryListLayout() }
+ .section { _ in layoutFactory.getDictionaryListLayout(isFilterHidden: isHidden) }
.build()
layout.register(Neutral300DividerView.self, forDecorationViewOfKind: Neutral300DividerView.identifier)
return layout
@@ -248,6 +249,9 @@ extension BookmarkListViewController: UICollectionViewDelegate, UICollectionView
imageUrl: item.imageUrl ?? "",
isBookmarked: true
),
+ indexPath: indexPath,
+ collectionView: collectionView,
+ isMap: item.type == .map,
onBookmarkTapped: { [weak self] isSelected in
guard let self = self else { return }
diff --git a/MLS/Presentation/BookmarkFeature/BookmarkFeature/CollectionDetail/CollectionDetailViewController.swift b/MLS/Presentation/BookmarkFeature/BookmarkFeature/CollectionDetail/CollectionDetailViewController.swift
index c30e3e90..6ff006bf 100644
--- a/MLS/Presentation/BookmarkFeature/BookmarkFeature/CollectionDetail/CollectionDetailViewController.swift
+++ b/MLS/Presentation/BookmarkFeature/BookmarkFeature/CollectionDetail/CollectionDetailViewController.swift
@@ -235,6 +235,8 @@ extension CollectionDetailViewController: UICollectionViewDelegate, UICollection
imageUrl: item.imageUrl ?? "",
isBookmarked: true
),
+ indexPath: indexPath,
+ collectionView: collectionView,
onBookmarkTapped: { [weak self] isSelected in
guard let self = self else { return }
diff --git a/MLS/Presentation/BookmarkFeature/BookmarkFeature/CollectionEdit/CollectionEditViewController.swift b/MLS/Presentation/BookmarkFeature/BookmarkFeature/CollectionEdit/CollectionEditViewController.swift
index 2a0627c7..74d2f552 100644
--- a/MLS/Presentation/BookmarkFeature/BookmarkFeature/CollectionEdit/CollectionEditViewController.swift
+++ b/MLS/Presentation/BookmarkFeature/BookmarkFeature/CollectionEdit/CollectionEditViewController.swift
@@ -159,7 +159,7 @@ extension CollectionEditViewController: UICollectionViewDelegate, UICollectionVi
}
cell.inject(
- type: .checkbox,
+ type: .bookmark,
input: DictionaryListCell.Input(
type: item.type,
mainText: item.name,
@@ -167,6 +167,8 @@ extension CollectionEditViewController: UICollectionViewDelegate, UICollectionVi
imageUrl: item.imageUrl ?? "",
isBookmarked: isSelected
),
+ indexPath: indexPath,
+ collectionView: collectionView,
onBookmarkTapped: { [weak self] _ in
self?.reactor?.action.onNext(.itemTapped(indexPath.row))
}
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Components/CardList.swift b/MLS/Presentation/DesignSystem/DesignSystem/Components/CardList.swift
index ac80254c..7e5b42ec 100644
--- a/MLS/Presentation/DesignSystem/DesignSystem/Components/CardList.swift
+++ b/MLS/Presentation/DesignSystem/DesignSystem/Components/CardList.swift
@@ -14,7 +14,7 @@ public final class CardList: UIView {
var icon: UIImage? {
switch self {
case .bookmark:
- return .bookmarkBorder
+ return .bookmarkBorderList
case .checkbox:
return .checkSquare
case .detailStack, .detailStackText, .detailStackBadge:
@@ -25,7 +25,7 @@ public final class CardList: UIView {
var selectedIcon: UIImage? {
switch self {
case .bookmark:
- return .bookmark
+ return .bookmarkList
case .checkbox:
return .checkSquareFill
case .detailStack, .detailStackText, .detailStackBadge:
@@ -44,6 +44,7 @@ public final class CardList: UIView {
static let imageContentViewSize: CGFloat = 80
static let stackViewSpacing: CGFloat = 4
static let iconSize: CGFloat = 24
+ static let mapImageSize: CGFloat = 40
}
// MARK: - Properties
@@ -72,7 +73,7 @@ public final class CardList: UIView {
public var onIconTapped: ((Bool) -> Void)?
// MARK: - Components
- private let imageView = ItemImageView(image: nil, cornerRadius: Constant.imageRadius, inset: Constant.imageInset, backgroundColor: .listMap)
+ public let imageView = ItemImageView(image: nil, cornerRadius: Constant.imageRadius, inset: Constant.imageInset, backgroundColor: .listMap)
private lazy var textLabelStackView: UIStackView = {
let view = UIStackView(arrangedSubviews: [mainTextLabel, subTextLabel])
@@ -119,7 +120,6 @@ public final class CardList: UIView {
let stack = UIStackView(arrangedSubviews: [dropTitleLabel, dropValueLabel])
stack.axis = .vertical
stack.alignment = .trailing
- stack.spacing = 2
stack.isHidden = true // 기본은 숨김
return stack
}()
@@ -158,14 +158,13 @@ private extension CardList {
textLabelStackView.snp.makeConstraints { make in
make.leading.equalTo(imageView.snp.trailing).offset(Constant.cardLeadingInset)
- make.trailing.lessThanOrEqualTo(dropInfoStack.snp.leading).offset(-Constant.cardLeadingInset)
make.centerY.equalToSuperview()
+ make.trailing.lessThanOrEqualToSuperview().inset(Constant.cardTrailingInset)
}
- iconButton.snp.makeConstraints { make in
+ dropInfoStack.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.trailing.equalToSuperview().inset(Constant.cardTrailingInset)
- make.size.equalTo(Constant.iconSize)
}
badge.snp.makeConstraints { make in
@@ -173,9 +172,16 @@ private extension CardList {
make.trailing.equalToSuperview().inset(Constant.cardTrailingInset)
}
- dropInfoStack.snp.makeConstraints { make in
+ iconButton.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.trailing.equalToSuperview().inset(Constant.cardTrailingInset)
+ make.size.equalTo(Constant.iconSize)
+ }
+
+ textLabelStackView.snp.makeConstraints { make in
+ make.trailing.lessThanOrEqualTo(dropInfoStack.snp.leading).offset(-Constant.cardLeadingInset)
+ make.trailing.lessThanOrEqualTo(badge.snp.leading).offset(-Constant.cardLeadingInset)
+ make.trailing.lessThanOrEqualTo(iconButton.snp.leading).offset(-Constant.cardLeadingInset)
}
}
@@ -210,15 +216,17 @@ public extension CardList {
}
func setSubText(text: String?) {
- if let text = text {
- subText = text
- }
+ subText = text
}
func setImage(image: UIImage, backgroundColor: UIColor) {
imageView.setImage(image: image, backgroundColor: backgroundColor)
}
+ func setMapImage(image: UIImage, backgroundColor: UIColor) {
+ imageView.setMapImage(image: image, backgroundColor: backgroundColor)
+ }
+
func setSelected(isSelected: Bool) {
isIconSelected = isSelected
}
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Components/ItemImageView.swift b/MLS/Presentation/DesignSystem/DesignSystem/Components/ItemImageView.swift
index a346d11f..57a15624 100644
--- a/MLS/Presentation/DesignSystem/DesignSystem/Components/ItemImageView.swift
+++ b/MLS/Presentation/DesignSystem/DesignSystem/Components/ItemImageView.swift
@@ -43,4 +43,12 @@ public extension ItemImageView {
imageView.image = image
self.backgroundColor = backgroundColor
}
+
+ func setMapImage(image: UIImage?, backgroundColor: UIColor) {
+ setImage(image: image, backgroundColor: backgroundColor)
+ imageView.snp.remakeConstraints { make in
+ make.center.equalToSuperview()
+ make.size.equalTo(40)
+ }
+ }
}
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Components/SearchBar.swift b/MLS/Presentation/DesignSystem/DesignSystem/Components/SearchBar.swift
index f94d600c..67008b75 100644
--- a/MLS/Presentation/DesignSystem/DesignSystem/Components/SearchBar.swift
+++ b/MLS/Presentation/DesignSystem/DesignSystem/Components/SearchBar.swift
@@ -2,8 +2,15 @@ import UIKit
import SnapKit
+public protocol SearchBarDelegate: AnyObject {
+ func searchBarDidReturn(_ searchBar: SearchBar, text: String)
+}
+
public final class SearchBar: UIView {
// MARK: - Properties
+ public weak var searchDelegate: SearchBarDelegate?
+
+ // MARK: - Components
public let backButton: UIButton = {
let button = UIButton(type: .system)
let image = DesignSystemAsset.image(named: "arrowBack")?.withRenderingMode(.alwaysTemplate)
@@ -139,6 +146,8 @@ extension SearchBar: UITextFieldDelegate {
}
public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+ searchDelegate?.searchBarDidReturn(self, text: textField.text ?? "")
+
endEditing(true)
clearButton.isHidden = true
return true
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark.imageset/Contents.json b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark.imageset/Contents.json
index b811307d..b9a0914c 100644
--- a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark.imageset/Contents.json
+++ b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "bookmark_true.svg",
+ "filename" : "bookmark.svg",
"idiom" : "universal",
"scale" : "1x"
},
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark.imageset/bookmark.svg b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark.imageset/bookmark.svg
new file mode 100644
index 00000000..4df98315
--- /dev/null
+++ b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark.imageset/bookmark.svg
@@ -0,0 +1,3 @@
+
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark.imageset/bookmark_true.svg b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark.imageset/bookmark_true.svg
deleted file mode 100644
index 7c6cd582..00000000
--- a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark.imageset/bookmark_true.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkBorder.imageset/Contents.json b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkBorder.imageset/Contents.json
new file mode 100644
index 00000000..718b074b
--- /dev/null
+++ b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkBorder.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "bookmark_border.svg",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkBorder.imageset/bookmark_border.svg b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkBorder.imageset/bookmark_border.svg
new file mode 100644
index 00000000..bf456cff
--- /dev/null
+++ b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkBorder.imageset/bookmark_border.svg
@@ -0,0 +1,3 @@
+
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkBorderList.imageset/Contents.json b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkBorderList.imageset/Contents.json
new file mode 100644
index 00000000..684a4e90
--- /dev/null
+++ b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkBorderList.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "bookmarkBorderList.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkBorderList.imageset/bookmarkBorderList.png b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkBorderList.imageset/bookmarkBorderList.png
new file mode 100644
index 00000000..9fe9661a
Binary files /dev/null and b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkBorderList.imageset/bookmarkBorderList.png differ
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkGrayBorderList.imageset/Contents.json b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkGrayBorderList.imageset/Contents.json
new file mode 100644
index 00000000..e279269b
--- /dev/null
+++ b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkGrayBorderList.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "filename" : "bookmarkGrayBorderList.svg",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkGrayBorderList.imageset/bookmarkGrayBorderList.svg b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkGrayBorderList.imageset/bookmarkGrayBorderList.svg
new file mode 100644
index 00000000..d5ace6ae
--- /dev/null
+++ b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkGrayBorderList.imageset/bookmarkGrayBorderList.svg
@@ -0,0 +1,8 @@
+
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark_border.imageset/Contents.json b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkList.imageset/Contents.json
similarity index 87%
rename from MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark_border.imageset/Contents.json
rename to MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkList.imageset/Contents.json
index b9a0914c..78cce243 100644
--- a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark_border.imageset/Contents.json
+++ b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkList.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "bookmark.svg",
+ "filename" : "bookmarkList.svg",
"idiom" : "universal",
"scale" : "1x"
},
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkList.imageset/bookmarkList.svg b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkList.imageset/bookmarkList.svg
new file mode 100644
index 00000000..dc45cef0
--- /dev/null
+++ b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmarkList.imageset/bookmarkList.svg
@@ -0,0 +1,8 @@
+
diff --git a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark_border.imageset/bookmark.svg b/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark_border.imageset/bookmark.svg
deleted file mode 100644
index 3183d363..00000000
--- a/MLS/Presentation/DesignSystem/DesignSystem/Resource/Image.xcassets/bookmark_border.imageset/bookmark.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-
diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/DictionaryDetailBaseView.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/DictionaryDetailBaseView.swift
index cc99f127..b40114f4 100644
--- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/DictionaryDetailBaseView.swift
+++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/DictionaryDetailBaseView.swift
@@ -343,7 +343,7 @@ private extension DictionaryDetailBaseView {
imageView.snp.makeConstraints { make in
make.center.equalToSuperview()
- make.size.equalTo(Constant.imageSize)
+ make.width.equalTo(imageContentView.snp.width).multipliedBy(0.42)
}
bookmarkContentView.snp.makeConstraints { make in
diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/DictionaryDetailBaseViewController.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/DictionaryDetailBaseViewController.swift
index 3c039007..2a4455e0 100644
--- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/DictionaryDetailBaseViewController.swift
+++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/DictionaryDetailBaseViewController.swift
@@ -150,6 +150,8 @@ extension DictionaryDetailBaseViewController {
}
func makeTagsRow(_ tags: Effectiveness) {
+ mainView.tagsVerticalStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
+
let maxWidth = UIScreen.main.bounds.width - DictionaryDetailBaseView.Constant.horizontalInset // 좌우 여백 고려 (16 * 2)
let tagSpacing: CGFloat = DictionaryDetailBaseView.Constant.tagVerticalSpacing
diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Item/ItemDictionaryDetailViewController.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Item/ItemDictionaryDetailViewController.swift
index 8354ee09..c3a7c7e3 100644
--- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Item/ItemDictionaryDetailViewController.swift
+++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Item/ItemDictionaryDetailViewController.swift
@@ -37,7 +37,8 @@ private extension ItemDictionaryDetailViewController {
detailInfoView.descriptionLabel.text = infos.descriptionText ?? ""
if let npcPrice = infos.npcPrice {
- detailInfoView.addInfo(mainText: "상점판매가", subText: "\(npcPrice)메소")
+ let formattedPrice = NumberFormatter.localizedString(from: NSNumber(value: npcPrice), number: .decimal)
+ detailInfoView.addInfo(mainText: "상점판매가", subText: "\(formattedPrice) 메소")
}
if let availableJobs = infos.availableJobs {
@@ -92,6 +93,10 @@ private extension ItemDictionaryDetailViewController {
detailInfoView.addInfo(mainText: title, subText: subText)
}
}
+
+ if let attackSpeed = equipmentStats.attackSpeed, let attackSpeedDetails = equipmentStats.attackSpeedDetails {
+ detailInfoView.addInfo(mainText: "공격속도", subText: "\(attackSpeed) (\(attackSpeedDetails))")
+ }
}
if let scrollDetail = infos.scrollDetail {
diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Map/MapDictionaryDetailViewController.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Map/MapDictionaryDetailViewController.swift
index 83ae69d0..67881480 100644
--- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Map/MapDictionaryDetailViewController.swift
+++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Map/MapDictionaryDetailViewController.swift
@@ -43,9 +43,9 @@ private extension MapDictionaryDetailViewController {
func setUpMapView() {
guard let reactor = reactor else { return }
- mapInfoView.setUpMapView(imageUrl: reactor.currentState.mapDetailInfo.mapUrl)
contentViews.append(mapInfoView)
if let mapUrl = reactor.currentState.mapDetailInfo.mapUrl, !mapUrl.isEmpty {
+ mapInfoView.setUpMapView(imageUrl: reactor.currentState.mapDetailInfo.mapUrl)
contentViews[0] = mapInfoView
} else {
contentViews[0] = DetailEmptyView(type: .mapInfo)
@@ -90,9 +90,11 @@ private extension MapDictionaryDetailViewController {
mapInfoView.mapImageView.addGestureRecognizer(tapGesture)
tapGesture.rx.event
- .bind(onNext: { [weak self] _ in
- guard let self else { return }
- let viewController = PinchMapViewController(imageUrl: "")
+ .withUnretained(self)
+ .bind(onNext: { owner, _ in
+ guard let reactor = owner.reactor,
+ let url = reactor.currentState.mapDetailInfo.mapUrl else { return }
+ let viewController = PinchMapViewController(imageUrl: url)
viewController.modalPresentationStyle = .overFullScreen
self.present(viewController, animated: true)
})
diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Monster/MonsterDictionaryDetailViewController.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Monster/MonsterDictionaryDetailViewController.swift
index b8a4102d..c7fdca31 100644
--- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Monster/MonsterDictionaryDetailViewController.swift
+++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Monster/MonsterDictionaryDetailViewController.swift
@@ -63,7 +63,7 @@ private extension MonsterDictionaryDetailViewController {
for map in maps {
appearMapView.inject(input: DetailStackCardView
.Input(
- type: .appearMonsterWithText,
+ type: .appearMapWithText,
imageUrl: map.iconUrl,
mainText: map.mapName,
subText: map.regionName,
diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Quest/QuestDictionaryDetailViewController.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Quest/QuestDictionaryDetailViewController.swift
index cbe66d63..d19806c1 100644
--- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Quest/QuestDictionaryDetailViewController.swift
+++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/Quest/QuestDictionaryDetailViewController.swift
@@ -22,7 +22,7 @@ private extension QuestDictionaryDetailViewController {
imageUrl: reactor?.currentState.detailInfo.iconUrl,
backgroundColor: type.backgroundColor,
name: reactor?.currentState.detailInfo.nameKr ?? "이름 없음",
- subText: "수락Lv.\(reactor?.currentState.detailInfo.minLevel ?? 0)"
+ subText: "수락 Lv.\(reactor?.currentState.detailInfo.minLevel ?? 0)"
))
}
diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/SectionStackView/DetailStackCardView.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/SectionStackView/DetailStackCardView.swift
index 29fc15f1..cdca16a2 100644
--- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/SectionStackView/DetailStackCardView.swift
+++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/SectionStackView/DetailStackCardView.swift
@@ -1,13 +1,11 @@
-import UIKit
-
import BaseFeature
import DesignSystem
import DomainInterface
-
import RxCocoa
import RxGesture
import RxSwift
import SnapKit
+import UIKit
final class DetailStackCardView: UIStackView {
// MARK: - Type
@@ -19,7 +17,12 @@ final class DetailStackCardView: UIStackView {
static let filterContainerTopMargin: CGFloat = 12
static let filterButtonTrailing: CGFloat = 8
static let viewSpacing: CGFloat = 10
- static let stackViewInset: UIEdgeInsets = .init(top: 12, left: 16, bottom: 0, right: 16)
+ static let stackViewInset: UIEdgeInsets = .init(
+ top: 12,
+ left: 16,
+ bottom: 0,
+ right: 16
+ )
}
// MARK: - Properties
@@ -35,8 +38,20 @@ final class DetailStackCardView: UIStackView {
// 몬스터 순서 필터 버튼
public let filterButton: UIButton = {
let button = UIButton()
- button.setAttributedTitle(.makeStyledString(font: .b_s_r, text: "드롭률 높은 순", color: .textColor), for: .normal)
- button.setImage(DesignSystemAsset.image(named: "dropDown")?.withRenderingMode(.alwaysTemplate), for: .normal)
+ button.setAttributedTitle(
+ .makeStyledString(
+ font: .b_s_r,
+ text: "드롭률 높은 순",
+ color: .textColor
+ ),
+ for: .normal
+ )
+ button.setImage(
+ DesignSystemAsset.image(named: "dropDown")?.withRenderingMode(
+ .alwaysTemplate
+ ),
+ for: .normal
+ )
button.tintColor = .textColor
button.semanticContentAttribute = .forceRightToLeft
@@ -63,21 +78,23 @@ final class DetailStackCardView: UIStackView {
}
// MARK: - SetUp
-private extension DetailStackCardView {
- func addViews() {
+extension DetailStackCardView {
+ fileprivate func addViews() {
addArrangedSubview(filterContainerView)
filterContainerView.addSubview(filterButton)
addArrangedSubview(spacer)
}
- func setUpConstraints() {
+ fileprivate func setUpConstraints() {
filterContainerView.snp.makeConstraints { make in
make.height.equalTo(Constant.filterContainerHeight)
}
filterButton.snp.makeConstraints { make in
make.centerY.equalToSuperview()
- make.trailing.equalToSuperview().inset(Constant.filterButtonTrailing)
+ make.trailing.equalToSuperview().inset(
+ Constant.filterButtonTrailing
+ )
}
spacer.snp.makeConstraints { make in
@@ -85,7 +102,7 @@ private extension DetailStackCardView {
}
}
- func configureUI() {
+ fileprivate func configureUI() {
axis = .vertical
alignment = .fill
distribution = .fill
@@ -140,7 +157,17 @@ extension DetailStackCardView {
cardView.setType(type: .detailStackText)
ImageLoader.shared.loadImage(stringURL: input.imageUrl) { image in
guard let image = image else { return }
- cardView.setImage(image: image, backgroundColor: input.type.backgroundColor)
+ if input.type == .appearMap || input.type == .appearMapWithText {
+ cardView.setMapImage(
+ image: image,
+ backgroundColor: input.type.backgroundColor
+ )
+ } else {
+ cardView.setImage(
+ image: image,
+ backgroundColor: input.type.backgroundColor
+ )
+ }
}
cardView.mainText = input.mainText
cardView.subText = input.subText
@@ -178,17 +205,33 @@ extension DetailStackCardView {
filterContainerView.isHidden = isHidden
spacer.snp.remakeConstraints { make in
- make.height.equalTo(isHidden ? Constant.topSpacing : Constant.filterSpacing)
+ make.height.equalTo(
+ isHidden ? Constant.topSpacing : Constant.filterSpacing
+ )
}
}
func selectFilter(selectedType: SortType) {
- filterButton.setAttributedTitle(.makeStyledString(font: .b_s_r, text: selectedType.rawValue, color: .primary700), for: .normal)
+ filterButton.setAttributedTitle(
+ .makeStyledString(
+ font: .b_s_r,
+ text: selectedType.rawValue,
+ color: .primary700
+ ),
+ for: .normal
+ )
filterButton.tintColor = .primary700
}
func initFilter(firstFilter: SortType) {
- filterButton.setAttributedTitle(.makeStyledString(font: .b_s_r, text: firstFilter.rawValue, color: .textColor), for: .normal)
+ filterButton.setAttributedTitle(
+ .makeStyledString(
+ font: .b_s_r,
+ text: firstFilter.rawValue,
+ color: .textColor
+ ),
+ for: .normal
+ )
}
func reset() {
diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/SectionStackView/DetailStackMapView.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/SectionStackView/DetailStackMapView.swift
index 380efa01..3fd3b0f6 100644
--- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/SectionStackView/DetailStackMapView.swift
+++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/SectionStackView/DetailStackMapView.swift
@@ -54,6 +54,15 @@ private extension DetailStackMapView {
extension DetailStackMapView {
func setUpMapView(imageUrl: String?) {
ImageLoader.shared.loadImage(stringURL: imageUrl) { [weak self] image in
+ if image == DesignSystemAsset.image(named: "connectionError") {
+ self?.mapImageView.snp.remakeConstraints { make in
+ make.size.equalTo(165)
+ }
+ } else {
+ self?.mapImageView.snp.remakeConstraints { make in
+ make.height.equalTo(self?.mapImageView.snp.width ?? 0)
+ }
+ }
self?.mapImageView.image = image
}
}
diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/SectionStackView/PinchMapView.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/SectionStackView/PinchMapView.swift
index ea90ee00..4ffa6d00 100644
--- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/SectionStackView/PinchMapView.swift
+++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryDetail/SectionStackView/PinchMapView.swift
@@ -19,6 +19,7 @@ final class PinchMapView: UIView {
scrollView.showsVerticalScrollIndicator = false
scrollView.showsHorizontalScrollIndicator = false
scrollView.bouncesZoom = true
+ scrollView.backgroundColor = .clearMLS
return scrollView
}()
@@ -26,7 +27,7 @@ final class PinchMapView: UIView {
let view = UIImageView()
view.clipsToBounds = true
view.contentMode = .scaleAspectFit
- view.backgroundColor = .textColor.withAlphaComponent(0.9)
+ view.backgroundColor = .clearMLS
view.layer.opacity = 0.9
return view
}()
@@ -79,7 +80,7 @@ private extension PinchMapView {
}
func configureUI() {
- backgroundColor = .clearMLS
+ backgroundColor = .textColor.withAlphaComponent(0.9)
}
}
diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryList/DictionaryListCell.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryList/DictionaryListCell.swift
deleted file mode 100644
index c636e5bd..00000000
--- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryList/DictionaryListCell.swift
+++ /dev/null
@@ -1,85 +0,0 @@
-// import UIKit
-//
-// import BaseFeature
-// import DesignSystem
-// import DomainInterface
-//
-// final class DictionaryListCell: UICollectionViewCell {
-// // MARK: - Properties
-// private var onBookmarkTapped: ((Bool) -> Void)?
-//
-// // MARK: - Components
-// public let cellView = CardList()
-// private var imageDownloadTask: URLSessionDataTask?
-//
-// // MARK: - init
-// override init(frame: CGRect) {
-// super.init(frame: frame)
-//
-// addViews()
-// setupContstraints()
-// }
-//
-// @available(*, unavailable)
-// required init?(coder: NSCoder) {
-// fatalError("\(#file), \(#function) Error")
-// }
-// }
-//
-//// MARK: - SetUp
-// private extension DictionaryListCell {
-// func addViews() {
-// contentView.addSubview(cellView)
-// }
-//
-// func setupContstraints() {
-// cellView.snp.makeConstraints { make in
-// make.edges.equalToSuperview()
-// }
-// }
-// }
-//
-// extension DictionaryListCell {
-// struct Input {
-// let type: DictionaryItemType
-// let mainText: String
-// let subText: String
-// let imageUrl: String
-// let isBookmarked: Bool
-// }
-//
-// func inject(type: CardList.CardListType, input: Input, onBookmarkTapped: @escaping (Bool) -> Void) {
-// cellView.setType(type: type)
-// // URL이 유효할 때만 요청
-// if let url = URL(string: input.imageUrl) {
-// ImageLoader.shared.loadImage(url: url) { image in
-// guard let image = image else { return }
-// self.cellView.setImage(image: image, backgroundColor: input.type.backgroundColor)
-// }
-// }
-// cellView.setMainText(text: input.mainText)
-// cellView.setSubText(text: input.subText)
-// cellView.setSelected(isSelected: input.isBookmarked)
-// self.onBookmarkTapped = onBookmarkTapped
-// cellView.onIconTapped = { [weak self] isSelected in
-// self?.onBookmarkTapped?(isSelected)
-// }
-// }
-// }
-//
-// public extension DictionaryItemType {
-// var backgroundColor: UIColor {
-// switch self {
-// case .item:
-// .listItem
-// case .monster:
-// .listMonster
-// case .map:
-// .listMap
-// case .npc:
-// .listNPC
-// case .quest:
-// .listQuest
-// }
-// }
-// }
diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryList/DictionaryListViewController.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryList/DictionaryListViewController.swift
index c1700ee7..e1b6330d 100644
--- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryList/DictionaryListViewController.swift
+++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionaryList/DictionaryListViewController.swift
@@ -41,8 +41,7 @@ public final class DictionaryListViewController: BaseViewController, View {
self.bookmarkModalFactory = bookmarkModalFactory
self.detailFactory = detailFactory
self.loginFactory = loginFactory
- self.mainView = DictionaryListView(
- isFilterHidden: reactor.currentState.type.isSortHidden)
+ self.mainView = DictionaryListView(isFilterHidden: reactor.currentState.type.isSortHidden)
super.init()
self.reactor = reactor
}
@@ -85,9 +84,10 @@ private extension DictionaryListViewController {
}
func createListLayout() -> UICollectionViewLayout {
+ guard let isHidden = reactor?.currentState.type.isSortHidden else { return UICollectionViewLayout() }
let layoutFactory = LayoutFactory()
let layout = CompositionalLayoutBuilder()
- .section { _ in layoutFactory.getDictionaryListLayout() }
+ .section { _ in layoutFactory.getDictionaryListLayout(isFilterHidden: isHidden) }
.build()
layout.register(
Neutral300DividerView.self,
@@ -209,11 +209,8 @@ extension DictionaryListViewController: UICollectionViewDelegate, UICollectionVi
guard let state = reactor?.currentState,
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DictionaryListCell.identifier, for: indexPath) as? DictionaryListCell else { return UICollectionViewCell() }
let item = state.listItems[indexPath.row]
+ let subText: String? = [.item, .monster, .quest].contains(item.type) ? item.level.map { "Lv. \($0)" } : nil
- var subText: String? {
- [.item, .monster, .quest].contains(item.type)
- ? item.level.map { "Lv. \($0)" } : nil
- }
cell.inject(
type: .bookmark,
input: DictionaryListCell.Input(
@@ -221,8 +218,11 @@ extension DictionaryListViewController: UICollectionViewDelegate, UICollectionVi
mainText: item.name,
subText: subText,
imageUrl: item.imageUrl ?? "",
- isBookmarked: item.bookmarkId != nil
+ isBookmarked: item.bookmarkId != nil,
),
+ indexPath: indexPath,
+ collectionView: collectionView,
+ isMap: item.type == .map,
onBookmarkTapped: { [weak self] isSelected in
guard let self = self else { return }
@@ -269,8 +269,7 @@ extension DictionaryListViewController: UICollectionViewDelegate, UICollectionVi
buttonAction: {
DispatchQueue.main.async { [weak self] in
guard let self = self,
- let reactor = self.reactor,
- let id = reactor.currentState.listItems[indexPath.row].bookmarkId else { return }
+ let id = item.bookmarkId else { return }
let viewController = self.bookmarkModalFactory.make(bookmarkIds: [id], onComplete: { isAdd in
if isAdd {
diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearch/DictionarySearchViewController.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearch/DictionarySearchViewController.swift
index 9693f932..f03f75dc 100644
--- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearch/DictionarySearchViewController.swift
+++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearch/DictionarySearchViewController.swift
@@ -57,6 +57,9 @@ private extension DictionarySearchViewController {
func configureUI() {
isBottomTabbarHidden = true
+ mainView.searchBar.searchDelegate = self
+ mainView.searchBar.textField.becomeFirstResponder()
+
mainView.searchCollectionView.collectionViewLayout = createLayout()
mainView.searchCollectionView.delegate = self
mainView.searchCollectionView.dataSource = self
@@ -292,3 +295,9 @@ extension DictionarySearchViewController: UICollectionViewDelegate, UICollection
}
}
}
+
+extension DictionarySearchViewController: SearchBarDelegate {
+ public func searchBarDidReturn(_ searchBar: SearchBar, text: String) {
+ reactor?.action.onNext(.searchButtonTapped(text))
+ }
+}
diff --git a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearchResult/DictionarySearchResultReactor.swift b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearchResult/DictionarySearchResultReactor.swift
index f8cf3ca6..6e3dc4a0 100644
--- a/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearchResult/DictionarySearchResultReactor.swift
+++ b/MLS/Presentation/DictionaryFeature/DictionaryFeature/DictionarySearchResult/DictionarySearchResultReactor.swift
@@ -96,7 +96,7 @@ public final class DictionarySearchResultReactor: Reactor {
.distinctUntilChanged() // 중복 keyword 방지
.flatMap { [weak self] keyword -> Observable in
guard let self = self else { return .empty() }
- let types = ["search", "monsters", "items", "npcs", "maps", "quests"]
+ let types = ["search", "monsters", "items", "maps", "npcs", "quests"]
let countObservables = types.map { type in
self.dictionarySearchCountUseCase.execute(type: type, keyword: keyword)
.map { $0.count ?? 0 }