diff --git a/LGHTSG/LGHTSG.xcodeproj/project.pbxproj b/LGHTSG/LGHTSG.xcodeproj/project.pbxproj new file mode 100644 index 0000000..afd0a2a --- /dev/null +++ b/LGHTSG/LGHTSG.xcodeproj/project.pbxproj @@ -0,0 +1,594 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 07120DF3296EDF6E00ABF98F /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 07120DF2296EDF6E00ABF98F /* Alamofire */; }; + 07120DF6296EDF7A00ABF98F /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 07120DF5296EDF7A00ABF98F /* SnapKit */; }; + 071E0541296BB7B50020282F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 071E0540296BB7B50020282F /* AppDelegate.swift */; }; + 071E0543296BB7B50020282F /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 071E0542296BB7B50020282F /* SceneDelegate.swift */; }; + 071E0545296BB7B50020282F /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 071E0544296BB7B50020282F /* ViewController.swift */; }; + 071E054A296BB7B70020282F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 071E0549296BB7B70020282F /* Assets.xcassets */; }; + 07557561296BFC5900B8AF77 /* MainTabController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07557560296BFC5900B8AF77 /* MainTabController.swift */; }; + F02807672979628100DDA7B1 /* ChartMarker.swift in Sources */ = {isa = PBXBuildFile; fileRef = F02807662979628100DDA7B1 /* ChartMarker.swift */; }; + F028076A297962AD00DDA7B1 /* Charts in Frameworks */ = {isa = PBXBuildFile; productRef = F0280769297962AD00DDA7B1 /* Charts */; }; + F028076C297962BF00DDA7B1 /* StockDateSegmentControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = F028076B297962BF00DDA7B1 /* StockDateSegmentControl.swift */; }; + F02EFA8B297F76CC00BA34B1 /* ResellPrice.swift in Sources */ = {isa = PBXBuildFile; fileRef = F02EFA8A297F76CC00BA34B1 /* ResellPrice.swift */; }; + F037E0602983936700C42A42 /* EstateDetailCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F037E05F2983936700C42A42 /* EstateDetailCell.swift */; }; + F045C16129756C0200E71129 /* LoginController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F045C16029756C0200E71129 /* LoginController.swift */; }; + F045C16329756C0F00E71129 /* RegisterationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F045C16229756C0F00E71129 /* RegisterationController.swift */; }; + F045C16929756C6B00E71129 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F045C16829756C6B00E71129 /* LaunchScreen.storyboard */; }; + F047B2D12970515700810AB4 /* SellAssetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F047B2D02970515700810AB4 /* SellAssetView.swift */; }; + F047B2D62970912600810AB4 /* UnderlineSegmentedControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = F047B2D52970912600810AB4 /* UnderlineSegmentedControl.swift */; }; + F047B2D82970955100810AB4 /* asset.swift in Sources */ = {isa = PBXBuildFile; fileRef = F047B2D72970955100810AB4 /* asset.swift */; }; + F047B2DA297154C400810AB4 /* UnderlineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F047B2D9297154C400810AB4 /* UnderlineView.swift */; }; + F047B2DC2971B5AC00810AB4 /* HomeTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F047B2DB2971B5AC00810AB4 /* HomeTableCell.swift */; }; + F047B2DE2972E06100810AB4 /* AssetModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F047B2DD2972E06100810AB4 /* AssetModel.swift */; }; + F049AEEB2988AD3500BBC8AA /* StockChartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F049AEEA2988AD3500BBC8AA /* StockChartViewController.swift */; }; + F04A11F3297D00860074C0ED /* realEstates.swift in Sources */ = {isa = PBXBuildFile; fileRef = F04A11F2297D00860074C0ED /* realEstates.swift */; }; + F04A11F5297D01600074C0ED /* EstatePriceModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F04A11F4297D01600074C0ED /* EstatePriceModel.swift */; }; + F04A11F7297D1DA10074C0ED /* ChartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F04A11F6297D1DA10074C0ED /* ChartViewController.swift */; }; + F04A11F9297D50E20074C0ED /* StockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F04A11F8297D50E20074C0ED /* StockView.swift */; }; + F04A1201297E65AF0074C0ED /* TableCellModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F04A1200297E65AF0074C0ED /* TableCellModel.swift */; }; + F04A1204297E7D350074C0ED /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = F04A1203297E7D350074C0ED /* Kingfisher */; }; + F04A1207297EC46C0074C0ED /* resellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F04A1206297EC46C0074C0ED /* resellView.swift */; }; + F09CA69A297AFB870017E2A6 /* StockPrice.swift in Sources */ = {isa = PBXBuildFile; fileRef = F09CA699297AFB870017E2A6 /* StockPrice.swift */; }; + F09CA69C297AFCE60017E2A6 /* StockPriceModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F09CA69B297AFCE60017E2A6 /* StockPriceModel.swift */; }; + F0C7CBAF296EF260007C8BCE /* HomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0C7CBAE296EF260007C8BCE /* HomeViewController.swift */; }; + F0C7CBB1296EF269007C8BCE /* ExploreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0C7CBB0296EF269007C8BCE /* ExploreViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 071E053D296BB7B50020282F /* LGHTSG.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LGHTSG.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 071E0540296BB7B50020282F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 071E0542296BB7B50020282F /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 071E0544296BB7B50020282F /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 071E0549296BB7B70020282F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 071E054E296BB7B70020282F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 07557560296BFC5900B8AF77 /* MainTabController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabController.swift; sourceTree = ""; }; + F02807662979628100DDA7B1 /* ChartMarker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartMarker.swift; sourceTree = ""; }; + F028076B297962BF00DDA7B1 /* StockDateSegmentControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StockDateSegmentControl.swift; sourceTree = ""; }; + F02EFA8A297F76CC00BA34B1 /* ResellPrice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResellPrice.swift; sourceTree = ""; }; + F037E05F2983936700C42A42 /* EstateDetailCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EstateDetailCell.swift; sourceTree = ""; }; + F045C16029756C0200E71129 /* LoginController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginController.swift; sourceTree = ""; }; + F045C16229756C0F00E71129 /* RegisterationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RegisterationController.swift; sourceTree = ""; }; + F045C16829756C6B00E71129 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; + F047B2D02970515700810AB4 /* SellAssetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SellAssetView.swift; sourceTree = ""; }; + F047B2D52970912600810AB4 /* UnderlineSegmentedControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnderlineSegmentedControl.swift; sourceTree = ""; }; + F047B2D72970955100810AB4 /* asset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = asset.swift; path = LGHTSG/View/Home/asset.swift; sourceTree = SOURCE_ROOT; }; + F047B2D9297154C400810AB4 /* UnderlineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnderlineView.swift; sourceTree = ""; }; + F047B2DB2971B5AC00810AB4 /* HomeTableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTableCell.swift; sourceTree = ""; }; + F047B2DD2972E06100810AB4 /* AssetModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AssetModel.swift; path = LGHTSG/View/Home/AssetModel.swift; sourceTree = SOURCE_ROOT; }; + F049AEEA2988AD3500BBC8AA /* StockChartViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StockChartViewController.swift; sourceTree = ""; }; + F04A11F2297D00860074C0ED /* realEstates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = realEstates.swift; sourceTree = ""; }; + F04A11F4297D01600074C0ED /* EstatePriceModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = EstatePriceModel.swift; path = LGHTSG/Model/EstatePriceModel.swift; sourceTree = SOURCE_ROOT; }; + F04A11F6297D1DA10074C0ED /* ChartViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChartViewController.swift; sourceTree = ""; }; + F04A11F8297D50E20074C0ED /* StockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StockView.swift; sourceTree = ""; }; + F04A1200297E65AF0074C0ED /* TableCellModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableCellModel.swift; sourceTree = SOURCE_ROOT; }; + F04A1206297EC46C0074C0ED /* resellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = resellView.swift; sourceTree = ""; }; + F09CA699297AFB870017E2A6 /* StockPrice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StockPrice.swift; sourceTree = ""; }; + F09CA69B297AFCE60017E2A6 /* StockPriceModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StockPriceModel.swift; sourceTree = SOURCE_ROOT; }; + F0C7CBAE296EF260007C8BCE /* HomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = ""; }; + F0C7CBB0296EF269007C8BCE /* ExploreViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreViewController.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 071E053A296BB7B50020282F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F04A1204297E7D350074C0ED /* Kingfisher in Frameworks */, + 07120DF3296EDF6E00ABF98F /* Alamofire in Frameworks */, + F028076A297962AD00DDA7B1 /* Charts in Frameworks */, + 07120DF6296EDF7A00ABF98F /* SnapKit in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 071E0534296BB7B50020282F = { + isa = PBXGroup; + children = ( + 071E053F296BB7B50020282F /* LGHTSG */, + 071E053E296BB7B50020282F /* Products */, + ); + sourceTree = ""; + }; + 071E053E296BB7B50020282F /* Products */ = { + isa = PBXGroup; + children = ( + 071E053D296BB7B50020282F /* LGHTSG.app */, + ); + name = Products; + sourceTree = ""; + }; + 071E053F296BB7B50020282F /* LGHTSG */ = { + isa = PBXGroup; + children = ( + 071E0554296BB8210020282F /* Model */, + 071E0558296BB8510020282F /* View */, + 071E0556296BB8380020282F /* ViewModel */, + 071E055A296BB88B0020282F /* Controller */, + 071E0557296BB83F0020282F /* Network */, + 071E0555296BB82F0020282F /* App */, + 071E0544296BB7B50020282F /* ViewController.swift */, + 071E0549296BB7B70020282F /* Assets.xcassets */, + F045C16829756C6B00E71129 /* LaunchScreen.storyboard */, + 071E054E296BB7B70020282F /* Info.plist */, + 071E0559296BB86E0020282F /* Font */, + ); + path = LGHTSG; + sourceTree = ""; + }; + 071E0554296BB8210020282F /* Model */ = { + isa = PBXGroup; + children = ( + F047B2D72970955100810AB4 /* asset.swift */, + F09CA699297AFB870017E2A6 /* StockPrice.swift */, + F02EFA8A297F76CC00BA34B1 /* ResellPrice.swift */, + F04A11F2297D00860074C0ED /* realEstates.swift */, + ); + path = Model; + sourceTree = ""; + }; + 071E0555296BB82F0020282F /* App */ = { + isa = PBXGroup; + children = ( + 071E0540296BB7B50020282F /* AppDelegate.swift */, + 071E0542296BB7B50020282F /* SceneDelegate.swift */, + ); + path = App; + sourceTree = ""; + }; + 071E0556296BB8380020282F /* ViewModel */ = { + isa = PBXGroup; + children = ( + F04A1200297E65AF0074C0ED /* TableCellModel.swift */, + F047B2DD2972E06100810AB4 /* AssetModel.swift */, + F09CA69B297AFCE60017E2A6 /* StockPriceModel.swift */, + F04A11F4297D01600074C0ED /* EstatePriceModel.swift */, + ); + path = ViewModel; + sourceTree = ""; + }; + 071E0557296BB83F0020282F /* Network */ = { + isa = PBXGroup; + children = ( + ); + path = Network; + sourceTree = ""; + }; + 071E0558296BB8510020282F /* View */ = { + isa = PBXGroup; + children = ( + F047B2D02970515700810AB4 /* SellAssetView.swift */, + F04A1205297EC4590074C0ED /* Explore */, + F047B2D229705CCA00810AB4 /* Home */, + ); + path = View; + sourceTree = ""; + }; + 071E0559296BB86E0020282F /* Font */ = { + isa = PBXGroup; + children = ( + ); + path = Font; + sourceTree = ""; + }; + 071E055A296BB88B0020282F /* Controller */ = { + isa = PBXGroup; + children = ( + 0755755A296BFC2100B8AF77 /* Authentication */, + 07557560296BFC5900B8AF77 /* MainTabController.swift */, + F0C7CBAE296EF260007C8BCE /* HomeViewController.swift */, + F0C7CBB0296EF269007C8BCE /* ExploreViewController.swift */, + F049AEEA2988AD3500BBC8AA /* StockChartViewController.swift */, + F04A11F6297D1DA10074C0ED /* ChartViewController.swift */, + ); + path = Controller; + sourceTree = ""; + }; + 0755755A296BFC2100B8AF77 /* Authentication */ = { + isa = PBXGroup; + children = ( + F045C16029756C0200E71129 /* LoginController.swift */, + F045C16229756C0F00E71129 /* RegisterationController.swift */, + ); + path = Authentication; + sourceTree = ""; + }; + F047B2D229705CCA00810AB4 /* Home */ = { + isa = PBXGroup; + children = ( + F047B2D9297154C400810AB4 /* UnderlineView.swift */, + F047B2DB2971B5AC00810AB4 /* HomeTableCell.swift */, + F047B2D52970912600810AB4 /* UnderlineSegmentedControl.swift */, + F02807662979628100DDA7B1 /* ChartMarker.swift */, + F028076B297962BF00DDA7B1 /* StockDateSegmentControl.swift */, + ); + path = Home; + sourceTree = ""; + }; + F04A1205297EC4590074C0ED /* Explore */ = { + isa = PBXGroup; + children = ( + F04A11F8297D50E20074C0ED /* StockView.swift */, + F04A1206297EC46C0074C0ED /* resellView.swift */, + F037E05F2983936700C42A42 /* EstateDetailCell.swift */, + ); + path = Explore; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 071E053C296BB7B50020282F /* LGHTSG */ = { + isa = PBXNativeTarget; + buildConfigurationList = 071E0551296BB7B70020282F /* Build configuration list for PBXNativeTarget "LGHTSG" */; + buildPhases = ( + 071E0539296BB7B50020282F /* Sources */, + 071E053A296BB7B50020282F /* Frameworks */, + 071E053B296BB7B50020282F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LGHTSG; + packageProductDependencies = ( + 07120DF2296EDF6E00ABF98F /* Alamofire */, + 07120DF5296EDF7A00ABF98F /* SnapKit */, + F0280769297962AD00DDA7B1 /* Charts */, + F04A1203297E7D350074C0ED /* Kingfisher */, + ); + productName = LGHTSG; + productReference = 071E053D296BB7B50020282F /* LGHTSG.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 071E0535296BB7B50020282F /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1400; + LastUpgradeCheck = 1400; + TargetAttributes = { + 071E053C296BB7B50020282F = { + CreatedOnToolsVersion = 14.0.1; + }; + }; + }; + buildConfigurationList = 071E0538296BB7B50020282F /* Build configuration list for PBXProject "LGHTSG" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 071E0534296BB7B50020282F; + packageReferences = ( + 07120DF1296EDF6E00ABF98F /* XCRemoteSwiftPackageReference "Alamofire" */, + 07120DF4296EDF7A00ABF98F /* XCRemoteSwiftPackageReference "SnapKit" */, + F0280768297962AD00DDA7B1 /* XCRemoteSwiftPackageReference "Charts" */, + F04A1202297E7D350074C0ED /* XCRemoteSwiftPackageReference "Kingfisher" */, + ); + productRefGroup = 071E053E296BB7B50020282F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 071E053C296BB7B50020282F /* LGHTSG */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 071E053B296BB7B50020282F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F045C16929756C6B00E71129 /* LaunchScreen.storyboard in Resources */, + 071E054A296BB7B70020282F /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 071E0539296BB7B50020282F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F02807672979628100DDA7B1 /* ChartMarker.swift in Sources */, + F028076C297962BF00DDA7B1 /* StockDateSegmentControl.swift in Sources */, + 071E0545296BB7B50020282F /* ViewController.swift in Sources */, + F0C7CBB1296EF269007C8BCE /* ExploreViewController.swift in Sources */, + F04A11F3297D00860074C0ED /* realEstates.swift in Sources */, + F047B2D82970955100810AB4 /* asset.swift in Sources */, + 07557561296BFC5900B8AF77 /* MainTabController.swift in Sources */, + F047B2D12970515700810AB4 /* SellAssetView.swift in Sources */, + F04A11F9297D50E20074C0ED /* StockView.swift in Sources */, + F047B2DA297154C400810AB4 /* UnderlineView.swift in Sources */, + F04A1201297E65AF0074C0ED /* TableCellModel.swift in Sources */, + F02EFA8B297F76CC00BA34B1 /* ResellPrice.swift in Sources */, + F047B2DC2971B5AC00810AB4 /* HomeTableCell.swift in Sources */, + 071E0541296BB7B50020282F /* AppDelegate.swift in Sources */, + F037E0602983936700C42A42 /* EstateDetailCell.swift in Sources */, + F04A1207297EC46C0074C0ED /* resellView.swift in Sources */, + F049AEEB2988AD3500BBC8AA /* StockChartViewController.swift in Sources */, + F0C7CBAF296EF260007C8BCE /* HomeViewController.swift in Sources */, + 071E0543296BB7B50020282F /* SceneDelegate.swift in Sources */, + F047B2D62970912600810AB4 /* UnderlineSegmentedControl.swift in Sources */, + F04A11F5297D01600074C0ED /* EstatePriceModel.swift in Sources */, + F045C16329756C0F00E71129 /* RegisterationController.swift in Sources */, + F09CA69A297AFB870017E2A6 /* StockPrice.swift in Sources */, + F045C16129756C0200E71129 /* LoginController.swift in Sources */, + F09CA69C297AFCE60017E2A6 /* StockPriceModel.swift in Sources */, + F047B2DE2972E06100810AB4 /* AssetModel.swift in Sources */, + F04A11F7297D1DA10074C0ED /* ChartViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 071E054F296BB7B70020282F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 071E0550296BB7B70020282F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 071E0552296BB7B70020282F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = NG2NLR2Z86; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = LGHTSG/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.Hha.LGHTSG; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 071E0553296BB7B70020282F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = NG2NLR2Z86; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = LGHTSG/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.Ha.LGHTSG; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 071E0538296BB7B50020282F /* Build configuration list for PBXProject "LGHTSG" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 071E054F296BB7B70020282F /* Debug */, + 071E0550296BB7B70020282F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 071E0551296BB7B70020282F /* Build configuration list for PBXNativeTarget "LGHTSG" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 071E0552296BB7B70020282F /* Debug */, + 071E0553296BB7B70020282F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 07120DF1296EDF6E00ABF98F /* XCRemoteSwiftPackageReference "Alamofire" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Alamofire/Alamofire.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.0.0; + }; + }; + 07120DF4296EDF7A00ABF98F /* XCRemoteSwiftPackageReference "SnapKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/SnapKit/SnapKit.git"; + requirement = { + branch = develop; + kind = branch; + }; + }; + F0280768297962AD00DDA7B1 /* XCRemoteSwiftPackageReference "Charts" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/danielgindi/Charts.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 4.0.0; + }; + }; + F04A1202297E7D350074C0ED /* XCRemoteSwiftPackageReference "Kingfisher" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/onevcat/Kingfisher.git"; + requirement = { + branch = master; + kind = branch; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 07120DF2296EDF6E00ABF98F /* Alamofire */ = { + isa = XCSwiftPackageProductDependency; + package = 07120DF1296EDF6E00ABF98F /* XCRemoteSwiftPackageReference "Alamofire" */; + productName = Alamofire; + }; + 07120DF5296EDF7A00ABF98F /* SnapKit */ = { + isa = XCSwiftPackageProductDependency; + package = 07120DF4296EDF7A00ABF98F /* XCRemoteSwiftPackageReference "SnapKit" */; + productName = SnapKit; + }; + F0280769297962AD00DDA7B1 /* Charts */ = { + isa = XCSwiftPackageProductDependency; + package = F0280768297962AD00DDA7B1 /* XCRemoteSwiftPackageReference "Charts" */; + productName = Charts; + }; + F04A1203297E7D350074C0ED /* Kingfisher */ = { + isa = XCSwiftPackageProductDependency; + package = F04A1202297E7D350074C0ED /* XCRemoteSwiftPackageReference "Kingfisher" */; + productName = Kingfisher; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 071E0535296BB7B50020282F /* Project object */; +} diff --git a/LGHTSG/LGHTSG.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/LGHTSG/LGHTSG.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/LGHTSG/LGHTSG.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/LGHTSG/LGHTSG.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/LGHTSG/LGHTSG.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/LGHTSG/LGHTSG.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/LGHTSG/LGHTSG.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/LGHTSG/LGHTSG.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..da58692 --- /dev/null +++ b/LGHTSG/LGHTSG.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,59 @@ +{ + "pins" : [ + { + "identity" : "alamofire", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/Alamofire.git", + "state" : { + "revision" : "78424be314842833c04bc3bef5b72e85fff99204", + "version" : "5.6.4" + } + }, + { + "identity" : "charts", + "kind" : "remoteSourceControl", + "location" : "https://github.com/danielgindi/Charts.git", + "state" : { + "revision" : "07b23476ad52b926be772f317d8f1d4511ee8d02", + "version" : "4.1.0" + } + }, + { + "identity" : "kingfisher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/onevcat/Kingfisher.git", + "state" : { + "branch" : "master", + "revision" : "3f179d840692d83978fa41eaad11caef68a8f418" + } + }, + { + "identity" : "snapkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SnapKit/SnapKit.git", + "state" : { + "branch" : "develop", + "revision" : "58320fe80522414bf3a7e24c88123581dc586752" + } + }, + { + "identity" : "swift-algorithms", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-algorithms", + "state" : { + "revision" : "b14b7f4c528c942f121c8b860b9410b2bf57825e", + "version" : "1.0.0" + } + }, + { + "identity" : "swift-numerics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-numerics", + "state" : { + "revision" : "0a5bc04095a675662cf24757cc0640aa2204253b", + "version" : "1.0.2" + } + } + ], + "version" : 2 +} diff --git a/LGHTSG/LGHTSG/App/AppDelegate.swift b/LGHTSG/LGHTSG/App/AppDelegate.swift new file mode 100644 index 0000000..e9ea301 --- /dev/null +++ b/LGHTSG/LGHTSG/App/AppDelegate.swift @@ -0,0 +1,36 @@ +// +// AppDelegate.swift +// LGHTSG +// +// Created by HA on 2023/01/09. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/LGHTSG/LGHTSG/App/SceneDelegate.swift b/LGHTSG/LGHTSG/App/SceneDelegate.swift new file mode 100644 index 0000000..e4aeb6d --- /dev/null +++ b/LGHTSG/LGHTSG/App/SceneDelegate.swift @@ -0,0 +1,54 @@ +// +// SceneDelegate.swift +// LGHTSG +// +// Created by HA on 2023/01/09. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + guard let windowscene = (scene as? UIWindowScene) else { return } + window = UIWindow(windowScene: windowscene) + window?.backgroundColor = .systemBackground + window?.rootViewController = UINavigationController(rootViewController: MainTabController()) + window?.tintColor = .label + window?.makeKeyAndVisible() + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/LGHTSG/LGHTSG/Assets.xcassets/AppIcon.appiconset/Contents.json b/LGHTSG/LGHTSG/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..13613e3 --- /dev/null +++ b/LGHTSG/LGHTSG/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,13 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/LGHTSG/LGHTSG/Assets.xcassets/Contents.json b/LGHTSG/LGHTSG/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/LGHTSG/LGHTSG/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/LGHTSG/LGHTSG/Assets.xcassets/compass.imageset/Contents.json b/LGHTSG/LGHTSG/Assets.xcassets/compass.imageset/Contents.json new file mode 100644 index 0000000..9ce3942 --- /dev/null +++ b/LGHTSG/LGHTSG/Assets.xcassets/compass.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "compass.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" + } +} diff --git a/LGHTSG/LGHTSG/Assets.xcassets/compass.imageset/compass.png b/LGHTSG/LGHTSG/Assets.xcassets/compass.imageset/compass.png new file mode 100644 index 0000000..718e506 Binary files /dev/null and b/LGHTSG/LGHTSG/Assets.xcassets/compass.imageset/compass.png differ diff --git a/LGHTSG/LGHTSG/Assets.xcassets/compass2.imageset/Contents.json b/LGHTSG/LGHTSG/Assets.xcassets/compass2.imageset/Contents.json new file mode 100644 index 0000000..c89b35b --- /dev/null +++ b/LGHTSG/LGHTSG/Assets.xcassets/compass2.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "compass-2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" + } +} diff --git a/LGHTSG/LGHTSG/Assets.xcassets/compass2.imageset/compass-2.png b/LGHTSG/LGHTSG/Assets.xcassets/compass2.imageset/compass-2.png new file mode 100644 index 0000000..d4b512e Binary files /dev/null and b/LGHTSG/LGHTSG/Assets.xcassets/compass2.imageset/compass-2.png differ diff --git a/LGHTSG/LGHTSG/Assets.xcassets/home.imageset/Contents.json b/LGHTSG/LGHTSG/Assets.xcassets/home.imageset/Contents.json new file mode 100644 index 0000000..5cb0b3b --- /dev/null +++ b/LGHTSG/LGHTSG/Assets.xcassets/home.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "home.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" + } +} diff --git a/LGHTSG/LGHTSG/Assets.xcassets/home.imageset/home.png b/LGHTSG/LGHTSG/Assets.xcassets/home.imageset/home.png new file mode 100644 index 0000000..c38d68e Binary files /dev/null and b/LGHTSG/LGHTSG/Assets.xcassets/home.imageset/home.png differ diff --git a/LGHTSG/LGHTSG/Assets.xcassets/home2.imageset/Contents.json b/LGHTSG/LGHTSG/Assets.xcassets/home2.imageset/Contents.json new file mode 100644 index 0000000..5246f25 --- /dev/null +++ b/LGHTSG/LGHTSG/Assets.xcassets/home2.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "home-2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" + } +} diff --git a/LGHTSG/LGHTSG/Assets.xcassets/home2.imageset/home-2.png b/LGHTSG/LGHTSG/Assets.xcassets/home2.imageset/home-2.png new file mode 100644 index 0000000..4a947c7 Binary files /dev/null and b/LGHTSG/LGHTSG/Assets.xcassets/home2.imageset/home-2.png differ diff --git a/LGHTSG/LGHTSG/Assets.xcassets/profile.imageset/Contents.json b/LGHTSG/LGHTSG/Assets.xcassets/profile.imageset/Contents.json new file mode 100644 index 0000000..e80e22e --- /dev/null +++ b/LGHTSG/LGHTSG/Assets.xcassets/profile.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "filename" : "profile.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" + } +} diff --git a/LGHTSG/LGHTSG/Assets.xcassets/profile.imageset/profile.png b/LGHTSG/LGHTSG/Assets.xcassets/profile.imageset/profile.png new file mode 100644 index 0000000..2be7384 Binary files /dev/null and b/LGHTSG/LGHTSG/Assets.xcassets/profile.imageset/profile.png differ diff --git a/LGHTSG/LGHTSG/Controller/Authentication/LoginController.swift b/LGHTSG/LGHTSG/Controller/Authentication/LoginController.swift new file mode 100644 index 0000000..d28a364 --- /dev/null +++ b/LGHTSG/LGHTSG/Controller/Authentication/LoginController.swift @@ -0,0 +1,18 @@ +// +// LoginController.swift +// LGHTSG +// +// Created by HA on 2023/01/09. +// + +import UIKit + +class LoginController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + } + + +} diff --git a/LGHTSG/LGHTSG/Controller/Authentication/RegisterationController.swift b/LGHTSG/LGHTSG/Controller/Authentication/RegisterationController.swift new file mode 100644 index 0000000..fd143e3 --- /dev/null +++ b/LGHTSG/LGHTSG/Controller/Authentication/RegisterationController.swift @@ -0,0 +1,18 @@ +// +// RegisterationController.swift +// LGHTSG +// +// Created by HA on 2023/01/09. +// + +import UIKit + +class RegisterationController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + } + + +} diff --git a/LGHTSG/LGHTSG/Controller/ChartViewController.swift b/LGHTSG/LGHTSG/Controller/ChartViewController.swift new file mode 100644 index 0000000..dbc2d17 --- /dev/null +++ b/LGHTSG/LGHTSG/Controller/ChartViewController.swift @@ -0,0 +1,368 @@ +// +// ChartViewController.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/22. +// +import UIKit +import Charts +import Kingfisher +import SnapKit +import Foundation + +class ChartViewController : UIViewController { + var stockPriceData = StockPriceModel() + var EstatePriceData = EstatePriceModel() + var nameText : String? + var PriceText : String? + var idx : Int? + + var pricePercentText : String? + var changeDateText : String? + var imageURL : String? + var priceListDatas = [Int]() + var timeListDatas = [String]() + let contentView = UIView() + private let contentScrollView : UIScrollView = { + let scrollview = UIScrollView() + scrollview.backgroundColor = .systemBackground + scrollview.translatesAutoresizingMaskIntoConstraints = false + return scrollview + }() + lazy var lineChartView : LineChartView = { + let chartView = LineChartView() + return chartView + }() + private lazy var nameLabel : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 16, weight: .semibold) + label.text = nameText + return label + }() + private lazy var priceLabel : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 14, weight: .medium) + label.textColor = UIColor.systemGray + label.text = PriceText + return label + }() + private lazy var pricePercent : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 12, weight: .medium) + label.textColor = UIColor.red + label.text = pricePercentText + return label + }() + private lazy var changeDate : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 12, weight : .medium) + label.textColor = UIColor.systemGray + label.text = changeDateText + return label + }() + //MARK: - Label + private lazy var dealLabel: UILabel = { + let label = UILabel() + label.text = "거래 이력" + label.font = UIFont.systemFont(ofSize: 12, weight: .light) + label.textColor = .white + return label + }() + + private lazy var revenueLabel: UILabel = { + let label = UILabel() + label.text = "구매 시점에 비해 얼마 올랐어요" + label.textColor = .white + label.font = UIFont.systemFont(ofSize: 16, weight: .bold) + return label + }() + private lazy var imageView : UIImageView = { + let imgview = UIImageView() + if let imageURL = imageURL{ + let url = URL(string: imageURL) + imgview.kf.setImage(with: url) + } + return imgview + }() + + private var lineImage = UnderlineView() + + + //MARK: - SegmentControl + private lazy var segmentCtrl: UISegmentedControl = { + let items = ["일","월", "1년", "3년"] + let seg = UISegmentedControl(items: items) + seg.addTarget(self, action: #selector(indexChanged(_:)), for: .valueChanged) + seg.layer.cornerRadius = 0.7 + seg.backgroundColor = UIColor(named: "dropdown") + seg.tintColor = .lightGray + seg.setTitleTextAttributes( + [ + NSAttributedString.Key.foregroundColor: UIColor.white, + .font: UIFont.systemFont(ofSize: 14, weight: .semibold) + ], + for: .selected + ) + seg.setTitleTextAttributes( + [ + NSAttributedString.Key.foregroundColor: UIColor.systemGray, + .font: UIFont.systemFont(ofSize: 14, weight: .semibold) + ], + for: .normal + ) + seg.selectedSegmentIndex = 1 + return seg + }() + + //MARK: - Button + private lazy var sellButton: UIButton = { + let btn = UIButton() + btn.setTitle("판매", for: .normal) + btn.setTitleColor(.blue, for: .normal) + btn.backgroundColor = .white + btn.layer.cornerRadius = 5 + btn.layer.borderWidth = 1 + return btn + + }() + + //MARK: - TableView + private lazy var tableView: UITableView = { + let table = UITableView() + table.backgroundColor = .clear + return table + + }() + + //MARK: - LifeCycle + override func viewDidLoad() { + super.viewDidLoad() + + setLineChartView() + configure() + + } + //MARK: - TableViewSetting + func setupTableView(){ + contentView.addSubview(tableView) + tableView.delegate = self + tableView.dataSource = self + tableView.register(EstateDetailCell.self, forCellReuseIdentifier: EstateDetailCell.identifier) + tableView.separatorStyle = .none + tableView.snp.makeConstraints{ + $0.top.equalTo(lineImage.snp.bottom) + $0.height.equalTo(120) + $0.leading.equalToSuperview().inset(33) + $0.trailing.equalToSuperview().inset(33) + $0.bottom.equalTo(sellButton.snp.top ).offset(-10) + + } + } + @objc func indexChanged(_ sender: UISegmentedControl){ + switch sender.selectedSegmentIndex{ + case 0: + + let daypricedata : [Int] = priceListDatas.suffix(30) + let daytimeListDatas : [String] = timeListDatas.suffix(30) + self.setLineData(lineChartView: self.lineChartView, lineChartDataEntries: self.entryData( yvalues: daypricedata), xAxis: daytimeListDatas, recentPrice : Double(daypricedata.last!)) + tableView.reloadData() + case 1: + let monthpricedata : [Int] = priceListDatas.suffix(90) + let monthtimeListDatas : [String] = timeListDatas.suffix(90) + self.setLineData(lineChartView: self.lineChartView, lineChartDataEntries: self.entryData( yvalues: monthpricedata), xAxis: monthtimeListDatas, recentPrice : Double(monthpricedata.last!)) + tableView.reloadData() + case 2: +// let keydate = Calendar(identifier: .gregorian).date(byAdding: , to: <#T##Date#>) + print("3년") + case 3: + print("5년") + default: + break + } + } +} +extension ChartViewController : UITableViewDelegate, UITableViewDataSource { + //cell 높이조절 + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 30 + } + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return timeListDatas.count } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = tableView.dequeueReusableCell(withIdentifier: EstateDetailCell.identifier, for: indexPath) as? EstateDetailCell else { return UITableViewCell() } + + cell.date.text = timeListDatas[indexPath.row] + cell.date.textColor = .white + cell.price.text = "\(priceListDatas[indexPath.row])원" + cell.price.textColor = .white + cell.buysell.text = "hello" + cell.buysell.textColor = .white + return cell + } +} +extension ChartViewController { + func setLineData(lineChartView: LineChartView, lineChartDataEntries: [ChartDataEntry], xAxis : [String], recentPrice : Double) { + // Entry들을 이용해 Data Set 만들기(그런데 우리는 각 포인트를 나타내줄 필요가 없어서 지워줌 + let lineChartdataSet = LineChartDataSet(entries: lineChartDataEntries, label: "주가") + lineChartdataSet.drawValuesEnabled = false + lineChartdataSet.drawCirclesEnabled = false + lineChartdataSet.colors = [.blue] + //선택했을때 라인 지워주기 + lineChartdataSet.drawHorizontalHighlightIndicatorEnabled = false +// lineChartdataSet.drawVerticalHighlightIndicatorEnabled = false + lineChartdataSet.highlightColor = .white + + // DataSet을 차트 데이터로 넣기 + let lineChartData = LineChartData(dataSet: lineChartdataSet) + // 데이터 출력 + lineChartView.data = lineChartData + // 선제거 + lineChartView.leftAxis.drawGridLinesEnabled = false + lineChartView.rightAxis.drawGridLinesEnabled = false + lineChartView.leftAxis.enabled = false // 왼쪽 label 값 지워주기 + lineChartView.rightAxis.enabled = false // right + lineChartView.xAxis.enabled = false // 위쪽 label + lineChartView.xAxis.drawGridLinesEnabled = false + lineChartView.xAxis.drawAxisLineEnabled = false + lineChartView.doubleTapToZoomEnabled = false + // 아래 뜨는 어떤항목인지 알려주는 label 제거 + lineChartView.legend.enabled = false + lineChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: xAxis) + + let marker = ChartMarker(pricedate: xAxis, recentprice: recentPrice) + marker.chartView = lineChartView + marker.chartx = contentView.frame.width - 10 + lineChartView.marker = marker + lineChartView.drawMarkers = true + // 데이터 소수점 제거 + let formatter = NumberFormatter() + formatter.minimumFractionDigits = 0 + lineChartView.data?.setValueFormatter(DefaultValueFormatter(formatter:formatter)) + } + // entry 만들기 + func entryData(yvalues: [Int]) -> [ChartDataEntry] { + // entry 담을 array + var lineDataEntries: [ChartDataEntry] = [] + // 담기 + for i in 0 ..< yvalues.count { + let lineDataEntry = ChartDataEntry(x: Double(i), y: Double(yvalues[i])) + lineDataEntries.append(lineDataEntry) + } + // 반환 + return lineDataEntries + } + private func setLineChartView() { + stockPriceData.requestResellPrice(resellIdx: self.idx!, onCompleted: { (pricelists, transctiontime) in + DispatchQueue.main.async { + self.priceListDatas = pricelists + self.timeListDatas = transctiontime + self.setLineData(lineChartView: self.lineChartView, lineChartDataEntries: self.entryData( yvalues: pricelists), xAxis: transctiontime, recentPrice : Double(pricelists.last!)) + + self.chartUI() + self.setupTableView() + + } + }) + + } + +// EstatePriceData.requestStockPrice(EstateIdx: self.idx!, onCompleted: { (pricelists, transctiontime) in +// DispatchQueue.main.async { +// self.view.addSubview(self.lineChartView) +// self.setLineData(lineChartView: self.lineChartView, lineChartDataEntries: self.entryData( yvalues: pricelists), xAxis: transctiontime, recentPrice : Double(pricelists.last!)) +//// self.lineChartView.snp.makeConstraints{ +//// $0.leading.trailing.equalToSuperview() +//// $0.top.bottom.equalToSuperview().inset(140) +//// } +// } +// }) + + } + + +extension ChartViewController { + //MARK: - Configure + private func chartUI(){ + [lineChartView, imageView,lineImage,dealLabel, revenueLabel, segmentCtrl].forEach{contentView.addSubview($0)} + lineChartView.snp.makeConstraints{ + $0.top.equalTo(priceLabel.snp.bottom).offset(20) +// $0.width.equalTo(contentView.snp.width) + $0.leading.trailing.equalTo(contentView ).inset(15) + $0.height.equalTo(270) +// $0.bottom.equalTo(segmentCtrl.snp.top).inset(8) + } + + segmentCtrl.snp.makeConstraints{ + $0.top.equalTo(lineChartView.snp.bottom) + $0.leading.equalTo(contentView.snp.leading).offset(15) + $0.trailing.equalTo(contentView.snp.trailing).offset(-15) + } + imageView.snp.makeConstraints{ + $0.top.equalTo(segmentCtrl.snp.bottom).offset(10) + if imageURL != nil { + $0.width.height.equalTo(300) + }else{ + $0.width.height.equalTo(0) + } + $0.centerX.equalToSuperview() + } + revenueLabel.snp.makeConstraints{ + $0.leading.equalToSuperview().inset(33) + $0.top.equalTo(imageView.snp.bottom).offset(10) + } + + dealLabel.snp.makeConstraints{ + $0.top.equalTo(revenueLabel.snp.bottom).offset(10) + $0.leading.equalToSuperview().inset(33) + } + lineImage.snp.makeConstraints{ + $0.leading.equalToSuperview().inset(33) + $0.trailing.equalToSuperview().inset(33) + $0.height.equalTo(1) + $0.top.equalTo(dealLabel.snp.bottom).offset(4) + } + + + } + private func configure(){ + lineImage.backgroundColor = .label + self.view.addSubview(contentScrollView) + // 스크롤뷰 세로로 + contentScrollView.addSubview(contentView) + [ nameLabel, priceLabel, pricePercent,changeDate, sellButton] + .forEach {contentView.addSubview($0)} + contentScrollView.snp.makeConstraints{ + $0.top.leading.trailing.bottom.equalTo(view.safeAreaLayoutGuide ) + } + contentView.snp.makeConstraints{ + $0.top.leading.trailing.bottom.equalTo(contentScrollView.contentLayoutGuide) + $0.width.equalTo(contentScrollView.frameLayoutGuide) + } + + nameLabel.snp.makeConstraints{ + $0.top.equalTo(contentView).offset(10) + $0.leading.equalTo(contentView.snp.leading).inset(15) + + } + priceLabel.snp.makeConstraints{ + $0.top.equalTo(nameLabel.snp.bottom).offset(8) + $0.leading.equalTo(nameLabel.snp.leading) + } + pricePercent.snp.makeConstraints{ + $0.top.equalTo(nameLabel.snp.bottom).offset(9) + $0.leading.equalTo(priceLabel.snp.trailing).offset(8) + } + changeDate.snp.makeConstraints{ + $0.top.equalTo(nameLabel.snp.bottom).offset(10) + $0.leading.equalTo(pricePercent.snp.trailing).offset(8) + } + + sellButton.snp.makeConstraints{ + $0.bottom.equalToSuperview().offset(-10) + $0.height.equalTo(48) + $0.width.equalToSuperview().inset(20) + $0.centerX.equalToSuperview() + } + } +} diff --git a/LGHTSG/LGHTSG/Controller/ExploreViewController.swift b/LGHTSG/LGHTSG/Controller/ExploreViewController.swift new file mode 100644 index 0000000..2e82b2e --- /dev/null +++ b/LGHTSG/LGHTSG/Controller/ExploreViewController.swift @@ -0,0 +1,200 @@ +// +// ExploreViewController.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/11. +// + +import UIKit +import SnapKit +protocol searchDataFilterDelegate{ + func searchData(data : String) +} +class ExploreViewController : UIViewController { + var delegate1 : searchDataFilterDelegate? + var segmentControl = UnderlineSegmentedControl(items: ["Top", "부동산", "주식", "리셀"]) + let underline1 = UnderlineView() + let underline2 = UnderlineView() + let underline3 = UnderlineView() + let underline4 = UnderlineView() + var resellVC = resellView() + static var isSearching = false + let stockView = StockView() +// private lazy var reSellView : resellView = { +// let view = resellView(coder: NSCoder) +// return view +// }() + override func viewDidLoad() { + super.viewDidLoad() +// reSellView.delegate = self + stockView.delegate = self + SetNavigationBar() + setTobTabbar() + + } + func setTobTabbar(){ + view.addSubview(segmentControl) + view.addSubview(underline1) + view.addSubview(underline2) + view.addSubview(underline3) + view.addSubview(underline4) + segmentControl.addTarget(self, action: #selector(clickfoursegment), for: .valueChanged) + segmentControl.snp.makeConstraints{ + $0.top.equalTo(view.safeAreaLayoutGuide.snp.top) + $0.leading.trailing.equalToSuperview().inset(16) + $0.height.equalTo(48) + } + underline1.backgroundColor = .white + underline1.snp.makeConstraints{ + $0.leading.equalToSuperview().inset(18) + $0.height.equalTo(1) + $0.width.equalTo((view.frame.width - 36 - 12.5) / 4) + $0.top.equalTo(segmentControl.snp.bottom).offset(-8) + } + underline2.snp.makeConstraints{ + $0.leading.equalTo(underline1.snp.trailing).offset(4.5) + $0.height.equalTo(1) + $0.width.equalTo((view.frame.width - 36 - 12.5) / 4) + $0.top.equalTo(segmentControl.snp.bottom).offset(-8) + } + underline3.snp.makeConstraints{ + $0.leading.equalTo(underline2.snp.trailing).offset(3.5) + $0.height.equalTo(1) + $0.width.equalTo((view.frame.width - 36 - 12.5) / 4) + $0.top.equalTo(segmentControl.snp.bottom).offset(-8) + } + underline4.snp.makeConstraints{ + $0.leading.equalTo(underline3.snp.trailing).offset(4.5) + $0.height.equalTo(1) + $0.width.equalTo((view.frame.width - 36 - 12.5) / 4) + $0.top.equalTo(segmentControl.snp.bottom).offset(-8) + } + } + @objc func clickfoursegment(_ sender : UISegmentedControl){ + switch sender.selectedSegmentIndex { + case 0: + stockView.removeFromParent() + stockView.view.removeFromSuperview() + resellVC.removeFromParent() + resellVC.view.removeFromSuperview() + underline1.backgroundColor = .white + underline2.backgroundColor = .darkGray + underline3.backgroundColor = .darkGray + underline4.backgroundColor = .darkGray + + case 1: + stockView.removeFromParent() + stockView.view.removeFromSuperview() + resellVC.removeFromParent() + resellVC.view.removeFromSuperview() + underline1.backgroundColor = .darkGray + underline2.backgroundColor = .white + underline3.backgroundColor = .darkGray + underline4.backgroundColor = .darkGray + + case 2: + resellVC.removeFromParent() + resellVC.view.removeFromSuperview() + underline1.backgroundColor = .darkGray + underline2.backgroundColor = .darkGray + underline3.backgroundColor = .white + underline4.backgroundColor = .darkGray + self.addChild(stockView) + self.view.addSubview(stockView.view) + stockView.view.snp.makeConstraints{ + $0.leading.trailing.equalToSuperview().inset(23) + $0.top.equalTo(underline4.snp.bottom).offset(32) + $0.bottom.equalTo(view.safeAreaLayoutGuide) + } + + + case 3: + stockView.removeFromParent() + stockView.view.removeFromSuperview() + underline1.backgroundColor = .darkGray + underline2.backgroundColor = .darkGray + underline3.backgroundColor = .darkGray + underline4.backgroundColor = .white + + + resellVC.delegate = self + self.addChild(resellVC) + self.view.addSubview(resellVC.view) + resellVC.view.snp.makeConstraints{ + $0.leading.trailing.equalToSuperview().inset(23) + $0.top.equalTo(underline4.snp.bottom).offset(32) + $0.bottom.equalTo(view.safeAreaLayoutGuide) + } + + + +// reSellView.alpha = 1 + default: break + } + } +} +extension ExploreViewController : showNavigationDelegate{ + func showSearchBar() { + layoutSearchBar() + } + func hideSearchBar() { + SetNavigationBar() + } + func SetNavigationBar(){ + ExploreViewController.isSearching = false + navigationItem.titleView = nil + let searchBtn = UIBarButtonItem(image: UIImage(systemName : "magnifyingglass"), style: .plain, target: self, action: #selector(showsearchbar)) + navigationItem.leftBarButtonItem = searchBtn + var config = UIButton.Configuration.plain() + var attributeString = AttributedString("-93") + attributeString.font = .systemFont(ofSize: 12, weight: .medium) + attributeString.foregroundColor = UIColor.systemBlue + config.attributedTitle = attributeString + config.titleAlignment = .leading + config.image = UIImage(named: "profile") + config.imagePadding = 8 + config.imagePlacement = .trailing + let realbtn = UIButton(configuration: config) + let profileBtn = UIBarButtonItem(customView:realbtn ) + navigationItem.rightBarButtonItem = profileBtn + } + + @objc func showsearchbar(){ + layoutSearchBar() + } + func layoutSearchBar(){ + let searchbar = UISearchBar() + searchbar.delegate = self + searchbar.placeholder = "검색어를 입력해주세요" + searchbar.searchTextField.backgroundColor = .clear + navigationItem.leftBarButtonItem = .none + navigationItem.rightBarButtonItem = .none + self.navigationItem.titleView = searchbar + let underline3 = UnderlineView() + navigationItem.titleView?.addSubview(underline3) + underline3.snp.makeConstraints{ + $0.bottom.equalToSuperview().offset(-8) + $0.leading.trailing.equalToSuperview().inset(15) + $0.height.equalTo(1.5) + } + } +} + +extension ExploreViewController :UISearchBarDelegate { + func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { + if(searchText.isEmpty){ + ExploreViewController.isSearching = false + } + else{ + ExploreViewController.isSearching = true + resellVC.resellSearchLists = resellVC.resellDataLists.filter{ + $0.name.contains(searchText) + }} + stockView.stockSearchLists = stockView.stockDataLists.filter{ + $0.name.contains(searchText) + } + stockView.StockaTableView.reloadData() + resellVC.resellTableView.reloadData() + + } +} diff --git a/LGHTSG/LGHTSG/Controller/HomeViewController.swift b/LGHTSG/LGHTSG/Controller/HomeViewController.swift new file mode 100644 index 0000000..5ef2492 --- /dev/null +++ b/LGHTSG/LGHTSG/Controller/HomeViewController.swift @@ -0,0 +1,160 @@ +// +// HomeViewController.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/11. +// +import SnapKit +import Foundation +import UIKit +final class HomeViewController : UIViewController{ + private var segmentControl = UnderlineSegmentedControl(items: ["나의 자산", "판매한 자산"]) + var changepercent : String = "-7.2%" + var tableview = UITableView() + var underline1 = UnderlineView() + var underline2 = UnderlineView() + var assetList = [asset]() + var assetmodel = AssetModel() + override func viewDidLoad(){ + super.viewDidLoad() + SetNavigationBar() + setTobTabbar() + segmentControl.addTarget(self, action: #selector(clicksegment), for: .valueChanged) + + setTable() +// assetmodel.delegate = self +// assetmodel.getAsset() + } + // 나의 자산, 판매한 자산 + @objc func clicksegment(_ sender : UISegmentedControl){ + if sender.selectedSegmentIndex == 0{ + underline1.backgroundColor = .white + underline2.backgroundColor = .darkGray + }else{ + underline1.backgroundColor = .darkGray + underline2.backgroundColor = .white + } + } + + +} +private extension HomeViewController{ + + // 네비게이션바 다시 생성 + @objc func shownavigationBar(){ + SetNavigationBar() + } + private func SetNavigationBar(){ + navigationItem.titleView = nil + let searchBtn = UIBarButtonItem(image: UIImage(systemName : "magnifyingglass"), style: .plain, target: self, action: #selector(showsearchbar)) + navigationItem.leftBarButtonItem = searchBtn + var config = UIButton.Configuration.plain() + var attributeString = AttributedString(changepercent) + attributeString.font = .systemFont(ofSize: 12, weight: .medium) + attributeString.foregroundColor = UIColor.systemBlue + config.attributedTitle = attributeString + config.titleAlignment = .leading + config.image = UIImage(named: "profile") + config.imagePadding = 8 + config.imagePlacement = .trailing + let realbtn = UIButton(configuration: config) + let profileBtn = UIBarButtonItem(customView:realbtn ) + navigationItem.rightBarButtonItem = profileBtn + } + + @objc func showsearchbar(){ + layoutSearchBar() + } + func layoutSearchBar(){ + let searchbar = UISearchBar() + searchbar.placeholder = "검색어를 입력해주세요" + searchbar.searchTextField.backgroundColor = .clear + navigationItem.leftBarButtonItem = .none + navigationItem.rightBarButtonItem = .none + self.navigationItem.titleView = searchbar + let underline3 = UnderlineView() + navigationItem.titleView?.addSubview(underline3) + underline3.snp.makeConstraints{ + $0.bottom.equalToSuperview().offset(-8) + $0.leading.trailing.equalToSuperview().inset(15) + $0.height.equalTo(1.5) + } + } + func setTobTabbar(){ + view.addSubview(segmentControl) + view.addSubview(underline1) + view.addSubview(underline2) + underline1.backgroundColor = .white + segmentControl.snp.makeConstraints{ + $0.top.equalTo(view.safeAreaLayoutGuide.snp.top) + $0.leading.trailing.equalToSuperview() + $0.height.equalTo(50) + } + underline1.snp.makeConstraints{ + $0.leading.equalToSuperview().inset(20) + $0.height.equalTo(1.5) + $0.top.equalTo(segmentControl.snp.bottom).offset(-6) + $0.trailing.equalToSuperview().inset(view.frame.width/2 + 5) + } + underline2.snp.makeConstraints{ + $0.leading.equalTo(view.snp.centerX).offset(5) + $0.height.equalTo(1.5) + $0.top.equalTo(segmentControl.snp.bottom).offset(-6) + $0.trailing.equalToSuperview().inset(20) + } + } + private func setTable(){ + view.addSubview(tableview) + tableview.register(HomeTableCell.self, forCellReuseIdentifier: "HomeTableCell") + tableview.delegate = self + tableview.rowHeight = 56 + tableview.dataSource = self + tableview.separatorStyle = .none + tableview.snp.makeConstraints{ + $0.top.equalTo(underline1.snp.bottom).offset(32) + $0.leading.trailing.equalToSuperview().inset(33) + $0.bottom.equalToSuperview().inset(100) + } + } +} +extension HomeViewController : UITableViewDelegate,UITableViewDataSource { + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableview.dequeueReusableCell(withIdentifier: "HomeTableCell", for: indexPath) as? HomeTableCell +// cell?.setup(with: assetList[indexPath.row]) + cell?.setuppp() + cell?.countLabel.text = "\(indexPath.row+1)" + + return cell ?? UITableViewCell() + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { +// let selectedIndex = self.segmentControl.selectedSegmentIndex +// switch selectedIndex{ +// case 0: +// return assetList.count +// case 1: +// return assetList.count +// default: +// return 0 +// } + 20 + } + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + + } + func scrollViewDidScroll(_ scrollView: UIScrollView) { + if self.tableview.contentOffset.y < 0 { + layoutSearchBar() + } + else if tableview.contentOffset.y>100 { + SetNavigationBar() + } + } +} +//extension HomeViewController : AssetModelProtocol{ +// // MARK : assetmodel protocol function +// func assetRetrived(assets : [asset]){ +// self.assetList = assets +// tableview.reloadData() +// } +//} diff --git a/LGHTSG/LGHTSG/Controller/MainTabController.swift b/LGHTSG/LGHTSG/Controller/MainTabController.swift new file mode 100644 index 0000000..aa031eb --- /dev/null +++ b/LGHTSG/LGHTSG/Controller/MainTabController.swift @@ -0,0 +1,98 @@ +// +// MainTabController.swift +// LGHTSG +// +// Created by HA on 2023/01/09. +// + +import UIKit +import Foundation +class MainTabController: UITabBarController { + var changepercent : String = "-7.2%" + override func viewDidLoad() { + view.backgroundColor = .systemBackground + super.viewDidLoad() +// SetNavigationBar() +// swipeGestureNavigationBar() + let systemFontAttributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12.0, weight: .semibold)] + UITabBarItem.appearance().setTitleTextAttributes(systemFontAttributes, for: .normal) + let HomeVC = UINavigationController(rootViewController: HomeViewController()) + HomeVC.tabBarItem.title = "Home" + HomeVC.tabBarItem.image = UIImage(named: "home2") + HomeVC.tabBarItem.selectedImage = UIImage(named: "home") + let ExploreVC = UINavigationController(rootViewController:ExploreViewController()) + ExploreVC.tabBarItem.title = "Explore" + ExploreVC.tabBarItem.image = UIImage(named : "compass") + ExploreVC.tabBarItem.selectedImage = UIImage(named: "compass2") + tabBar.layer.borderColor = UIColor.label.cgColor + tabBar.clipsToBounds = false + viewControllers = [HomeVC,ExploreVC] + + addSeparatorToTabBar() + + + } + private func addSeparatorToTabBar() { + if tabBar.items != nil{ + //Get the height of the tab bar + let height = (tabBar.bounds).height + let itemSize = CGSize( + width: (tabBar.frame.width) / 2, + height: (tabBar.frame.size.height)) + let xPosition = itemSize.width * CGFloat(1) + let separator = UIView(frame: CGRect( + x: xPosition, y: 0, width: 0.7, height: height)) + separator.backgroundColor = UIColor.label + tabBar.insertSubview(separator, at: 0) + let separator2 = UIView(frame: CGRect(x: 0, y: 0, width: tabBar.frame.width, height: 0.7)) + separator2.backgroundColor = UIColor.label + tabBar.insertSubview(separator2, at: 0) + } + } +// private func SetNavigationBar(){ +// navigationItem.titleView = nil +// let searchBtn = UIBarButtonItem(image: UIImage(systemName : "magnifyingglass"), style: .plain, target: self, action: #selector(showsearchbar)) +// navigationItem.leftBarButtonItem = searchBtn +// var config = UIButton.Configuration.plain() +// var attributeString = AttributedString(changepercent) +// attributeString.font = .systemFont(ofSize: 12, weight: .medium) +// attributeString.foregroundColor = UIColor.systemBlue +// config.attributedTitle = attributeString +// config.titleAlignment = .leading +// config.image = UIImage(named: "profile") +// config.imagePadding = 8 +// config.imagePlacement = .trailing +// let realbtn = UIButton(configuration: config) +// let profileBtn = UIBarButtonItem(customView:realbtn ) +// navigationItem.rightBarButtonItem = profileBtn +// } +// func swipeGestureNavigationBar(){ +// let down = UISwipeGestureRecognizer(target: self, action: #selector(showsearchbar)) +// down.direction = .down +// let swipeup = UISwipeGestureRecognizer(target: self, action: #selector(shownavigationBar)) +// swipeup.direction = .up +// self.view.addGestureRecognizer(down) +// self.view.addGestureRecognizer(swipeup) +// } +// @objc func shownavigationBar(){ +// SetNavigationBar() +// } +// @objc func showsearchbar(){ +// layoutSearchBar() +// } +// func layoutSearchBar(){ +// let searchbar = UISearchBar() +// searchbar.placeholder = "검색어를 입력해주세요" +// searchbar.searchTextField.backgroundColor = .clear +// navigationItem.leftBarButtonItem = .none +// navigationItem.rightBarButtonItem = .none +// self.navigationItem.titleView = searchbar +// let underline3 = UnderlineView() +// navigationItem.titleView?.addSubview(underline3) +// underline3.snp.makeConstraints{ +// $0.bottom.equalToSuperview().offset(-8) +// $0.leading.trailing.equalToSuperview().inset(15) +// $0.height.equalTo(1.5) +// } +// } +} diff --git a/LGHTSG/LGHTSG/Controller/StockChartViewController.swift b/LGHTSG/LGHTSG/Controller/StockChartViewController.swift new file mode 100644 index 0000000..3a2c1da --- /dev/null +++ b/LGHTSG/LGHTSG/Controller/StockChartViewController.swift @@ -0,0 +1,454 @@ +// +// StockChartViewController.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/31. +// + +import Foundation +import UIKit +import Charts +import SnapKit +class StockChartViewController : UIViewController { + var stockPriceData = StockPriceModel() + var EstatePriceData = EstatePriceModel() + var nameText : String? + + var idx : Int? + var pricePercentText : String? + var changeDateText : String? + var priceListDatas = [Int]() + var timeListDatas = [String]() + var temppriceListDatas = [Int]() + var temptimeListDatas = [String]() + lazy var lineChartView : LineChartView = { + let chartView = LineChartView() + return chartView + }() + private lazy var nameLabel : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 17, weight: .semibold) + label.text = nameText + return label + }() + private lazy var priceLabel : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 14, weight: .medium) + label.textColor = UIColor.systemGray + + return label + }() + private lazy var pricePercent : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 12, weight: .medium) + label.text = pricePercentText + if (label.text!.prefix(1) == "-"){ + label.textColor = UIColor.blue + }else{ + label.textColor = UIColor.red + } + return label + }() + private lazy var changeDate : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 12, weight : .medium) + label.textColor = UIColor.systemGray + label.text = changeDateText + return label + }() + //MARK: - Label + private lazy var dealLabel: UILabel = { + let label = UILabel() + label.text = "거래 이력" + label.font = UIFont.systemFont(ofSize: 12, weight: .light) + label.textColor = .white + return label + }() + + private lazy var revenueLabel: UILabel = { + let label = UILabel() + label.text = "구매 시점에 비해 얼마 올랐어요" + label.textColor = .white + label.font = UIFont.systemFont(ofSize: 16, weight: .bold) + return label + }() + + + private var lineImage = UnderlineView() + + + //MARK: - SegmentControl + private lazy var segmentCtrl: UISegmentedControl = { + let items = ["1일","월", "1년", "5년"] + let seg = UISegmentedControl(items: items) + seg.addTarget(self, action: #selector(indexChanged(_:)), for: .valueChanged) + seg.layer.cornerRadius = 0.7 + seg.backgroundColor = UIColor(named: "dropdown") + seg.tintColor = .lightGray + seg.setTitleTextAttributes( + [ + NSAttributedString.Key.foregroundColor: UIColor.white, + .font: UIFont.systemFont(ofSize: 14, weight: .semibold) + ], + for: .selected + ) + seg.setTitleTextAttributes( + [ + NSAttributedString.Key.foregroundColor: UIColor.systemGray, + .font: UIFont.systemFont(ofSize: 14, weight: .semibold) + ], + for: .normal + ) + seg.selectedSegmentIndex = 3 + return seg + }() + + //MARK: - Button + private lazy var sellButton: UIButton = { + let btn = UIButton() + btn.setTitle("판매", for: .normal) + btn.setTitleColor(.blue, for: .normal) + btn.backgroundColor = .white + btn.layer.cornerRadius = 5 + btn.layer.borderWidth = 1 + return btn + + }() + + //MARK: - TableView + private lazy var tableView: UITableView = { + let table = UITableView() + table.backgroundColor = .clear + return table + + }() + + //MARK: - LifeCycle + override func viewDidLoad() { + super.viewDidLoad() + + configure() + setLineChartView() + + } + //MARK: - TableViewSetting + func setupTableView(){ + tableView.delegate = self + tableView.dataSource = self + tableView.separatorStyle = .none + tableView.register(EstateDetailCell.self, forCellReuseIdentifier: EstateDetailCell.identifier) + } + @objc func indexChanged(_ sender: UISegmentedControl){ + switch sender.selectedSegmentIndex{ + case 0: + changeDate.text = "일주일 대비" + let daypricedata : [Int] = priceListDatas.suffix(7) + let daytimeListDatas : [String] = timeListDatas.suffix(7) + self.setLineData(lineChartView: self.lineChartView, lineChartDataEntries: self.entryData( yvalues: daypricedata), xAxis: daytimeListDatas, recentPrice : Double(daypricedata.last!)) + temptimeListDatas = daytimeListDatas + temppriceListDatas = daypricedata + pricePercent.text = "\(String(format: "%.2f", Double((temppriceListDatas.last! - temppriceListDatas[0])) / Double(temppriceListDatas[0]) * 100))%" + if(pricePercent.text?.prefix(1) == "-"){ + pricePercent.textColor = UIColor.blue + } + else{ + pricePercent.textColor = UIColor.red + } + tableView.reloadData() + case 1: + changeDate.text = "한달 전 대비" + let monthpricedata : [Int] = priceListDatas.suffix(31) + let monthtimeListDatas : [String] = timeListDatas.suffix(31) + self.setLineData(lineChartView: self.lineChartView, lineChartDataEntries: self.entryData( yvalues: monthpricedata), xAxis: monthtimeListDatas, recentPrice : Double(monthpricedata.last!)) + temppriceListDatas = monthpricedata + temptimeListDatas = monthtimeListDatas + pricePercent.text = "\(String(format: "%.2f", Double((temppriceListDatas.last! - temppriceListDatas[0])) / Double(temppriceListDatas[0]) * 100))%" + if(pricePercent.text?.prefix(1) == "-"){ + pricePercent.textColor = UIColor.blue + } + else{ + pricePercent.textColor = UIColor.red + } + tableView.reloadData() + case 2: + changeDate.text = "1년 전 대비" + temppriceListDatas = [] + temptimeListDatas = [] + guard let recentTimestring = timeListDatas.last else{ return} + // 만약 주식이 상장된지 1년이 안되었다면? 기준을 245개로 잡음 + if(timeListDatas.count < 243){ +// temppriceListDatas = [] +// temptimeListDatas = [] +// for (index, element ) in timeListDatas.enumerated(){ +// if index % 5 == 0 { +// temptimeListDatas.append(element) +// } +// } +// for (index, element ) in priceListDatas.enumerated(){ +// if index % 5 == 0 { +// temppriceListDatas.append(element) +// } +// } + temppriceListDatas = priceListDatas + temptimeListDatas = timeListDatas + pricePercent.text = "\(String(format: "%.2f", Double((temppriceListDatas.last! - temppriceListDatas[0])) / Double(temppriceListDatas[0]) * 100))%" + if(pricePercent.text?.prefix(1) == "-"){ + pricePercent.textColor = UIColor.blue + } + else{ + pricePercent.textColor = UIColor.red + } + self.setLineData(lineChartView: self.lineChartView, lineChartDataEntries: self.entryData( yvalues: priceListDatas), xAxis: timeListDatas, recentPrice : Double(priceListDatas.last!)) + tableView.reloadData() + } + else{ + let recenttimedata = Array(recentTimestring) + let changeyear = Int(String(recenttimedata[3]))! - 1 + let changeyearString = recentTimestring.prefix(3) + "\(changeyear)" + recentTimestring.dropFirst(4) + // 정확히 1년전데이터가 있는경우 ex) 2023-1-31 > 2022-1-31 + if let firstindex = timeListDatas.firstIndex(of: String(changeyearString)) { + let temptimeList = Array(timeListDatas.dropFirst(firstindex)) + for (index, element ) in temptimeList.enumerated(){ + if index % 5 == 0 { + temptimeListDatas.append(element) + } + } + let temppriceList = Array(priceListDatas.dropFirst(firstindex)) + for (index, element ) in temppriceList.enumerated(){ + if index % 5 == 0 { + temppriceListDatas.append(element) + } + } + pricePercent.text = "\(String(format: "%.2f", Double((temppriceListDatas.last! - temppriceListDatas[0])) / Double(temppriceListDatas[0]) * 100))%" + if(pricePercent.text?.prefix(1) == "-"){ + pricePercent.textColor = UIColor.blue + } + else{ + pricePercent.textColor = UIColor.red + } + self.setLineData(lineChartView: self.lineChartView, lineChartDataEntries: self.entryData( yvalues: temppriceListDatas), xAxis: temptimeListDatas, recentPrice : Double(temppriceListDatas.last!)) + tableView.reloadData() + } + // 그런데 1년이상이지만 날짜상 그날이 휴장일일때를 대비해서 그냥 244개만 데이터 뽑기. + else{ + let beforePriceData = priceListDatas.suffix(244) + let beforeTimeData = timeListDatas.suffix(244) + for (index, element ) in beforeTimeData.enumerated(){ + if index % 5 == 0 { + temptimeListDatas.append(element) + } + } + for (index, element ) in beforePriceData.enumerated(){ + if index % 5 == 0 { + temppriceListDatas.append(element) + } + } + if(!temptimeListDatas.contains( recentTimestring)){ + temptimeListDatas.append(recentTimestring) + temppriceListDatas.append(priceListDatas.last!) + } + self.setLineData(lineChartView: self.lineChartView, lineChartDataEntries: self.entryData( yvalues: temppriceListDatas), xAxis: temptimeListDatas, recentPrice : Double(temppriceListDatas.last!)) + pricePercent.text = "\(String(format: "%.2f", Double((temppriceListDatas.last! - temppriceListDatas[0])) / Double(temppriceListDatas[0]) * 100))%" + if(pricePercent.text?.prefix(1) == "-"){ + pricePercent.textColor = UIColor.blue + } + else{ + pricePercent.textColor = UIColor.red + } + tableView.reloadData() + }} + + + case 3: + changeDate.text = "5년전 대비" + temppriceListDatas = [] + temptimeListDatas = [] + for (index, element ) in timeListDatas.enumerated(){ + if index % 5 == 0 { + temptimeListDatas.append(element) + } + } + for (index, element ) in priceListDatas.enumerated(){ + if index % 5 == 0 { + temppriceListDatas.append(element) + } + } + pricePercent.text = "\(String(format: "%.2f", Double((temppriceListDatas.last! - temppriceListDatas[0])) / Double(temppriceListDatas[0]) * 100))%" + if(pricePercent.text?.prefix(1) == "-"){ + pricePercent.textColor = UIColor.blue + } + else{ + pricePercent.textColor = UIColor.red + } + self.setLineData(lineChartView: self.lineChartView, lineChartDataEntries: self.entryData( yvalues: temppriceListDatas), xAxis: temptimeListDatas, recentPrice : Double(temppriceListDatas.last!)) + tableView.reloadData() + default: + break + } + } + } + extension StockChartViewController : UITableViewDelegate, UITableViewDataSource { + //cell 높이조절 + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 30 + } + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return temptimeListDatas.count } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = tableView.dequeueReusableCell(withIdentifier: EstateDetailCell.identifier, for: indexPath) as? EstateDetailCell else { return UITableViewCell() } + + cell.date.text = temptimeListDatas[indexPath.row] + cell.date.textColor = .white + cell.price.text = "\(temppriceListDatas[indexPath.row])원" + cell.price.textColor = .white + cell.buysell.text = "hello" + cell.buysell.textColor = .white + return cell + } + } + extension StockChartViewController { + func setLineData(lineChartView: LineChartView, lineChartDataEntries: [ChartDataEntry], xAxis : [String], recentPrice : Double) { + // Entry들을 이용해 Data Set 만들기(그런데 우리는 각 포인트를 나타내줄 필요가 없어서 지워줌 + let lineChartdataSet = LineChartDataSet(entries: lineChartDataEntries, label: "주가") + lineChartdataSet.drawValuesEnabled = false + lineChartdataSet.drawCirclesEnabled = false + lineChartdataSet.colors = [.blue] + //선택했을때 라인 지워주기 + lineChartdataSet.drawHorizontalHighlightIndicatorEnabled = false + // lineChartdataSet.drawVerticalHighlightIndicatorEnabled = false + lineChartdataSet.highlightColor = .white + + // DataSet을 차트 데이터로 넣기 + let lineChartData = LineChartData(dataSet: lineChartdataSet) + // 데이터 출력 + lineChartView.data = lineChartData + // 선제거 + lineChartView.leftAxis.drawGridLinesEnabled = false + lineChartView.rightAxis.drawGridLinesEnabled = false + lineChartView.leftAxis.enabled = false // 왼쪽 label 값 지워주기 + lineChartView.rightAxis.enabled = false // right + lineChartView.xAxis.enabled = false // 위쪽 label + lineChartView.xAxis.drawGridLinesEnabled = false + lineChartView.xAxis.drawAxisLineEnabled = false + lineChartView.doubleTapToZoomEnabled = false + // 아래 뜨는 어떤항목인지 알려주는 label 제거 + lineChartView.legend.enabled = false + lineChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: xAxis) + + let marker = ChartMarker(pricedate: xAxis, recentprice: recentPrice) + + marker.chartView = lineChartView + marker.chartx = view.frame.width - 10 + lineChartView.marker = marker + lineChartView.drawMarkers = true + // 데이터 소수점 제거 + let formatter = NumberFormatter() + formatter.minimumFractionDigits = 0 + lineChartView.data?.setValueFormatter(DefaultValueFormatter(formatter:formatter)) + } + // entry 만들기 + func entryData(yvalues: [Int]) -> [ChartDataEntry] { + // entry 담을 array + var lineDataEntries: [ChartDataEntry] = [] + // 담기 + for i in 0 ..< yvalues.count { + let lineDataEntry = ChartDataEntry(x: Double(i), y: Double(yvalues[i])) + lineDataEntries.append(lineDataEntry) + } + // 반환 + return lineDataEntries + } + private func setLineChartView() { + stockPriceData.requestStockPrice(stockIdx: self.idx!, onCompleted: { (pricelists, transctiontime) in + DispatchQueue.main.async { + self.view.addSubview(self.lineChartView) + let sortedtimeLists = transctiontime.sorted{$0.compare($1, options: .numeric) == .orderedAscending} + self.priceListDatas = pricelists + self.priceLabel.text = "\(self.priceListDatas.last!)원" + self.timeListDatas = sortedtimeLists + self.setLineData(lineChartView: self.lineChartView, lineChartDataEntries: self.entryData( yvalues: pricelists), xAxis: sortedtimeLists, recentPrice : Double(pricelists.last!)) + self.setupTableView() + } + }) + // EstatePriceData.requestStockPrice(EstateIdx: self.idx!, onCompleted: { (pricelists, transctiontime) in + // DispatchQueue.main.async { + // self.view.addSubview(self.lineChartView) + // self.setLineData(lineChartView: self.lineChartView, lineChartDataEntries: self.entryData( yvalues: pricelists), xAxis: transctiontime, recentPrice : Double(pricelists.last!)) + //// self.lineChartView.snp.makeConstraints{ + //// $0.leading.trailing.equalToSuperview() + //// $0.top.bottom.equalToSuperview().inset(140) + //// } + // } + // }) + } + + } + + + extension StockChartViewController { + //MARK: - Configure + private func configure(){ + lineImage.backgroundColor = .label + [nameLabel, priceLabel, pricePercent,changeDate, sellButton, tableView, lineImage,dealLabel, revenueLabel, segmentCtrl,lineChartView] + .forEach {view.addSubview($0)} + nameLabel.snp.makeConstraints{ + $0.top.equalTo(view.safeAreaLayoutGuide.snp.top ).offset(10) + $0.leading.equalToSuperview().inset(15) + } + priceLabel.snp.makeConstraints{ + $0.top.equalTo(nameLabel.snp.bottom).offset(8) + $0.leading.equalTo(nameLabel.snp.leading) + } + pricePercent.snp.makeConstraints{ + $0.top.equalTo(nameLabel.snp.bottom).offset(9) + $0.leading.equalTo(priceLabel.snp.trailing).offset(8) + } + changeDate.snp.makeConstraints{ + $0.top.equalTo(nameLabel.snp.bottom).offset(10) + $0.leading.equalTo(pricePercent.snp.trailing).offset(8) + } + lineChartView.snp.makeConstraints{ + $0.top.equalTo(priceLabel.snp.bottom).offset(30) + $0.leading.equalToSuperview().inset(15) + $0.trailing.equalToSuperview().inset(15) + $0.bottom.equalTo(view.snp.centerY).offset(20) + } + segmentCtrl.snp.makeConstraints{ + $0.top.equalTo(lineChartView.snp.bottom) + $0.leading.equalToSuperview().inset(15) + $0.trailing.equalToSuperview().inset(15) + } + revenueLabel.snp.makeConstraints{ + $0.leading.equalToSuperview().inset(33) + $0.top.equalTo(segmentCtrl.snp.bottom).offset(24) + } + + dealLabel.snp.makeConstraints{ + $0.top.equalTo(revenueLabel.snp.bottom).offset(24) + $0.leading.equalToSuperview().inset(33) + } + lineImage.snp.makeConstraints{ + + $0.leading.equalToSuperview().inset(33) + $0.trailing.equalToSuperview().inset(33) + $0.height.equalTo(1) + $0.top.equalTo(dealLabel.snp.bottom).offset(4) + } + + tableView.snp.makeConstraints{ + $0.top.equalTo(lineImage.snp.bottom) + $0.bottom.equalTo(sellButton.snp.top).offset(-20) + $0.leading.equalToSuperview().inset(33) + $0.trailing.equalToSuperview().inset(33) + } + + sellButton.snp.makeConstraints{ + $0.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-10) + $0.leading.equalToSuperview().inset(33) + $0.height.equalTo(48) + $0.trailing.equalToSuperview().inset(33) + } + } + } + diff --git a/LGHTSG/LGHTSG/Info.plist b/LGHTSG/LGHTSG/Info.plist new file mode 100644 index 0000000..bc240fd --- /dev/null +++ b/LGHTSG/LGHTSG/Info.plist @@ -0,0 +1,28 @@ + + + + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + + diff --git a/LGHTSG/LGHTSG/LaunchScreen.storyboard b/LGHTSG/LGHTSG/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/LGHTSG/LGHTSG/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LGHTSG/LGHTSG/Model/EstatePriceModel.swift b/LGHTSG/LGHTSG/Model/EstatePriceModel.swift new file mode 100644 index 0000000..a76e4d2 --- /dev/null +++ b/LGHTSG/LGHTSG/Model/EstatePriceModel.swift @@ -0,0 +1,32 @@ +// +// EstatePriceModel.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/22. +// + +import Foundation +import Alamofire +class EstatePriceModel { + var PriceLists : [Int] = [] + var transactionTimeLists : [String] = [] + func requestStockPrice(EstateIdx : Int, onCompleted : @escaping([Int],[String]) -> Void){ + let urlString = "http://api.lghtsg.site:8090/realestates/\(EstateIdx)/prices" + guard let url = URL(string: urlString) else {return print("erorr")} + AF.request(url).responseDecodable(of: realEstates.self) { [weak self]response in + switch response.result { + case let .success(data): + guard let self = self else {return} + data.body.forEach{ + self.PriceLists.append($0.price) + self.transactionTimeLists.append($0.datetime) + } + onCompleted(self.PriceLists , self.transactionTimeLists) + case let .failure(err): + print(err) + } + + } + } + +} diff --git a/LGHTSG/LGHTSG/Model/ResellPrice.swift b/LGHTSG/LGHTSG/Model/ResellPrice.swift new file mode 100644 index 0000000..851f3f4 --- /dev/null +++ b/LGHTSG/LGHTSG/Model/ResellPrice.swift @@ -0,0 +1,19 @@ +// +// ResellPrice.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/24. +// + +import Foundation +class ResellPrice : Decodable { + let body : [body] + struct body : Decodable{ + let name : String + let price : Int + let rateOfChange : Double + let rateCalDateDiff : String + let idx : Int + let imageUrl : String + } +} diff --git a/LGHTSG/LGHTSG/Model/StockPrice.swift b/LGHTSG/LGHTSG/Model/StockPrice.swift new file mode 100644 index 0000000..9521762 --- /dev/null +++ b/LGHTSG/LGHTSG/Model/StockPrice.swift @@ -0,0 +1,19 @@ +// +// StockPrice.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/21. +// + +import Foundation +struct StockPrice : Decodable { + let body : [StockBody] + struct StockBody : Decodable { + let price : Int + let transactionTime : String + } +} +//struct StockHeader : Decodable{ +// let resultMsg : String +// let resultCode : String +//} diff --git a/LGHTSG/LGHTSG/Model/realEstates.swift b/LGHTSG/LGHTSG/Model/realEstates.swift new file mode 100644 index 0000000..6c169c2 --- /dev/null +++ b/LGHTSG/LGHTSG/Model/realEstates.swift @@ -0,0 +1,15 @@ +// +// File.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/22. +// + +import Foundation +struct realEstates :Decodable { + let body : [EstateBody] + struct EstateBody : Decodable { + let datetime : String + let price : Int + } +} diff --git a/LGHTSG/LGHTSG/View/Cell.swift b/LGHTSG/LGHTSG/View/Cell.swift new file mode 100644 index 0000000..1c9617e --- /dev/null +++ b/LGHTSG/LGHTSG/View/Cell.swift @@ -0,0 +1,9 @@ +// +// Cell.swift +// LGHTSG +// +// Created by HA on 2023/01/09. +// + +import UIKit + diff --git a/LGHTSG/LGHTSG/View/Explore/EstateDetailCell.swift b/LGHTSG/LGHTSG/View/Explore/EstateDetailCell.swift new file mode 100644 index 0000000..a33a13c --- /dev/null +++ b/LGHTSG/LGHTSG/View/Explore/EstateDetailCell.swift @@ -0,0 +1,66 @@ +// +// EstateDetailCell.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/27. +// + +import UIKit +class EstateDetailCell: UITableViewCell { + + static let identifier = "EstateDetailCell" + + lazy var date: UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 14, weight: .medium) + return label + }() + + lazy var price: UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 14, weight: .medium) + return label + }() + + lazy var buysell: UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 14, weight: .medium) + return label + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 6, left: 6, bottom: 6, right: 6)) + self.cellSetting() + + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func cellSetting() { + self.backgroundColor = .black + + [date, price, buysell] + .forEach {contentView.addSubview($0)} + + date.snp.makeConstraints { + $0.leading.equalToSuperview().inset(1) + $0.centerY.equalToSuperview() + + + } + price.snp.makeConstraints { + $0.leading.equalTo(date.snp.trailing ).offset(69) + $0.centerY.equalToSuperview() + + } + buysell.snp.makeConstraints { + $0.trailing.equalToSuperview().inset(30) + $0.centerY.equalToSuperview() + + } + + } +} diff --git a/LGHTSG/LGHTSG/View/Explore/StockView.swift b/LGHTSG/LGHTSG/View/Explore/StockView.swift new file mode 100644 index 0000000..5e925e6 --- /dev/null +++ b/LGHTSG/LGHTSG/View/Explore/StockView.swift @@ -0,0 +1,124 @@ +// +// StockView.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/22. +// +import UIKit +import Foundation +import SnapKit +class StockView : UIViewController { + var delegate : showNavigationDelegate? + lazy private var segment : UISegmentedControl = { + let control = UnderlineSegmentedControl(items: ["급상승", "급하락", "거래량", "시가총액"]) + control.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.darkGray, .font : UIFont.systemFont(ofSize: 16, weight: .semibold)], for: .normal) + control.selectedSegmentIndex = 0 + AssetModel.requestTableCellModel(segmentIndex: 0){ + data in + self.stockDataLists = data + self.StockaTableView.reloadData() + } + return control + }() + let AssetModel = TableCellModel() + var stockDataLists = [asset.body]() + var stockSearchLists = [asset.body]() + init(){ + super.init(nibName: nil, bundle: nil) + } + var StockaTableView = UITableView() + override func viewDidLoad() { + setView() + StockaTableView.dataSource = self + StockaTableView.delegate = self + segment.addTarget(self, action: #selector(clickSegment), for: .valueChanged) + } + //segment이벤트 받아서 급상승, 급하락, 거래량, 시가총액을 구분. + @objc func clickSegment(_ sender : UISegmentedControl){ + switch sender.selectedSegmentIndex { + case 0: + AssetModel.requestTableCellModel(segmentIndex: 0){ + data in + self.stockDataLists = data + self.StockaTableView.reloadData() + } + case 1: + AssetModel.requestTableCellModel(segmentIndex: 1){ + data in + self.stockDataLists = data + self.StockaTableView.reloadData()} + case 2: + AssetModel.requestTableCellModel(segmentIndex: 2){ + data in + self.stockDataLists = data + self.StockaTableView.reloadData()} + case 3: + AssetModel.requestTableCellModel(segmentIndex: 3){ + data in + self.stockDataLists = data + self.StockaTableView.reloadData()} + default: break + } + } + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + func setView(){ + StockaTableView.register(HomeTableCell.self, forCellReuseIdentifier: "HomeTabeCell") + StockaTableView.separatorStyle = .none + self.view.addSubview(segment) + segment.snp.makeConstraints{ + $0.leading.top.equalToSuperview() + $0.height.equalTo(18) + } + self.view.addSubview(StockaTableView) + StockaTableView.snp.makeConstraints{ + $0.leading.trailing.equalToSuperview() + $0.top.equalTo(segment.snp.bottom).offset(22) + $0.bottom.equalToSuperview() + } + } +} +extension StockView : UITableViewDataSource, UITableViewDelegate{ + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if(ExploreViewController.isSearching){ + return stockSearchLists.count + }else{ + return stockDataLists.count} + } + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTabeCell", for: indexPath) as? HomeTableCell else {return UITableViewCell()} + if(ExploreViewController.isSearching){ + cell.setup(with: stockSearchLists[indexPath.row]) + } + else{cell.setup(with: stockDataLists[indexPath.row])} + cell.countLabel.text = "\(indexPath.row+1)" + return cell + } + func scrollViewDidScroll(_ scrollView: UIScrollView) { + if StockaTableView.contentOffset.y < 0 { + delegate?.showSearchBar() + } + else if StockaTableView.contentOffset.y>100 { + delegate?.hideSearchBar() + } + } + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let ChartVc = StockChartViewController() + if(ExploreViewController.isSearching){ + ChartVc.nameText = stockSearchLists[indexPath.row].name + ChartVc.changeDateText = ((stockSearchLists[indexPath.row].rateCalDateDiff)) + ChartVc.pricePercentText = "\(stockSearchLists[indexPath.row].rateOfChange)%" + ChartVc.idx = stockSearchLists[indexPath.row].idx + + }else{ + ChartVc.nameText = stockDataLists[indexPath.row].name + ChartVc.changeDateText = (stockDataLists[indexPath.row].rateCalDateDiff) + ChartVc.pricePercentText = "\(stockDataLists[indexPath.row].rateOfChange)%" + ChartVc.idx = stockDataLists[indexPath.row].idx + + } + + self.navigationController?.pushViewController(ChartVc, animated: true) + } +} diff --git a/LGHTSG/LGHTSG/View/Explore/resellView.swift b/LGHTSG/LGHTSG/View/Explore/resellView.swift new file mode 100644 index 0000000..451c347 --- /dev/null +++ b/LGHTSG/LGHTSG/View/Explore/resellView.swift @@ -0,0 +1,140 @@ +// +// ResellView.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/23. +// + +import UIKit +import Foundation +import SnapKit +protocol showNavigationDelegate{ + func hideSearchBar() + func showSearchBar() +} + +class resellView : UIViewController{ + var delegate : showNavigationDelegate? + let AssetModel = TableCellModel() + var resellDataLists = [ResellPrice.body]() + var resellSearchLists = [ResellPrice.body]() + lazy private var segment : UISegmentedControl = { + let control = UnderlineSegmentedControl(items: ["급상승", "급하락", "거래량"]) + control.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.darkGray, .font : UIFont.systemFont(ofSize: 16, weight: .semibold)], for: .normal) + control.selectedSegmentIndex = 0 + AssetModel.requestResellModel(segmentIndex: 0){ + data in + self.resellDataLists = data + self.resellTableView.reloadData() + } + return control + }() + var resellTableView = UITableView() +// override init(frame: CGRect) { +// super.init(frame: frame) +// setView() +// resellTableView.dataSource = self +// resellTableView.delegate = self +// segment.addTarget(self, action: #selector(clickSegment), for: .valueChanged) +//// let superview = ExploreViewController() +//// superview.delegate1 = self +// } + + init(){ + super.init(nibName: nil, bundle: nil) + } + override func viewDidLoad() { + super.viewDidLoad() + setView() + resellTableView.dataSource = self + resellTableView.delegate = self + segment.addTarget(self, action: #selector(clickSegment), for: .valueChanged) + } + //segment이벤트 받아서 급상승, 급하락, 거래량 + @objc func clickSegment(_ sender : UISegmentedControl){ + switch sender.selectedSegmentIndex { + case 0: + AssetModel.requestResellModel(segmentIndex: 0){ + data in + self.resellDataLists = data + self.resellTableView.reloadData() + } + case 1: + AssetModel.requestResellModel(segmentIndex: 1){ + data in + self.resellDataLists = data + self.resellTableView.reloadData()} + case 2: + AssetModel.requestResellModel(segmentIndex: 2){ + data in + self.resellDataLists = data + self.resellTableView.reloadData()} + default: break + } + } + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + func setView() { + resellTableView.register(HomeTableCell.self, forCellReuseIdentifier: "HomeTabeCell") + resellTableView.separatorStyle = .none + self.view.addSubview(segment) + segment.snp.makeConstraints{ + $0.leading.top.equalToSuperview() + $0.height.equalTo(18) + } + self.view.addSubview(resellTableView) + resellTableView.snp.makeConstraints{ + $0.leading.trailing.equalToSuperview() + $0.top.equalTo(segment.snp.bottom).offset(22) + $0.bottom.equalToSuperview() + } + } +} +extension resellView : UITableViewDataSource , UITableViewDelegate, UIScrollViewDelegate { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if(ExploreViewController.isSearching){ + return resellSearchLists.count + }else{ + return resellDataLists.count }} + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTabeCell", for: indexPath) as? HomeTableCell else {return UITableViewCell()} + if(ExploreViewController.isSearching){ + cell.setup(with: resellSearchLists[indexPath.row]) + }else{ + cell.setup(with: resellDataLists[indexPath.row])} + cell.countLabel.text = "\(indexPath.row+1)" + return cell + + } + func scrollViewDidScroll(_ scrollView: UIScrollView) { + if resellTableView.contentOffset.y < 0 { + delegate?.showSearchBar() + } + else if resellTableView.contentOffset.y>100 { + delegate?.hideSearchBar() + } + } + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let ChartVc = ChartViewController() + + + if(ExploreViewController.isSearching){ + ChartVc.nameText = resellSearchLists[indexPath.row].name + ChartVc.changeDateText = String(resellSearchLists[indexPath.row].rateOfChange) + ChartVc.pricePercentText = resellSearchLists[indexPath.row].rateCalDateDiff + ChartVc.PriceText = "\(String(resellSearchLists[indexPath.row].price))원" + ChartVc.idx = resellSearchLists[indexPath.row].idx + ChartVc.imageURL = resellSearchLists[indexPath.row].imageUrl + }else{ + ChartVc.nameText = resellDataLists[indexPath.row].name + ChartVc.changeDateText = String(resellDataLists[indexPath.row].rateOfChange) + ChartVc.pricePercentText = resellDataLists[indexPath.row].rateCalDateDiff + ChartVc.PriceText = "\(String(resellDataLists[indexPath.row].price))원" + ChartVc.idx = resellDataLists[indexPath.row].idx + ChartVc.imageURL = resellDataLists[indexPath.row].imageUrl + } + + self.navigationController?.pushViewController(ChartVc, animated: true) + } +} diff --git a/LGHTSG/LGHTSG/View/Home/AssetModel.swift b/LGHTSG/LGHTSG/View/Home/AssetModel.swift new file mode 100644 index 0000000..cebcbd6 --- /dev/null +++ b/LGHTSG/LGHTSG/View/Home/AssetModel.swift @@ -0,0 +1,32 @@ +// +// AssetModel.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/14. +// +// 일단 assetmodel이라고 임의의 url넣어놨는데 나의자산, 판매한자산의 model을 따로 만들생각. +import Foundation +protocol AssetModelProtocol { + func assetRetrived(assets : [asset]) +} +class AssetModel { + var delegate : AssetModelProtocol? + func getAsset(){ + let urlString = "요청할 url" + let url = URL(string: urlString) + guard let url = url else{return} //url 없으면 멈추도록 + let dataTask = URLSession.shared.dataTask(with: url){ + (data, res, err) in + if err == nil && data != nil { + let decoder = JSONDecoder() + do { + let asset = try decoder.decode(asset.self, from: data!) //asset decodable 형식의 swift인스턴스로 파싱 + DispatchQueue.main.async { + self.delegate?.assetRetrived(assets: [asset]) + } + }catch{print("erorr json")} + } + } + dataTask.resume() + } +} diff --git a/LGHTSG/LGHTSG/View/Home/ChartMarker.swift b/LGHTSG/LGHTSG/View/Home/ChartMarker.swift new file mode 100644 index 0000000..475efb9 --- /dev/null +++ b/LGHTSG/LGHTSG/View/Home/ChartMarker.swift @@ -0,0 +1,78 @@ +// +// BalloonMarker.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/18. +// + + + +import Charts +import UIKit + + +class ChartMarker: MarkerView { + var text = "" + var pricedatelists = [String]() + var priceDate = "" + var pricetext = "" + var pricepercent : String = "" + var recentprice : Double = 0.0 + + var chartx: Double = 0.0 + init(pricedate: [String], recentprice : Double) { + super.init(frame: .zero) + self.pricedatelists = pricedate + self.recentprice = recentprice + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + // highlight 클릭되면 제일먼저 값을 entry로 부터 가져오는데 entry에는 double밖에 넣지 못해 임의로 pricedatelist생성후 대입 + override func refreshContent(entry: ChartDataEntry, highlight: Highlight) { + super.refreshContent(entry: entry, highlight: highlight) + self.pricepercent = "\(String(format: "%.2f",(recentprice - entry.y) / recentprice * 100))%" +// if (self.pricepercent[self.pricepercent.startIndex] == "-") { +// let attributeStr = NSMutableAttributedString(string: text) +// } + text = "이때 샀다면 지금\(self.pricepercent)" + priceDate = pricedatelists[Int(entry.x)] + pricetext = "\(Int(entry.y))원" + } + + override func draw(context: CGContext, point: CGPoint) { + super.draw(context: context, point: point) + var drawAttributes = [NSAttributedString.Key : Any]() + drawAttributes[.font] = UIFont.systemFont(ofSize: 12) + drawAttributes[.foregroundColor] = UIColor.white + drawAttributes[.backgroundColor] = UIColor.clear + self.bounds.size = ("\(text)" as NSString).size(withAttributes: drawAttributes) + self.offset = CGPoint(x: -self.bounds.size.width / 2, y: self.bounds.size.height * 2) + if point.x + offset.x < 0.0 + { + offset.x = -point.x + } + else if point.x + self.bounds.size.width + offset.x > chartx + { + offset.x = chartx - point.x - self.bounds.size.width + } + drawText(text: " \(text) " as NSString, rect: CGRect(origin: CGPoint(x: point.x + offset.x, y: 0), size: self.bounds.size), withAttributes: drawAttributes) + self.bounds.size = ("\(pricetext)" as NSString).size(withAttributes: drawAttributes) + drawAttributes[.font] = UIFont.systemFont(ofSize: 10) + drawAttributes[.foregroundColor] = UIColor.lightGray + drawText(text: "\(priceDate)" as NSString, rect: CGRect(origin: CGPoint(x: point.x + offset.x / 2, y: offset.y), size: self.bounds.size ), withAttributes: drawAttributes) + drawAttributes[.font] = UIFont.systemFont(ofSize: 12) + drawAttributes[.foregroundColor] = UIColor.white + drawText(text: "\(pricetext)" as NSString, rect: CGRect(origin: CGPoint(x: point.x + offset.x / 2, y: offset.y / 2 ), size: self.bounds.size ), withAttributes: drawAttributes) + + } + override func draw(_ rect: CGRect) { + super.draw(rect) + } + func drawText(text: NSString, rect: CGRect, withAttributes attributes: [NSAttributedString.Key : Any]? = nil) { + let size = text.size(withAttributes: attributes) + let centeredRect = CGRect(x: rect.origin.x + (rect.size.width - size.width) / 2, y: rect.origin.y + (rect.size.height - size.height) / 2 , width: size.width, height: size.height) + text.draw(in: centeredRect, withAttributes: attributes) + } +} diff --git a/LGHTSG/LGHTSG/View/Home/HomeTableCell.swift b/LGHTSG/LGHTSG/View/Home/HomeTableCell.swift new file mode 100644 index 0000000..cc1f4de --- /dev/null +++ b/LGHTSG/LGHTSG/View/Home/HomeTableCell.swift @@ -0,0 +1,185 @@ +// +// HomeTableCell.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/14. +// + +import Foundation +import UIKit +import SnapKit +import Kingfisher +class HomeTableCell : UITableViewCell { + var countLabel : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 16, weight: .bold) + return label + }() + private lazy var nameLabel : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 14, weight: .semibold) + return label + }() + private lazy var priceLabel : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 14, weight: .medium) + label.textColor = UIColor.systemGray + return label + }() + private lazy var pricePercent : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 12, weight: .medium) + label.textColor = UIColor.red + return label + }() + private lazy var changeDate : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 12, weight : .medium) + label.textColor = UIColor.systemGray + return label + }() + var iconimage = UIImageView() +// override func layoutSubviews() { +// super.layoutSubviews() +// contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 12, left: 0, bottom: 12, right: 0)) +// } +} +extension HomeTableCell { + func setup(with assetinfo : asset.body){ + [countLabel, nameLabel, priceLabel, pricePercent, changeDate, iconimage].forEach{ + addSubview($0) + } + nameLabel.text = assetinfo.name + priceLabel.text = String(assetinfo.price)+"원" + changeDate.text = assetinfo.rateCalDateDiff + let stringofratechange = String(assetinfo.rateOfChange) + if(stringofratechange[stringofratechange.startIndex] == "-"){ + pricePercent.text = "\(stringofratechange)%" + pricePercent.textColor = .blue + }else { + pricePercent.text = "+\(stringofratechange)%" + pricePercent.textColor = .red + } + let url = URL(string: assetinfo.iconImage) + iconimage.clipsToBounds = true + iconimage.kf.setImage(with: url) + countLabel.snp.makeConstraints{ + $0.leading.equalToSuperview() + $0.top.equalToSuperview() + $0.bottom.equalToSuperview().offset(-12) + } + iconimage.snp.makeConstraints{ + $0.leading.equalToSuperview().offset(23.66) + $0.top.equalToSuperview() + $0.height.width.equalTo(44) + $0.bottom.equalToSuperview().offset(-12) + } + nameLabel.snp.makeConstraints{ + $0.leading.equalTo(iconimage.snp.trailing).offset(16.34) + $0.top.equalToSuperview() + + } + priceLabel.snp.makeConstraints{ + $0.leading.equalTo(nameLabel.snp.leading) + $0.top.equalTo(nameLabel.snp.bottom).offset(5) + } + pricePercent.snp.makeConstraints{ + $0.leading.equalTo(priceLabel.snp.trailing).offset(8) + $0.top.equalTo(priceLabel.snp.top) + } + changeDate.snp.makeConstraints{ + $0.leading.equalTo(pricePercent.snp.trailing).offset(9) + $0.top.equalTo(pricePercent.snp.top) + } + } + func setup(with resellinfo : ResellPrice.body){ + [countLabel, nameLabel, priceLabel, pricePercent, changeDate, iconimage].forEach{ + addSubview($0) + } + nameLabel.text = resellinfo.name + priceLabel.text = String(resellinfo.price)+"원" + changeDate.text = resellinfo.rateCalDateDiff + let stringofratechange = String( resellinfo.rateOfChange) + if(stringofratechange[stringofratechange.startIndex] == "-"){ + pricePercent.text = "\(stringofratechange)%" + pricePercent.textColor = .blue + }else { + pricePercent.text = "+\(stringofratechange)%" + pricePercent.textColor = .red + } + + let url = URL(string: resellinfo.imageUrl) + // kf 이미지 둥그렇게 + + iconimage.clipsToBounds = true + iconimage.layer.cornerRadius = 20 + iconimage.backgroundColor = .white + iconimage.kf.setImage(with: url ) + + countLabel.snp.makeConstraints{ + $0.leading.equalToSuperview() + $0.top.equalToSuperview() + $0.bottom.equalToSuperview().offset(-12) + } + iconimage.snp.makeConstraints{ + $0.leading.equalToSuperview().offset(23.66) + $0.top.equalToSuperview() + $0.height.width.equalTo(44) + $0.bottom.equalToSuperview().offset(-12) + } + nameLabel.snp.makeConstraints{ + $0.leading.equalTo(iconimage.snp.trailing).offset(16.34) + $0.top.equalToSuperview() + + } + priceLabel.snp.makeConstraints{ + $0.leading.equalTo(nameLabel.snp.leading) + $0.top.equalTo(nameLabel.snp.bottom).offset(5) + } + pricePercent.snp.makeConstraints{ + $0.leading.equalTo(priceLabel.snp.trailing).offset(8) + $0.top.equalTo(priceLabel.snp.top) + } + changeDate.snp.makeConstraints{ + $0.leading.equalTo(pricePercent.snp.trailing).offset(9) + $0.top.equalTo(pricePercent.snp.top) + } + } + func setuppp(){ + [countLabel, nameLabel, priceLabel, pricePercent, changeDate, iconimage].forEach{ + addSubview($0) + } + nameLabel.text = "서울특별시 강남구 논현동 동현아파트" + priceLabel.text = "22,303,921원/m2" + changeDate.text = "3달전 대비" + pricePercent.text = "+3.0%" + iconimage.image = UIImage(systemName: "star") + countLabel.snp.makeConstraints{ + $0.leading.equalToSuperview() + $0.top.equalToSuperview() + $0.bottom.equalToSuperview().offset(-12) + } + iconimage.snp.makeConstraints{ + $0.leading.equalToSuperview().offset(23.66) + $0.top.equalToSuperview() + $0.bottom.equalToSuperview().offset(-12) + } + nameLabel.snp.makeConstraints{ + $0.leading.equalTo(iconimage.snp.trailing).offset(16.34) + $0.top.equalToSuperview() + + } + priceLabel.snp.makeConstraints{ + $0.leading.equalTo(nameLabel.snp.leading) + $0.top.equalTo(nameLabel.snp.bottom).offset(5) + } + pricePercent.snp.makeConstraints{ + $0.leading.equalTo(priceLabel.snp.trailing).offset(8) + $0.top.equalTo(priceLabel.snp.top) + } + changeDate.snp.makeConstraints{ + $0.leading.equalTo(pricePercent.snp.trailing).offset(9) + $0.top.equalTo(pricePercent.snp.top) + } + } +} diff --git a/LGHTSG/LGHTSG/View/Home/MyAssetTableView.swift b/LGHTSG/LGHTSG/View/Home/MyAssetTableView.swift new file mode 100644 index 0000000..080b348 --- /dev/null +++ b/LGHTSG/LGHTSG/View/Home/MyAssetTableView.swift @@ -0,0 +1,24 @@ +// +// MyAssetView.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/12. +// + +import Foundation +import UIKit +class MyAssetTableView : UITableView{ + + self.delegate = self + self.datasource = self} +extension MyAssetTableView : UITableViewDelegate, UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + <#code#> + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + <#code#> + } + + +} diff --git a/LGHTSG/LGHTSG/View/Home/NavigationBar.swift b/LGHTSG/LGHTSG/View/Home/NavigationBar.swift new file mode 100644 index 0000000..90cdd91 --- /dev/null +++ b/LGHTSG/LGHTSG/View/Home/NavigationBar.swift @@ -0,0 +1,8 @@ +// +// NavigationBar.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/13. +// + +import Foundation diff --git a/LGHTSG/LGHTSG/View/Home/StockDateSegmentControl.swift b/LGHTSG/LGHTSG/View/Home/StockDateSegmentControl.swift new file mode 100644 index 0000000..2b6316c --- /dev/null +++ b/LGHTSG/LGHTSG/View/Home/StockDateSegmentControl.swift @@ -0,0 +1,31 @@ +// +// StockDateSegmentControl.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/19. +// + +import Foundation +import UIKit +final class StockDateSegmentControl : UnderlineSegmentedControl{ + + override func removeBackgroundAndDivider() { + super.removeBackgroundAndDivider() + self.backgroundColor = .darkGray + self.setTitleTextAttributes( + [ + NSAttributedString.Key.foregroundColor: UIColor.lightGray, + .font: UIFont.systemFont(ofSize: 16, weight: .semibold) + ], + for: .normal + + ) + self.setTitleTextAttributes( + [ + NSAttributedString.Key.foregroundColor: UIColor.tintColor, + .font: UIFont.systemFont(ofSize: 16, weight: .semibold) + ], + for: .selected + ) + } +} diff --git a/LGHTSG/LGHTSG/View/Home/TopTabBarView.swift b/LGHTSG/LGHTSG/View/Home/TopTabBarView.swift new file mode 100644 index 0000000..b6d0bc8 --- /dev/null +++ b/LGHTSG/LGHTSG/View/Home/TopTabBarView.swift @@ -0,0 +1,65 @@ +// +// .swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/13. +// +// +//import Foundation +//import UIKit +//final class TopTabBarView : UIView { +// var tabbaritemsList : [String] +// private lazy var segmentControl : UISegmentedControl = { +// let segment = UISegmentedControl() +// segment.selectedSegmentTintColor = .clear +// //배경색 제거 , 구분 라인 제거 +// segment.setBackgroundImage(UIImage(), for: .normal, barMetrics: .default) +// segment.setDividerImage(UIImage(), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default) +// segment.setTitleTextAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 15, weight: .bold)], for: .normal) +// for i in 0.. UIView{ +// let view = UIView() +// view.backgroundColor = .secondaryLabel +// return view +// } +//} +//extension TopTabBarView { +// func layout(){ +// addSubview(segmentControl) +// segmentControl.addSubview(underLineView) +// +// segmentControl.snp.makeConstraints{ +// $0.edges.equalToSuperview() +// } +// underLineView.snp.makeConstraints{ +// $0.leading.trailing.equalTo(segmentControl).inset(20) +// $0.height.equalTo(10) +// $0.bottom.equalToSuperview() +// } +// } +//} diff --git a/LGHTSG/LGHTSG/View/Home/UnderlineSegmentedControl.swift b/LGHTSG/LGHTSG/View/Home/UnderlineSegmentedControl.swift new file mode 100644 index 0000000..606e46b --- /dev/null +++ b/LGHTSG/LGHTSG/View/Home/UnderlineSegmentedControl.swift @@ -0,0 +1,38 @@ +// +// LGHTSG +// +// Created by SunHo Lee on 2023/01/13. +// +// +import UIKit +class UnderlineSegmentedControl: UISegmentedControl { + + override init(frame: CGRect) { + super.init(frame: frame) + self.removeBackgroundAndDivider() + } + override init(items: [Any]?) { + super.init(items: items) + self.removeBackgroundAndDivider() + self.selectedSegmentIndex = 0 + self.setTitleTextAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16, weight: .semibold)], for: .normal) + self.setTitleTextAttributes( + [ + NSAttributedString.Key.foregroundColor: UIColor.tintColor, + .font: UIFont.systemFont(ofSize: 16, weight: .bold) + ], + for: .selected + ) + } + required init?(coder: NSCoder) { + fatalError() + } + + func removeBackgroundAndDivider() { + let image = UIImage() + self.setBackgroundImage(image, for: .normal, barMetrics: .default) + self.setBackgroundImage(image, for: .selected, barMetrics: .default) + self.setBackgroundImage(image, for: .highlighted, barMetrics: .default) + self.setDividerImage(image, forLeftSegmentState: .selected, rightSegmentState: .normal, barMetrics: .default) + } +} diff --git a/LGHTSG/LGHTSG/View/Home/UnderlineView.swift b/LGHTSG/LGHTSG/View/Home/UnderlineView.swift new file mode 100644 index 0000000..2256833 --- /dev/null +++ b/LGHTSG/LGHTSG/View/Home/UnderlineView.swift @@ -0,0 +1,19 @@ +// +// SearchBar.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/13. +// + +import Foundation +import UIKit +class UnderlineView : UIView { + override init(frame: CGRect) { + super.init(frame: frame) + self.backgroundColor = .darkGray + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/LGHTSG/LGHTSG/View/Home/asset.swift b/LGHTSG/LGHTSG/View/Home/asset.swift new file mode 100644 index 0000000..19b9cd7 --- /dev/null +++ b/LGHTSG/LGHTSG/View/Home/asset.swift @@ -0,0 +1,20 @@ +// +// asset.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/13. +// + +import Foundation +struct asset : Decodable { + let body : [body] + struct body : Decodable{ + let name : String + let price : Int + let idx : Int + let rateOfChange : Double + let rateCalDateDiff : String + let iconImage : String + } + +} diff --git a/LGHTSG/LGHTSG/View/SellAssetView.swift b/LGHTSG/LGHTSG/View/SellAssetView.swift new file mode 100644 index 0000000..ca43538 --- /dev/null +++ b/LGHTSG/LGHTSG/View/SellAssetView.swift @@ -0,0 +1,12 @@ +// +// SellAssetView.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/12. +// + +import Foundation +import UIKit +class SellAssetView : UIView { + +} diff --git a/LGHTSG/LGHTSG/ViewController.swift b/LGHTSG/LGHTSG/ViewController.swift new file mode 100644 index 0000000..87d3381 --- /dev/null +++ b/LGHTSG/LGHTSG/ViewController.swift @@ -0,0 +1,20 @@ +// +// ViewController.swift +// LGHTSG +// +// Created by HA on 2023/01/09. +// + +import UIKit + +class ViewController: UIViewController { + + + override func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = .darkGray + } + + +} + diff --git a/LGHTSG/StockPriceModel.swift b/LGHTSG/StockPriceModel.swift new file mode 100644 index 0000000..ca4773b --- /dev/null +++ b/LGHTSG/StockPriceModel.swift @@ -0,0 +1,50 @@ +// +// File.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/21. +// + +import Foundation +import Alamofire +class StockPriceModel { + var PriceLists : [Int] = [] + var transactionTimeLists : [String] = [] + func requestStockPrice(stockIdx : Int, onCompleted : @escaping([Int],[String]) -> Void){ + let urlString = "http://api.lghtsg.site:8090/stocks/\(stockIdx)/prices" + guard let url = URL(string: urlString) else {return print("erorr")} + AF.request(url).responseDecodable(of: StockPrice.self) { [weak self]response in + switch response.result { + case let .success(data): + guard let self = self else {return} + data.body.forEach{ + self.PriceLists.append($0.price) + self.transactionTimeLists.append(String($0.transactionTime.prefix(10))) + } + onCompleted(self.PriceLists , self.transactionTimeLists) + + case let .failure(err): + print(err) + } + + } + } + func requestResellPrice(resellIdx : Int, onCompleted : @escaping([Int],[String]) -> Void){ + let urlString = "http://api.lghtsg.site:8090/resells/\(resellIdx)/prices" + guard let url = URL(string: urlString) else {return print("erorr")} + AF.request(url).responseDecodable(of: StockPrice.self) { [weak self]response in + switch response.result { + case let .success(data): + guard let self = self else {return} + data.body.forEach{ + self.PriceLists.append($0.price) + self.transactionTimeLists.append($0.transactionTime) + } + onCompleted(self.PriceLists , self.transactionTimeLists) + case let .failure(err): + print(err) + } + + } + } +} diff --git a/LGHTSG/TableCellModel.swift b/LGHTSG/TableCellModel.swift new file mode 100644 index 0000000..3627836 --- /dev/null +++ b/LGHTSG/TableCellModel.swift @@ -0,0 +1,60 @@ +// +// TableCellModel.swift +// LGHTSG +// +// Created by SunHo Lee on 2023/01/23. +// + +import Foundation +import Alamofire + +class TableCellModel { + var urlString : String? + func requestTableCellModel(segmentIndex: Int , onCompleted : @escaping([asset.body]) -> Void){ + switch segmentIndex{ + case 0: + urlString = "http://api.lghtsg.site:8090/stocks?sort=fluctuation&order=descending" + case 1: + urlString = "http://api.lghtsg.site:8090/stocks?sort=fluctuation&order=ascending" + case 2: + urlString = "http://api.lghtsg.site:8090/stocks?sort=trading-volume" + case 3: + urlString = "http://api.lghtsg.site:8090/stocks?sort=market-cap" + default: + break + } + guard let urlString = urlString else{ return} + guard let url = URL(string: urlString) else {return print("erorr")} + AF.request(url).responseDecodable(of: asset.self) {response in + switch response.result { + case let .success(data): + onCompleted(data.body) + case let .failure(err): + print(err) + } + } + } + func requestResellModel(segmentIndex: Int , onCompleted : @escaping([ResellPrice.body]) -> Void){ + switch segmentIndex{ + case 0: + urlString = "http://api.lghtsg.site:8090/resells?sort=fluctuation&order=descending" + case 1: + urlString = "http://api.lghtsg.site:8090/resells?sort=fluctuation&order=ascending" + case 2: + urlString = "http://api.lghtsg.site:8090/resells " + default: + break + } + guard let urlString = urlString else{ return} + guard let url = URL(string: urlString) else {return print("erorr")} + AF.request(url).responseDecodable(of: ResellPrice.self) {response in + switch response.result { + case let .success(data): + onCompleted(data.body) + case let .failure(err): + print(err) + } + + } + } +}