Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
255 changes: 218 additions & 37 deletions MLS/MLS.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions MLS/MLS.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion MLS/MLS.xcworkspace/xcshareddata/swiftpm/Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions MLS/MLSCore/Sources/MLSCore/BaseController/WebViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import SafariServices
import UIKit

public final class WebViewController {

public static func make(urlString: String) -> SFSafariViewController? {
guard let url = URL(string: urlString) else { return nil }
return SFSafariViewController(url: url)
}
}
36 changes: 36 additions & 0 deletions MLS/MLSCore/Sources/MLSCore/Extension/String+.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Foundation

public extension String {
func isOnlyKorean() -> Bool {
return !self.isEmpty &&
self.allSatisfy { char in
char.unicodeScalars.allSatisfy { scalar in
switch scalar.value {
case 0x30...0x39:
return true
case 0xac00...0xd7a3:
return true
case 0x3131...0x3163:
return true
default:
return false
}
}
}
}

func toDisplayDateString() -> String {
let inputFormatter = DateFormatter()
inputFormatter.locale = Locale(identifier: "ko_KR")
inputFormatter.timeZone = TimeZone(identifier: "Asia/Seoul")
inputFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"

guard let date = inputFormatter.date(from: self) else { return self }

let outputFormatter = DateFormatter()
outputFormatter.locale = Locale(identifier: "ko_KR")
outputFormatter.dateFormat = "yyyy.MM.dd HH:mm"

return outputFormatter.string(from: date)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import UIKit

@MainActor
public class LayoutFactory {
public init() {}

public static func getPageTabbarLayout(underLineController: TabBarUnderlineController? = nil) -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .estimated(100), height: .absolute(40))
.group(.horizontal, width: .estimated(100), height: .absolute(40))
.buildSection()
.orthogonalScrolling(.continuous)
.interGroupSpacing(28)
.contentInsets(.init(top: 0, leading: 16, bottom: 0, trailing: 16))
.visibleItemsInvalidationHandler { _, offset, _ in
underLineController?.updateScrollOffset(offset)
}
}

public static func getItemTagListSection(width: CGFloat = 50) -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .estimated(width), height: .absolute(34))
.group(.horizontal, width: .fractionalWidth(1), height: .absolute(34))
.interItemSpacing(.fixed(8))
.buildSection()
.header(height: 22)
.interGroupSpacing(8)
.contentInsets(.init(top: 12, leading: 16, bottom: 32, trailing: 16))
}

public static func getLevelRangeSection() -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .fractionalWidth(1), height: .estimated(100))
.group(.horizontal, width: .fractionalWidth(1), height: .estimated(100))
.buildSection()
.header(height: 22)
.contentInsets(.init(top: 12, leading: 16, bottom: 32, trailing: 16))
}

public static 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: isFilterHidden ? 20 : 0, leading: 16, bottom: 0, trailing: 16))
}

public static func getTagChipLayout() -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .estimated(70), height: .estimated(32))
.group(.horizontal, width: .estimated(70), height: .estimated(32))
.buildSection()
.header(height: 44)
.orthogonalScrolling(.continuous)
.interGroupSpacing(8)
.contentInsets(.init(top: 24, leading: 16, bottom: 24, trailing: 16))
}

public static func getDecorationSection() -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .fractionalWidth(1.0), height: .absolute(1))
.group(.vertical, width: .fractionalWidth(1.0), height: .absolute(10))
.buildSection()
.decorationItem(kind: SearchDividerView.identifier)
.contentInsets(.init(top: 5, leading: 0, bottom: 5, trailing: 0))
}

public static func getPopularResultLayout() -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .fractionalWidth(1.0), height: .estimated(40))
.group(.horizontal, width: .fractionalWidth(1.0), height: .estimated(40), count: 2)
.buildSection()
.header(height: 44)
.contentInsets(.init(top: 16, leading: 16, bottom: 16, trailing: 16))
}

public static func getNotificationLayout() -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .fractionalWidth(1.0), height: .estimated(86))
.group(.vertical, width: .fractionalWidth(1.0), height: .estimated(86))
.buildSection()
.interGroupSpacing(8)
.contentInsets(.init(top: 0, leading: 16, bottom: 0, trailing: 16))
}

