diff --git a/iOS/Layover/Layover.xcodeproj/project.pbxproj b/iOS/Layover/Layover.xcodeproj/project.pbxproj index ac669046..dff0e7ca 100644 --- a/iOS/Layover/Layover.xcodeproj/project.pbxproj +++ b/iOS/Layover/Layover.xcodeproj/project.pbxproj @@ -31,8 +31,11 @@ 194552392B05230E00299768 /* HomeCarouselCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 194552382B05230E00299768 /* HomeCarouselCollectionViewCell.swift */; }; 1945523B2B05258200299768 /* HomeConfigurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1945523A2B05258200299768 /* HomeConfigurator.swift */; }; 19743C052B06940D001E405A /* PlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19743C042B06940D001E405A /* PlayerView.swift */; }; + 19ABC1C32B0B78C800736813 /* LayoverConstraintWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ABC1C22B0B78C800736813 /* LayoverConstraintWrapper.swift */; }; + 19ABC1C52B0B7D0100736813 /* LayoverConstraintWrapper+UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19ABC1C42B0B7D0100736813 /* LayoverConstraintWrapper+UIView.swift */; }; 19C7AFCE2B02410F003B35F2 /* AuthManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19C7AFCD2B02410F003B35F2 /* AuthManager.swift */; }; 19C7AFD62B02584D003B35F2 /* KeychainStored.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19C7AFD52B02584D003B35F2 /* KeychainStored.swift */; }; + 19E79AC02B0A85D0009EA9ED /* LoopingPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19E79ABF2B0A85D0009EA9ED /* LoopingPlayerView.swift */; }; 835A61902B067D61002F22A5 /* LOSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 835A618F2B067D61002F22A5 /* LOSlider.swift */; }; 835A61922B067FEC002F22A5 /* LOTagStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 835A61912B067FEC002F22A5 /* LOTagStackView.swift */; }; 835A61942B068096002F22A5 /* LODescriptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 835A61932B068096002F22A5 /* LODescriptionView.swift */; }; @@ -42,7 +45,6 @@ 835A61A02B068115002F22A5 /* PlaybackModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 835A619A2B068115002F22A5 /* PlaybackModels.swift */; }; 835A61A12B068115002F22A5 /* PlaybackViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 835A619B2B068115002F22A5 /* PlaybackViewController.swift */; }; 835A61A22B068115002F22A5 /* PlaybackInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 835A619C2B068115002F22A5 /* PlaybackInteractor.swift */; }; - 19E79AC02B0A85D0009EA9ED /* LoopingPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19E79ABF2B0A85D0009EA9ED /* LoopingPlayerView.swift */; }; FC2511A02B045C0A004717BC /* SignUpInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC25119F2B045C0A004717BC /* SignUpInteractor.swift */; }; FC2511A22B045C3F004717BC /* SignUpPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC2511A12B045C3F004717BC /* SignUpPresenter.swift */; }; FC2511A42B045D6C004717BC /* SignUpModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC2511A32B045D6C004717BC /* SignUpModels.swift */; }; @@ -115,8 +117,11 @@ 194552382B05230E00299768 /* HomeCarouselCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeCarouselCollectionViewCell.swift; sourceTree = ""; }; 1945523A2B05258200299768 /* HomeConfigurator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeConfigurator.swift; sourceTree = ""; }; 19743C042B06940D001E405A /* PlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerView.swift; sourceTree = ""; }; + 19ABC1C22B0B78C800736813 /* LayoverConstraintWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoverConstraintWrapper.swift; sourceTree = ""; }; + 19ABC1C42B0B7D0100736813 /* LayoverConstraintWrapper+UIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LayoverConstraintWrapper+UIView.swift"; sourceTree = ""; }; 19C7AFCD2B02410F003B35F2 /* AuthManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthManager.swift; sourceTree = ""; }; 19C7AFD52B02584D003B35F2 /* KeychainStored.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainStored.swift; sourceTree = ""; }; + 19E79ABF2B0A85D0009EA9ED /* LoopingPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoopingPlayerView.swift; sourceTree = ""; }; 835A618F2B067D61002F22A5 /* LOSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LOSlider.swift; sourceTree = ""; }; 835A61912B067FEC002F22A5 /* LOTagStackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LOTagStackView.swift; sourceTree = ""; }; 835A61932B068096002F22A5 /* LODescriptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LODescriptionView.swift; sourceTree = ""; }; @@ -126,7 +131,6 @@ 835A619A2B068115002F22A5 /* PlaybackModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaybackModels.swift; sourceTree = ""; }; 835A619B2B068115002F22A5 /* PlaybackViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaybackViewController.swift; sourceTree = ""; }; 835A619C2B068115002F22A5 /* PlaybackInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaybackInteractor.swift; sourceTree = ""; }; - 19E79ABF2B0A85D0009EA9ED /* LoopingPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoopingPlayerView.swift; sourceTree = ""; }; FC25119F2B045C0A004717BC /* SignUpInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignUpInteractor.swift; sourceTree = ""; }; FC2511A12B045C3F004717BC /* SignUpPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignUpPresenter.swift; sourceTree = ""; }; FC2511A32B045D6C004717BC /* SignUpModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignUpModels.swift; sourceTree = ""; }; @@ -233,6 +237,15 @@ path = Cell; sourceTree = ""; }; + 19ABC1C62B0B8A5B00736813 /* LayoverConstraint */ = { + isa = PBXGroup; + children = ( + 19ABC1C22B0B78C800736813 /* LayoverConstraintWrapper.swift */, + 19ABC1C42B0B7D0100736813 /* LayoverConstraintWrapper+UIView.swift */, + ); + path = LayoverConstraint; + sourceTree = ""; + }; 19BB8A572B07BEE30070B922 /* UIComponents */ = { isa = PBXGroup; children = ( @@ -429,6 +442,7 @@ FC7E45812AFF6FF9004F155A /* Extensions */ = { isa = PBXGroup; children = ( + 19ABC1C62B0B8A5B00736813 /* LayoverConstraint */, FC7E45952AFF7497004F155A /* DummyExtension.swift */, FC4975982B03439000D8627F /* UIFont+.swift */, 194552012B038B8300299768 /* OSLog+.swift */, @@ -617,12 +631,14 @@ 835A61922B067FEC002F22A5 /* LOTagStackView.swift in Sources */, FC7E45902AFF746E004F155A /* DummyWorker.swift in Sources */, 835A61A12B068115002F22A5 /* PlaybackViewController.swift in Sources */, + 19ABC1C32B0B78C800736813 /* LayoverConstraintWrapper.swift in Sources */, 1945520F2B03AEA400299768 /* Configurator.swift in Sources */, 835A619F2B068115002F22A5 /* PlaybackRouter.swift in Sources */, FC2511B12B04EAEC004717BC /* MapModels.swift in Sources */, FC68E29F2B023315001AABFF /* HTTPMethod.swift in Sources */, 835A619D2B068115002F22A5 /* PlaybackPresenter.swift in Sources */, FCEE0FFA2B03AF8500195BBE /* SignUpViewController.swift in Sources */, + 19ABC1C52B0B7D0100736813 /* LayoverConstraintWrapper+UIView.swift in Sources */, 194551F32B037F2D00299768 /* LoginWorker.swift in Sources */, 835A61902B067D61002F22A5 /* LOSlider.swift in Sources */, 19E79AC02B0A85D0009EA9ED /* LoopingPlayerView.swift in Sources */, diff --git a/iOS/Layover/Layover/Extensions/LayoverConstraint/LayoverConstraintWrapper+UIView.swift b/iOS/Layover/Layover/Extensions/LayoverConstraint/LayoverConstraintWrapper+UIView.swift new file mode 100644 index 00000000..f0c4bfad --- /dev/null +++ b/iOS/Layover/Layover/Extensions/LayoverConstraint/LayoverConstraintWrapper+UIView.swift @@ -0,0 +1,155 @@ +// +// LayoverConstraintWrapper+UIView.swift +// Layover +// +// Created by 김인환 on 11/20/23. +// Copyright © 2023 CodeBomber. All rights reserved. +// + +import UIKit + +extension LayoverConstraintWrapper where Base: UIView { + + func makeConstraints(_ closure: (ConstraintMaker) -> Void) { + base.translatesAutoresizingMaskIntoConstraints = false + closure(ConstraintMaker(base)) + } +} + +final class ConstraintMaker { + + // MARK: Properties + + private let view: UIView + + var edges: ConstraintEdges { + ConstraintEdges(view) + } + + var top: ConstraintEdges { + ConstraintEdges(view).top + } + + var bottom: ConstraintEdges { + ConstraintEdges(view).bottom + } + + var leading: ConstraintEdges { + ConstraintEdges(view).leading + } + + var trailing: ConstraintEdges { + ConstraintEdges(view).trailing + } + + var width: ConstraintEdges { + ConstraintEdges(view).width + } + + var height: ConstraintEdges { + ConstraintEdges(view).height + } + + var centerX: ConstraintEdges { + ConstraintEdges(view).centerX + } + + var centerY: ConstraintEdges { + ConstraintEdges(view).centerY + } + + var center: ConstraintEdges { + ConstraintEdges(view).center + } + + // MARK: Initializer + + init(_ view: UIView) { + self.view = view + } +} + +final class ConstraintEdges { + + // MARK: Properties + + private let view: UIView + + private var topAnchor: NSLayoutYAxisAnchor? + private var leadingAnchor: NSLayoutXAxisAnchor? + private var trailingAnchor: NSLayoutXAxisAnchor? + private var bottomAnchor: NSLayoutYAxisAnchor? + + private var widthAnchor: NSLayoutDimension? + private var heightAnchor: NSLayoutDimension? + + private var centerXAnchor: NSLayoutXAxisAnchor? + private var centerYAnchor: NSLayoutYAxisAnchor? + + // MARK: Builder Pattern Properties + + var top: ConstraintEdges { + topAnchor = view.topAnchor + return self + } + + var leading: ConstraintEdges { + leadingAnchor = view.leadingAnchor + return self + } + + var trailing: ConstraintEdges { + trailingAnchor = view.trailingAnchor + return self + } + + var bottom: ConstraintEdges { + bottomAnchor = view.bottomAnchor + return self + } + + var width: ConstraintEdges { + widthAnchor = view.widthAnchor + return self + } + + var height: ConstraintEdges { + heightAnchor = view.heightAnchor + return self + } + + var centerX: ConstraintEdges { + centerXAnchor = view.centerXAnchor + return self + } + + var centerY: ConstraintEdges { + centerYAnchor = view.centerYAnchor + return self + } + + var center: ConstraintEdges { + centerXAnchor = view.centerXAnchor + centerYAnchor = view.centerYAnchor + return self + } + + // MARK: Intializer + + init(_ view: UIView) { + self.view = view + } + + // MARK: Methods + + func equalToSuperView() { + guard let superView = view.superview else { return } + + NSLayoutConstraint.activate([ + topAnchor?.constraint(equalTo: superView.topAnchor), + leadingAnchor?.constraint(equalTo: superView.leadingAnchor), + trailingAnchor?.constraint(equalTo: superView.trailingAnchor), + bottomAnchor?.constraint(equalTo: superView.bottomAnchor) + ].compactMap { $0 }) + } +} diff --git a/iOS/Layover/Layover/Extensions/LayoverConstraint/LayoverConstraintWrapper.swift b/iOS/Layover/Layover/Extensions/LayoverConstraint/LayoverConstraintWrapper.swift new file mode 100644 index 00000000..62f145ce --- /dev/null +++ b/iOS/Layover/Layover/Extensions/LayoverConstraint/LayoverConstraintWrapper.swift @@ -0,0 +1,29 @@ +// +// LayoverConstraintWrapper.swift +// Layover +// +// Created by 김인환 on 11/20/23. +// Copyright © 2023 CodeBomber. All rights reserved. +// + +import UIKit + +struct LayoverConstraintWrapper { + let base: Base +} + +protocol LayoverConstraintCompatible { + associatedtype LayoverConstraintBase + + var lor: LayoverConstraintWrapper { get } +} + +extension LayoverConstraintCompatible { + var lor: LayoverConstraintWrapper { + get { + return LayoverConstraintWrapper(base: self) + } + } +} + +extension UIView: LayoverConstraintCompatible { } diff --git a/iOS/Layover/Layover/Scenes/Home/Cell/HomeCarouselCollectionViewCell.swift b/iOS/Layover/Layover/Scenes/Home/Cell/HomeCarouselCollectionViewCell.swift index 5b30e92d..fa6bf1fd 100644 --- a/iOS/Layover/Layover/Scenes/Home/Cell/HomeCarouselCollectionViewCell.swift +++ b/iOS/Layover/Layover/Scenes/Home/Cell/HomeCarouselCollectionViewCell.swift @@ -12,6 +12,8 @@ final class HomeCarouselCollectionViewCell: UICollectionViewCell { // MARK: - Properties + private let loopingPlayerView = LoopingPlayerView() + // MARK: - UI Components // MARK: - Object lifecycle @@ -35,7 +37,12 @@ final class HomeCarouselCollectionViewCell: UICollectionViewCell { } private func setConstraints() { + addSubviews(loopingPlayerView) + loopingPlayerView.backgroundColor = .green + loopingPlayerView.lor.makeConstraints { + $0.center.equalToSuperView() + } } // MARK: - Methods diff --git a/iOS/Layover/Layover/Scenes/Home/HomeViewController.swift b/iOS/Layover/Layover/Scenes/Home/HomeViewController.swift index 0a944bc3..8d1b1768 100644 --- a/iOS/Layover/Layover/Scenes/Home/HomeViewController.swift +++ b/iOS/Layover/Layover/Scenes/Home/HomeViewController.swift @@ -40,6 +40,7 @@ final class HomeViewController: BaseViewController, HomeDisplayLogic { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: HomeCarouselCollectionViewCell.identifier, for: indexPath) as? HomeCarouselCollectionViewCell else { return UICollectionViewCell() } cell.layer.cornerRadius = 10 + cell.clipsToBounds = true return cell }