public static func getCollectionModalLayout() -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .fractionalWidth(1.0), height: .absolute(72))
.group(.vertical, width: .fractionalWidth(1.0), height: .absolute(72))
.buildSection()
.interGroupSpacing(1)
}

public static func getCollectionListLayout() -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .fractionalWidth(1.0), height: .absolute(96))
.group(.vertical, width: .fractionalWidth(1.0), height: .absolute(96))
.buildSection()
.interGroupSpacing(10)
.contentInsets(.init(top: 0, leading: 16, bottom: 0, trailing: 16))
}

public static func getCollectionListEditLayout() -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .fractionalWidth(1.0), height: .absolute(104))
.group(.vertical, width: .fractionalWidth(1.0), height: .absolute(104))
.buildSection()
.interGroupSpacing(10)
.contentInsets(.init(top: 20, leading: 16, bottom: 20, trailing: 16))
}

// 이 아래는 정리
public func getMyPageMainLayout() -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .fractionalWidth(1.0), height: .estimated(200))
.group(.vertical, width: .fractionalWidth(1.0), height: .estimated(200))
.buildSection()
}

public func getMyPageSettingLayout() -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .fractionalWidth(1.0), height: .absolute(50))
.group(.vertical, width: .fractionalWidth(1.0), height: .estimated(100))
.buildSection()
.decorationItem(kind: SettingBackgroundView.identifier)
.contentInsets(.init(top: 20 + 10, leading: 16 + 10, bottom: 10, trailing: 16 + 10))
}

public func getMyPageSupportLayout() -> CompositionalSectionBuilder {
return CompositionalSectionBuilder()
.item(width: .fractionalWidth(1.0), height: .absolute(50))
.group(.vertical, width: .fractionalWidth(1.0), height: .estimated(100))
.buildSection()
.decorationItem(kind: SupportBackgroundView.identifier)
.contentInsets(.init(top: 16 + 10, leading: 16 + 10, bottom: 20 + 10, trailing: 16 + 10))
}

public func getSelectImageLayout() -> CompositionalSectionBuilder {
let itemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0/3.0),
heightDimension: .fractionalWidth(1.0/3.0)
)
let item = NSCollectionLayoutItem(layoutSize: itemSize)

let groupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalWidth(1.0/3.0)
)
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item, item, item])
group.interItemSpacing = .fixed(16)

let section = NSCollectionLayoutSection(group: group)
section.contentInsets = NSDirectionalEdgeInsets(top: 20, leading: 16, bottom: 16, trailing: 16)

return CompositionalSectionBuilder(section: section)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import UIKit

final public class DescriptionBackgroundView: UICollectionReusableView {
// MARK: - Type
enum Constant {
static let horizontalInset: CGFloat = 16
static let topInset: CGFloat = 60
static let bottomInset: CGFloat = 20
}

private let containerView: UIView = {
let view = UIView()
view.backgroundColor = .whiteMLS
view.layer.cornerRadius = 16
view.layer.masksToBounds = true
return view
}()

override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .neutral200
addViews()
setConstraints()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

}

private extension DescriptionBackgroundView {
private func addViews() {
addSubview(containerView)
}

func setConstraints() {
containerView.snp.makeConstraints { make in
make.top.equalToSuperview().inset(Constant.topInset)
make.horizontalEdges.equalToSuperview().inset(Constant.horizontalInset)
make.bottom.equalToSuperview().inset(Constant.bottomInset)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import UIKit

final public class Neutral100BackgroundView: UICollectionReusableView {
// MARK: - Type
private let containerView: UIView = {
let view = UIView()
view.backgroundColor = .neutral100
return view
}()

override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .neutral200
addViews()
setConstraints()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

}

private extension Neutral100BackgroundView {
private func addViews() {
addSubview(containerView)
}

func setConstraints() {
containerView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import UIKit

final public class Neutral200DividerView: UICollectionReusableView {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .neutral200
layer.zPosition = -1
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

public override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
super.apply(layoutAttributes)
self.frame.size.height = 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import UIKit

final public class Neutral300DividerView: UICollectionReusableView {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .neutral300
layer.zPosition = -1
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

public override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
super.apply(layoutAttributes)
self.frame.size.height = 1
}
}
Loading
Loading