diff --git a/PolyHack/PolyHack.xcodeproj/project.pbxproj b/PolyHack/PolyHack.xcodeproj/project.pbxproj index 392bf99..10b12f2 100644 --- a/PolyHack/PolyHack.xcodeproj/project.pbxproj +++ b/PolyHack/PolyHack.xcodeproj/project.pbxproj @@ -11,9 +11,20 @@ 5141B6302A3B41CA00105625 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5141B62F2A3B41CA00105625 /* Color.swift */; }; 5141B6322A3B7D7300105625 /* SplashVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5141B6312A3B7D7300105625 /* SplashVC.swift */; }; 5141B6342A3B83C900105625 /* Home.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5141B6332A3B83C900105625 /* Home.storyboard */; }; - 5141B6382A3B8DF900105625 /* HomeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5141B6372A3B8DF900105625 /* HomeVC.swift */; }; 5141B63B2A3B956B00105625 /* MyPage.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5141B63A2A3B956B00105625 /* MyPage.storyboard */; }; 5141B63D2A3B957D00105625 /* MyPageVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5141B63C2A3B957D00105625 /* MyPageVC.swift */; }; + 518CD57D2A3D9FE300C86A4D /* HomeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518CD57C2A3D9FE300C86A4D /* HomeVC.swift */; }; + 518CD5842A3DA8A300C86A4D /* TabBar.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 518CD5832A3DA8A300C86A4D /* TabBar.storyboard */; }; + 518CD5862A3DA8BD00C86A4D /* TabBarVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518CD5852A3DA8BD00C86A4D /* TabBarVC.swift */; }; + 518CD5AA2A3DB17A00C86A4D /* StaticVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518CD5A92A3DB17A00C86A4D /* StaticVC.swift */; }; + 518CD5AC2A3DB18E00C86A4D /* Static.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 518CD5AB2A3DB18E00C86A4D /* Static.storyboard */; }; + 518CD5B12A3DCF2000C86A4D /* HomeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518CD5B02A3DCF2000C86A4D /* HomeTableViewCell.swift */; }; + 518CD5B32A3DD04F00C86A4D /* EntireNewsAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518CD5B22A3DD04F00C86A4D /* EntireNewsAPI.swift */; }; + 518CD5B52A3DD1F100C86A4D /* HomeAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518CD5B42A3DD1F100C86A4D /* HomeAPI.swift */; }; + 518CD5B72A3DD20600C86A4D /* API.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518CD5B62A3DD20600C86A4D /* API.swift */; }; + 518CD5B92A3DD77C00C86A4D /* TopNewsAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 518CD5B82A3DD77C00C86A4D /* TopNewsAPI.swift */; }; + 51A794F02A3E07C30029B39D /* NewsDetailVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A794EF2A3E07C30029B39D /* NewsDetailVC.swift */; }; + 51A794F22A3E0B390029B39D /* NewsDetailAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51A794F12A3E0B390029B39D /* NewsDetailAPI.swift */; }; 51E674C92A358DB600D30EE1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E674C82A358DB600D30EE1 /* AppDelegate.swift */; }; 51E674CB2A358DB600D30EE1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E674CA2A358DB600D30EE1 /* SceneDelegate.swift */; }; 51E674CD2A358DB600D30EE1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E674CC2A358DB600D30EE1 /* ViewController.swift */; }; @@ -27,9 +38,20 @@ 5141B62F2A3B41CA00105625 /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = ""; }; 5141B6312A3B7D7300105625 /* SplashVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashVC.swift; sourceTree = ""; }; 5141B6332A3B83C900105625 /* Home.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Home.storyboard; sourceTree = ""; }; - 5141B6372A3B8DF900105625 /* HomeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeVC.swift; sourceTree = ""; }; 5141B63A2A3B956B00105625 /* MyPage.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = MyPage.storyboard; sourceTree = ""; }; 5141B63C2A3B957D00105625 /* MyPageVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyPageVC.swift; sourceTree = ""; }; + 518CD57C2A3D9FE300C86A4D /* HomeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeVC.swift; sourceTree = ""; }; + 518CD5832A3DA8A300C86A4D /* TabBar.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = TabBar.storyboard; sourceTree = ""; }; + 518CD5852A3DA8BD00C86A4D /* TabBarVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarVC.swift; sourceTree = ""; }; + 518CD5A92A3DB17A00C86A4D /* StaticVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticVC.swift; sourceTree = ""; }; + 518CD5AB2A3DB18E00C86A4D /* Static.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Static.storyboard; sourceTree = ""; }; + 518CD5B02A3DCF2000C86A4D /* HomeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTableViewCell.swift; sourceTree = ""; }; + 518CD5B22A3DD04F00C86A4D /* EntireNewsAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntireNewsAPI.swift; sourceTree = ""; }; + 518CD5B42A3DD1F100C86A4D /* HomeAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeAPI.swift; sourceTree = ""; }; + 518CD5B62A3DD20600C86A4D /* API.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = API.swift; sourceTree = ""; }; + 518CD5B82A3DD77C00C86A4D /* TopNewsAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopNewsAPI.swift; sourceTree = ""; }; + 51A794EF2A3E07C30029B39D /* NewsDetailVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsDetailVC.swift; sourceTree = ""; }; + 51A794F12A3E0B390029B39D /* NewsDetailAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsDetailAPI.swift; sourceTree = ""; }; 51E674C52A358DB600D30EE1 /* PolyHack.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PolyHack.app; sourceTree = BUILT_PRODUCTS_DIR; }; 51E674C82A358DB600D30EE1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 51E674CA2A358DB600D30EE1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -55,6 +77,7 @@ isa = PBXGroup; children = ( 5141B62F2A3B41CA00105625 /* Color.swift */, + 518CD5B62A3DD20600C86A4D /* API.swift */, ); path = Const; sourceTree = ""; @@ -62,7 +85,9 @@ 5141B6352A3B8DD900105625 /* Home */ = { isa = PBXGroup; children = ( - 5141B6372A3B8DF900105625 /* HomeVC.swift */, + 518CD57C2A3D9FE300C86A4D /* HomeVC.swift */, + 518CD5B42A3DD1F100C86A4D /* HomeAPI.swift */, + 51A794EF2A3E07C30029B39D /* NewsDetailVC.swift */, ); path = Home; sourceTree = ""; @@ -87,6 +112,9 @@ 5156508A2A39E8CF00840026 /* API */ = { isa = PBXGroup; children = ( + 518CD5B22A3DD04F00C86A4D /* EntireNewsAPI.swift */, + 518CD5B82A3DD77C00C86A4D /* TopNewsAPI.swift */, + 51A794F12A3E0B390029B39D /* NewsDetailAPI.swift */, ); path = API; sourceTree = ""; @@ -94,6 +122,8 @@ 5156508B2A39E8DD00840026 /* Controller */ = { isa = PBXGroup; children = ( + 518CD5A72A3DB14F00C86A4D /* Statics */, + 518CD5822A3DA89800C86A4D /* Const */, 5141B6392A3B955400105625 /* MyPage */, 5141B6362A3B8DE000105625 /* Login */, 5141B6352A3B8DD900105625 /* Home */, @@ -104,9 +134,11 @@ 5156508C2A39E8EC00840026 /* Views */ = { isa = PBXGroup; children = ( - 51E674CE2A358DB600D30EE1 /* Main.storyboard */, - 5141B6332A3B83C900105625 /* Home.storyboard */, - 5141B63A2A3B956B00105625 /* MyPage.storyboard */, + 518CD5A82A3DB15600C86A4D /* Statics */, + 518CD5812A3DA89200C86A4D /* Const */, + 518CD5802A3DA87E00C86A4D /* MyPage */, + 518CD57F2A3DA87900C86A4D /* Home */, + 518CD57E2A3DA87200C86A4D /* Login */, ); path = Views; sourceTree = ""; @@ -114,10 +146,75 @@ 5156508D2A39E90A00840026 /* Models */ = { isa = PBXGroup; children = ( + 518CD5AD2A3DCEFA00C86A4D /* Home */, ); path = Models; sourceTree = ""; }; + 518CD57E2A3DA87200C86A4D /* Login */ = { + isa = PBXGroup; + children = ( + 51E674CE2A358DB600D30EE1 /* Main.storyboard */, + ); + path = Login; + sourceTree = ""; + }; + 518CD57F2A3DA87900C86A4D /* Home */ = { + isa = PBXGroup; + children = ( + 5141B6332A3B83C900105625 /* Home.storyboard */, + ); + path = Home; + sourceTree = ""; + }; + 518CD5802A3DA87E00C86A4D /* MyPage */ = { + isa = PBXGroup; + children = ( + 5141B63A2A3B956B00105625 /* MyPage.storyboard */, + ); + path = MyPage; + sourceTree = ""; + }; + 518CD5812A3DA89200C86A4D /* Const */ = { + isa = PBXGroup; + children = ( + 518CD5832A3DA8A300C86A4D /* TabBar.storyboard */, + ); + path = Const; + sourceTree = ""; + }; + 518CD5822A3DA89800C86A4D /* Const */ = { + isa = PBXGroup; + children = ( + 518CD5852A3DA8BD00C86A4D /* TabBarVC.swift */, + ); + path = Const; + sourceTree = ""; + }; + 518CD5A72A3DB14F00C86A4D /* Statics */ = { + isa = PBXGroup; + children = ( + 518CD5A92A3DB17A00C86A4D /* StaticVC.swift */, + ); + path = Statics; + sourceTree = ""; + }; + 518CD5A82A3DB15600C86A4D /* Statics */ = { + isa = PBXGroup; + children = ( + 518CD5AB2A3DB18E00C86A4D /* Static.storyboard */, + ); + path = Statics; + sourceTree = ""; + }; + 518CD5AD2A3DCEFA00C86A4D /* Home */ = { + isa = PBXGroup; + children = ( + 518CD5B02A3DCF2000C86A4D /* HomeTableViewCell.swift */, + ); + path = Home; + sourceTree = ""; + }; 51E674BC2A358DB600D30EE1 = { isa = PBXGroup; children = ( @@ -212,8 +309,10 @@ files = ( 51E674D52A358DB700D30EE1 /* LaunchScreen.storyboard in Resources */, 5141B63B2A3B956B00105625 /* MyPage.storyboard in Resources */, + 518CD5AC2A3DB18E00C86A4D /* Static.storyboard in Resources */, 51E674D22A358DB700D30EE1 /* Assets.xcassets in Resources */, 51E674D02A358DB600D30EE1 /* Main.storyboard in Resources */, + 518CD5842A3DA8A300C86A4D /* TabBar.storyboard in Resources */, 5141B6342A3B83C900105625 /* Home.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -225,14 +324,23 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 518CD5AA2A3DB17A00C86A4D /* StaticVC.swift in Sources */, 51E674CD2A358DB600D30EE1 /* ViewController.swift in Sources */, - 5141B6382A3B8DF900105625 /* HomeVC.swift in Sources */, + 518CD57D2A3D9FE300C86A4D /* HomeVC.swift in Sources */, 51E674C92A358DB600D30EE1 /* AppDelegate.swift in Sources */, + 51A794F22A3E0B390029B39D /* NewsDetailAPI.swift in Sources */, 5141B62D2A3B3AB500105625 /* LoginVC.swift in Sources */, + 518CD5B12A3DCF2000C86A4D /* HomeTableViewCell.swift in Sources */, + 51A794F02A3E07C30029B39D /* NewsDetailVC.swift in Sources */, + 518CD5B72A3DD20600C86A4D /* API.swift in Sources */, + 518CD5862A3DA8BD00C86A4D /* TabBarVC.swift in Sources */, 5141B6302A3B41CA00105625 /* Color.swift in Sources */, + 518CD5B92A3DD77C00C86A4D /* TopNewsAPI.swift in Sources */, 5141B63D2A3B957D00105625 /* MyPageVC.swift in Sources */, + 518CD5B52A3DD1F100C86A4D /* HomeAPI.swift in Sources */, 51E674CB2A358DB600D30EE1 /* SceneDelegate.swift in Sources */, 5141B6322A3B7D7300105625 /* SplashVC.swift in Sources */, + 518CD5B32A3DD04F00C86A4D /* EntireNewsAPI.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PolyHack/PolyHack.xcodeproj/project.xcworkspace/xcuserdata/mokjeong-a.xcuserdatad/UserInterfaceState.xcuserstate b/PolyHack/PolyHack.xcodeproj/project.xcworkspace/xcuserdata/mokjeong-a.xcuserdatad/UserInterfaceState.xcuserstate index 401082c..0d4dc0e 100644 Binary files a/PolyHack/PolyHack.xcodeproj/project.xcworkspace/xcuserdata/mokjeong-a.xcuserdatad/UserInterfaceState.xcuserstate and b/PolyHack/PolyHack.xcodeproj/project.xcworkspace/xcuserdata/mokjeong-a.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/PolyHack/PolyHack.xcodeproj/xcuserdata/mokjeong-a.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/PolyHack/PolyHack.xcodeproj/xcuserdata/mokjeong-a.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..9c9ae8f --- /dev/null +++ b/PolyHack/PolyHack.xcodeproj/xcuserdata/mokjeong-a.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/PolyHack/PolyHack/API/EntireNewsAPI.swift b/PolyHack/PolyHack/API/EntireNewsAPI.swift new file mode 100644 index 0000000..55a5aa1 --- /dev/null +++ b/PolyHack/PolyHack/API/EntireNewsAPI.swift @@ -0,0 +1,31 @@ +import Foundation + +// MARK: - NewsAPI +struct EntireNewsAPI: Codable { + let code: Int? + let message: String? + let data: [EntireNewsDatum]? +} + +struct EntireNewsDatum: Codable { + let news_id: Int? + let title: String? + let source: EntireSource? + let published_at: String? + let author: String? + let image_url: String? + + enum EntireCodingKeys: String, CodingKey { + case news_id + case title, source + case published_at + case author + case image_url + } +} + +enum EntireSource: String, Codable { + case cnn = "CNN" + case time = "Time" +} + diff --git a/PolyHack/PolyHack/API/NewsDetailAPI.swift b/PolyHack/PolyHack/API/NewsDetailAPI.swift new file mode 100644 index 0000000..f1f29e4 --- /dev/null +++ b/PolyHack/PolyHack/API/NewsDetailAPI.swift @@ -0,0 +1,25 @@ +import Foundation + +// MARK: - NewsDetailAPI +struct NewsDetailAPI: Codable { + let code: Int? + let message: String? + let data: NewsDetailDataClass? +} + +// MARK: - DataClass +struct NewsDetailDataClass: Codable { + let news_id: Int? + let title, content, source, published_at: String? + let author: String? + let image_url: String? + + enum CodingKeys: String, CodingKey { + case news_id + case title, content, source + case published_at + case author + case image_url + } +} + diff --git a/PolyHack/PolyHack/API/TopNewsAPI.swift b/PolyHack/PolyHack/API/TopNewsAPI.swift new file mode 100644 index 0000000..6510342 --- /dev/null +++ b/PolyHack/PolyHack/API/TopNewsAPI.swift @@ -0,0 +1,24 @@ +import Foundation + +// MARK: - TopNewsAPI +struct TopNewsAPI: Codable { + let code: Int? + let message: String? + let data: DataClass? +} + +// MARK: - DataClass +struct DataClass: Codable { + let newsID: Int? + let title, source, publishedAt, author: String? + let imageURL: String? + + enum CodingKeys: String, CodingKey { + case newsID = "news_id" + case title, source + case publishedAt = "published_at" + case author + case imageURL = "image_url" + } +} + diff --git a/PolyHack/PolyHack/AppDelegate.swift b/PolyHack/PolyHack/AppDelegate.swift index 9269d71..59a0a10 100644 --- a/PolyHack/PolyHack/AppDelegate.swift +++ b/PolyHack/PolyHack/AppDelegate.swift @@ -10,8 +10,6 @@ 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 diff --git a/PolyHack/PolyHack/Assets.xcassets/MainColor.colorset/Contents.json b/PolyHack/PolyHack/Assets.xcassets/MainColor.colorset/Contents.json index 2122739..c4aaaf1 100644 --- a/PolyHack/PolyHack/Assets.xcassets/MainColor.colorset/Contents.json +++ b/PolyHack/PolyHack/Assets.xcassets/MainColor.colorset/Contents.json @@ -20,12 +20,12 @@ } ], "color" : { - "color-space" : "srgb", + "color-space" : "extended-srgb", "components" : { "alpha" : "1.000", - "blue" : "255", - "green" : "255", - "red" : "255" + "blue" : "0xAB", + "green" : "0x58", + "red" : "0x25" } }, "idiom" : "universal" diff --git a/PolyHack/PolyHack/Assets.xcassets/Navigation/Contents.json b/PolyHack/PolyHack/Assets.xcassets/Navigation/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/PolyHack/PolyHack/Assets.xcassets/Navigation/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/PolyHack/PolyHack/Assets.xcassets/Navigation/Home.imageset/Contents.json b/PolyHack/PolyHack/Assets.xcassets/Navigation/Home.imageset/Contents.json new file mode 100644 index 0000000..f06155d --- /dev/null +++ b/PolyHack/PolyHack/Assets.xcassets/Navigation/Home.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Home.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/PolyHack/PolyHack/Assets.xcassets/Navigation/Home.imageset/Home.png b/PolyHack/PolyHack/Assets.xcassets/Navigation/Home.imageset/Home.png new file mode 100644 index 0000000..4a77a4f Binary files /dev/null and b/PolyHack/PolyHack/Assets.xcassets/Navigation/Home.imageset/Home.png differ diff --git a/PolyHack/PolyHack/Assets.xcassets/Navigation/Home_Grey.imageset/Contents.json b/PolyHack/PolyHack/Assets.xcassets/Navigation/Home_Grey.imageset/Contents.json new file mode 100644 index 0000000..c3ae8ed --- /dev/null +++ b/PolyHack/PolyHack/Assets.xcassets/Navigation/Home_Grey.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Home_Grey.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/PolyHack/PolyHack/Assets.xcassets/Navigation/Home_Grey.imageset/Home_Grey.png b/PolyHack/PolyHack/Assets.xcassets/Navigation/Home_Grey.imageset/Home_Grey.png new file mode 100644 index 0000000..7224d76 Binary files /dev/null and b/PolyHack/PolyHack/Assets.xcassets/Navigation/Home_Grey.imageset/Home_Grey.png differ diff --git a/PolyHack/PolyHack/Assets.xcassets/Navigation/MyPage.imageset/Contents.json b/PolyHack/PolyHack/Assets.xcassets/Navigation/MyPage.imageset/Contents.json new file mode 100644 index 0000000..4bb9ff6 --- /dev/null +++ b/PolyHack/PolyHack/Assets.xcassets/Navigation/MyPage.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "MyPage.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/PolyHack/PolyHack/Assets.xcassets/Navigation/MyPage.imageset/MyPage.png b/PolyHack/PolyHack/Assets.xcassets/Navigation/MyPage.imageset/MyPage.png new file mode 100644 index 0000000..ab7a2a2 Binary files /dev/null and b/PolyHack/PolyHack/Assets.xcassets/Navigation/MyPage.imageset/MyPage.png differ diff --git a/PolyHack/PolyHack/Assets.xcassets/Navigation/MyPage_Grey.imageset/Contents.json b/PolyHack/PolyHack/Assets.xcassets/Navigation/MyPage_Grey.imageset/Contents.json new file mode 100644 index 0000000..4bb9ff6 --- /dev/null +++ b/PolyHack/PolyHack/Assets.xcassets/Navigation/MyPage_Grey.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "MyPage.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/PolyHack/PolyHack/Assets.xcassets/Navigation/MyPage_Grey.imageset/MyPage.png b/PolyHack/PolyHack/Assets.xcassets/Navigation/MyPage_Grey.imageset/MyPage.png new file mode 100644 index 0000000..12387d8 Binary files /dev/null and b/PolyHack/PolyHack/Assets.xcassets/Navigation/MyPage_Grey.imageset/MyPage.png differ diff --git a/PolyHack/PolyHack/Assets.xcassets/Navigation/Static.imageset/Contents.json b/PolyHack/PolyHack/Assets.xcassets/Navigation/Static.imageset/Contents.json new file mode 100644 index 0000000..398f3fd --- /dev/null +++ b/PolyHack/PolyHack/Assets.xcassets/Navigation/Static.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Static.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/PolyHack/PolyHack/Assets.xcassets/Navigation/Static.imageset/Static.png b/PolyHack/PolyHack/Assets.xcassets/Navigation/Static.imageset/Static.png new file mode 100644 index 0000000..fb87aa5 Binary files /dev/null and b/PolyHack/PolyHack/Assets.xcassets/Navigation/Static.imageset/Static.png differ diff --git a/PolyHack/PolyHack/Assets.xcassets/Navigation/Static_Grey.imageset/Contents.json b/PolyHack/PolyHack/Assets.xcassets/Navigation/Static_Grey.imageset/Contents.json new file mode 100644 index 0000000..398f3fd --- /dev/null +++ b/PolyHack/PolyHack/Assets.xcassets/Navigation/Static_Grey.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Static.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/PolyHack/PolyHack/Assets.xcassets/Navigation/Static_Grey.imageset/Static.png b/PolyHack/PolyHack/Assets.xcassets/Navigation/Static_Grey.imageset/Static.png new file mode 100644 index 0000000..7502eea Binary files /dev/null and b/PolyHack/PolyHack/Assets.xcassets/Navigation/Static_Grey.imageset/Static.png differ diff --git a/PolyHack/PolyHack/Const/API.swift b/PolyHack/PolyHack/Const/API.swift new file mode 100644 index 0000000..c24b6c1 --- /dev/null +++ b/PolyHack/PolyHack/Const/API.swift @@ -0,0 +1,79 @@ +import Foundation + +// API URL + +let BASE_URL : String = "http://localhost:8080/news" + +let ENTIRE_DETAIL_URL : String = "\(BASE_URL)" +let NEWS_DETAIL_URL : String = "\(BASE_URL)/detail" +let TOP_NEWS_API : String = "\(BASE_URL)/top" + + +class FetchNews { + + func entireNews() { + guard let url = URL(string: ENTIRE_DETAIL_URL) else { + print("Invalid URL") + return + } + + let session = URLSession.shared + + let task = session.dataTask(with: url) { (data, response, error) in + + if let error = error { + print("Error: \(error.localizedDescription)") + return + } + + guard let data = data else { + print("No data received") + return + } + + do { + let newsAPI = try JSONDecoder().decode(EntireNewsAPI.self, from: data) + print(newsAPI) + } catch { + print("Error decoding data: \(error.localizedDescription)") + } + } + task.resume() + } + + + // Detail news API + func detailNews(id: Int) -> String { + return "\(NEWS_DETAIL_URL)/\(id)" + } + + // Top News API + func fetchTopNews() { + guard let url = URL(string: TOP_NEWS_API) else { + print("Invalid URL") + return + } + + let session = URLSession.shared + + let task = session.dataTask(with: url) { (data, response, error) in + if let error = error { + print("Error: \(error.localizedDescription)") + return + } + + guard let data = data else { + print("No data received") + return + } + + do { + let newsAPI = try JSONDecoder().decode(TopNewsAPI.self, from: data) + print(newsAPI) + } catch { + print("Error decoding data: \(error.localizedDescription)") + } + } + task.resume() + } +} diff --git a/PolyHack/PolyHack/Controller/Const/TabBarVC.swift b/PolyHack/PolyHack/Controller/Const/TabBarVC.swift new file mode 100644 index 0000000..a70dd40 --- /dev/null +++ b/PolyHack/PolyHack/Controller/Const/TabBarVC.swift @@ -0,0 +1,29 @@ +// +// TabBarVC.swift +// PolyHack +// +// Created by 목정아 on 2023/06/17. +// + +import UIKit + +class TabBarVC: UITabBarController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/PolyHack/PolyHack/Controller/Home/HomeAPI.swift b/PolyHack/PolyHack/Controller/Home/HomeAPI.swift new file mode 100644 index 0000000..a1300c5 --- /dev/null +++ b/PolyHack/PolyHack/Controller/Home/HomeAPI.swift @@ -0,0 +1,8 @@ +// +// HomeAPI.swift +// PolyHack +// +// Created by 목정아 on 2023/06/17. +// + +import Foundation diff --git a/PolyHack/PolyHack/Controller/Home/HomeVC.swift b/PolyHack/PolyHack/Controller/Home/HomeVC.swift index 1c50aba..d3c28eb 100644 --- a/PolyHack/PolyHack/Controller/Home/HomeVC.swift +++ b/PolyHack/PolyHack/Controller/Home/HomeVC.swift @@ -1,29 +1,260 @@ -// -// HomeVC.swift -// PolyHack -// -// Created by 목정아 on 2023/06/16. -// - import UIKit class HomeVC: UIViewController { - + + // MARK: - Variable + let newsFetcher = FetchNews() + var TopnewsData: TopNewsAPI? + + var entireNewsArry: [EntireNewsDatum] = [] + var entireNewsAPI: EntireNewsAPI? + + var newsDetailID : Int = 1 + + // MARK: - IBOutlet + @IBOutlet weak var tagView: UIView! + @IBOutlet weak var bannerImage: UIImageView! + @IBOutlet weak var bannerTitle: UILabel! + @IBOutlet weak var bannerAuthor: UILabel! + @IBOutlet weak var bannerPublished: UILabel! + + @IBOutlet weak var entireTableView: UITableView! + + + // MARK: - LifeCycle + override func viewDidLoad() { super.viewDidLoad() + UI() + delegate() + fetchNewsData() + fetchEntireNewsData() + } + + func delegate() { + self.entireTableView.delegate = self + self.entireTableView.dataSource = self + } + + // MARK: - Func + func UI() { + // tag UIView + tagView.layer.cornerRadius = 12.0 + + // Image + bannerImage.contentMode = .scaleAspectFill + bannerImage.clipsToBounds = true + + bannerAuthor.textColor = .white + bannerPublished.textColor = .white + bannerTitle.textColor = .white + } + + func fetchNewsData() { + guard let url = URL(string: TOP_NEWS_API) else { + print("Invalid URL") + return + } + + let session = URLSession.shared + + let task = session.dataTask(with: url) { [weak self] (data, response, error) in + if let error = error { + print("Error: \(error.localizedDescription)") + return + } + + guard let data = data else { + print("No data received") + return + } + + do { + let newsAPI = try JSONDecoder().decode(TopNewsAPI.self, from: data) + self?.TopnewsData = newsAPI + + DispatchQueue.main.async { + self?.updateUI() + } + } catch { + print("Error decoding data: \(error.localizedDescription)") + } + } + task.resume() + } + + fileprivate func extractedFunc(_ newsData: TopNewsAPI) { + if let dateString = newsData.data?.publishedAt { + let formattedString = formatDateString(dateString) + self.bannerPublished.text = "Published \(formattedString)" + } else { + self.bannerPublished.text = "" + } + } + + func updateUI() { + + guard let newsData = self.TopnewsData else { + return + } + + if let imageURL = newsData.data?.imageURL, let url = URL(string: imageURL) { + DispatchQueue.global().async { + if let data = try? Data(contentsOf: url) { + let image = UIImage(data: data) + + DispatchQueue.main.async { + self.bannerImage.image = image + self.bannerImage.frame.size.height = 294 + } + } + } + } + + if let title = newsData.data?.title { + self.bannerTitle.text = title + } + + if let author = newsData.data?.author, let source = newsData.data?.source { + self.bannerAuthor.text = "\(author), \(source)" + } else { + self.bannerAuthor.text = "Unknown" + } + + if let dateString = newsData.data?.publishedAt { + let formattedString = formatDateString(dateString) + self.bannerPublished.text = "Published \(formattedString)" + } else { + self.bannerPublished.text = "" + } + + } + + func formatDateString(_ dateString: String) -> String { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss" + + if let date = formatter.date(from: dateString) { + let currentDate = Date() + + if date < currentDate { + formatter.dateFormat = "yyyy-MM-dd" + return formatter.string(from: date) + } else { + formatter.dateFormat = "h:mm a" + return formatter.string(from: date) + } + } + return "" + } + + func fetchEntireNewsData() { + + guard let url = URL(string: ENTIRE_DETAIL_URL) else { + print("Invalid URL") + return + } + + let session = URLSession.shared + + let task = session.dataTask(with: url) { [weak self] (data, response, error) in + + if let error = error { + print("Error: \(error.localizedDescription)") + return + } + + guard let data = data else { + print("No data received") + return + } + + do { + let newsAPI = try JSONDecoder().decode(EntireNewsAPI.self, from: data) + self?.entireNewsAPI = newsAPI + + DispatchQueue.main.async { + self?.entireTableView.reloadData() + } + } catch { + print("Error decoding data: \(error.localizedDescription)") + } + } + task.resume() + } +} - // Do any additional setup after loading the view. +extension HomeVC : UITableViewDelegate { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return self.entireNewsAPI?.data?.count ?? 0 } + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + + guard let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTableViewCell", for: indexPath) as? HomeTableViewCell else { + return UITableViewCell() + } + + + guard let newsData = self.entireNewsAPI?.data else { + return cell + } + + if indexPath.row < newsData.count { + let news = newsData[indexPath.row] + cell.newsTitle.text = news.title + + if news.author != nil && news.published_at != nil { + cell.newsTime.text = "By \(String(describing: news.author!)), \(String(describing: news.source!)) | \(formatDateString(news.published_at!))" + } else if news.author == nil && news.published_at != nil { + cell.newsTime.text = "\(String(describing: news.source!)) | \(formatDateString(news.published_at!))" + } else if news.author != nil && news.published_at == nil { + cell.newsTime.text = "\(String(describing: news.author!))" + } else { + cell.newsTime.text = "" + } + + cell.newsImage.image = nil + cell.newsImage.contentMode = .center + cell.newsImage.backgroundColor = .lightGray + cell.newsImage.frame.size.height = 104 + cell.newsImage.frame.size.width = 104 + cell.newsImage.clipsToBounds = true + cell.newsImage.layer.cornerRadius = 18 + + if let imageURL = news.image_url, let url = URL(string: imageURL) { + DispatchQueue.global().async { + if let data = try? Data(contentsOf: url) { + let image = UIImage(data: data) + + DispatchQueue.main.async { + if cell.newsImage.image == nil { + cell.newsImage.contentMode = .scaleAspectFill + cell.newsImage.image = image + } + } + } + } + } + } + return cell + } - /* - // MARK: - Navigation +} - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. +extension HomeVC : UITableViewDataSource { + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + + let storyboard = UIStoryboard(name: "Home", bundle: nil) + let nextViewController = storyboard.instantiateViewController(withIdentifier: "NewsDetailVC") as! NewsDetailVC + + if let selectedData = entireNewsAPI?.data?[indexPath.row].news_id { + nextViewController.selectedIndex = selectedData + } + + self.modalPresentationStyle = .fullScreen + self.present(nextViewController, animated: true, completion: nil) } - */ } diff --git a/PolyHack/PolyHack/Controller/Home/NewsDetailVC.swift b/PolyHack/PolyHack/Controller/Home/NewsDetailVC.swift new file mode 100644 index 0000000..6c58433 --- /dev/null +++ b/PolyHack/PolyHack/Controller/Home/NewsDetailVC.swift @@ -0,0 +1,128 @@ +import UIKit + +class NewsDetailVC: UIViewController { + + // MARK: - Var + let fetchNews = FetchNews() + var detailnewsData: NewsDetailAPI? + var selectedIndex: Int = 1 // Check Index Row Number + + // MARK: - @IBOutlet + @IBOutlet weak var newsTitle: UILabel! + @IBOutlet weak var newsAuthor: UILabel! + @IBOutlet weak var newsDate: UILabel! + @IBOutlet weak var newsImage: UIImageView! + @IBOutlet weak var newsContents: UILabel! + @IBOutlet weak var scrollView: UIView! + + + // MARK: - LifeCycle + override func viewDidLoad() { + super.viewDidLoad() + print(selectedIndex) + UI() + fetchNewsData() + } + + func UI() { + // Image + newsImage.contentMode = .scaleAspectFill + newsImage.clipsToBounds = true + } + + // MARK: - UI + func fetchNewsData() { + guard let url = URL(string: fetchNews.detailNews(id: selectedIndex)) else { + print("Invalid URL") + return + } + + let session = URLSession.shared + + let task = session.dataTask(with: url) { [weak self] (data, response, error) in + if let error = error { + print("Error: \(error.localizedDescription)") + return + } + + guard let data = data else { + print("No data received") + return + } + + do { + let newsAPI = try JSONDecoder().decode(NewsDetailAPI.self, from: data) + self?.detailnewsData = newsAPI + + DispatchQueue.main.async { + self?.updateUI() + } + } catch { + print("Error decoding data: \(error.localizedDescription)") + } + } + task.resume() + } + + func updateUI() { + + guard let newsData = self.detailnewsData else { + return + } + + if let imageURL = newsData.data?.image_url, let url = URL(string: imageURL) { + DispatchQueue.global().async { + if let data = try? Data(contentsOf: url) { + let image = UIImage(data: data) + + DispatchQueue.main.async { + self.newsImage.image = image + self.newsImage.frame.size.height = 245 + } + } + } + } + + + if let title = newsData.data?.title { + self.newsTitle.text = title + } + + if let author = newsData.data?.author, let source = newsData.data?.source { + self.newsAuthor.text = "\(author), \(source)" + } else { + self.newsAuthor.text = "" + } + + if let dateString = newsData.data?.published_at { + let formattedString = formatDateString(dateString) + self.newsDate.text = "Published \(formattedString)" + } else { + self.newsDate.text = "" + } + + if let content = newsData.data?.content { + self.newsContents.text = content + } + + } + + + func formatDateString(_ dateString: String) -> String { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss" + + if let date = formatter.date(from: dateString) { + let currentDate = Date() + + if date < currentDate { + formatter.dateFormat = "yyyy-MM-dd" + return formatter.string(from: date) + } else { + formatter.dateFormat = "h:mm a" + return formatter.string(from: date) + } + } + return "" + } +} diff --git a/PolyHack/PolyHack/Controller/Login/LoginVC.swift b/PolyHack/PolyHack/Controller/Login/LoginVC.swift index 2f42384..f1668b9 100644 --- a/PolyHack/PolyHack/Controller/Login/LoginVC.swift +++ b/PolyHack/PolyHack/Controller/Login/LoginVC.swift @@ -152,10 +152,10 @@ class LoginVC: UIViewController { showErrorLabel() return } else { - let storyboard = UIStoryboard(name: "Home", bundle: nil) - let homeViewController = storyboard.instantiateViewController(withIdentifier: "HomeVC") as! HomeVC + let storyboard = UIStoryboard(name: "TabBar", bundle: nil) + let homeViewController = storyboard.instantiateViewController(withIdentifier: "TabBarVC") as! TabBarVC homeViewController.modalPresentationStyle = .fullScreen - self.present(homeViewController, animated: true, completion: nil) + self.present(homeViewController, animated: true, completion: nil) } } diff --git a/PolyHack/PolyHack/Controller/Statics/StaticVC.swift b/PolyHack/PolyHack/Controller/Statics/StaticVC.swift new file mode 100644 index 0000000..ece3b81 --- /dev/null +++ b/PolyHack/PolyHack/Controller/Statics/StaticVC.swift @@ -0,0 +1,29 @@ +// +// StaticVC.swift +// PolyHack +// +// Created by 목정아 on 2023/06/17. +// + +import UIKit + +class StaticVC: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/PolyHack/PolyHack/Models/Home/HomeTableViewCell.swift b/PolyHack/PolyHack/Models/Home/HomeTableViewCell.swift new file mode 100644 index 0000000..668504e --- /dev/null +++ b/PolyHack/PolyHack/Models/Home/HomeTableViewCell.swift @@ -0,0 +1,16 @@ +import UIKit + +class HomeTableViewCell: UITableViewCell { + + // MARK: - IBOutlet + + @IBOutlet weak var newsImage: UIImageView! + @IBOutlet weak var newsTitle: UILabel! + @IBOutlet weak var newsTime: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + + } + +} diff --git a/PolyHack/PolyHack/SceneDelegate.swift b/PolyHack/PolyHack/SceneDelegate.swift index a21dde1..4bd5121 100644 --- a/PolyHack/PolyHack/SceneDelegate.swift +++ b/PolyHack/PolyHack/SceneDelegate.swift @@ -11,14 +11,20 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? - func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. - // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. - // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). - guard let _ = (scene as? UIWindowScene) else { return } + guard let windowScene = (scene as? UIWindowScene) else { return } + + let window = UIWindow(windowScene: windowScene) + self.window = window + + let storyboard = UIStoryboard(name: "Main", bundle: nil) + let homeTabBarController = storyboard.instantiateViewController(withIdentifier: "SplashVC") as! SplashVC + window.rootViewController = homeTabBarController + + 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. @@ -47,6 +53,14 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { // to restore the scene back to its current state. } + func changeRootViewController(_ vc: UIViewController, animated: Bool = true) { + guard let window = self.window else { + return + } + + // change the root view controller to your specific view controller + window.rootViewController = vc + } } diff --git a/PolyHack/PolyHack/Views/Const/TabBar.storyboard b/PolyHack/PolyHack/Views/Const/TabBar.storyboard new file mode 100644 index 0000000..5c16908 --- /dev/null +++ b/PolyHack/PolyHack/Views/Const/TabBar.storyboard @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PolyHack/PolyHack/Views/Home.storyboard b/PolyHack/PolyHack/Views/Home.storyboard deleted file mode 100644 index fef19c0..0000000 --- a/PolyHack/PolyHack/Views/Home.storyboard +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PolyHack/PolyHack/Views/Home/Home.storyboard b/PolyHack/PolyHack/Views/Home/Home.storyboard new file mode 100644 index 0000000..76f846d --- /dev/null +++ b/PolyHack/PolyHack/Views/Home/Home.storyboard @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PolyHack/PolyHack/Views/Base.lproj/Main.storyboard b/PolyHack/PolyHack/Views/Login/Base.lproj/Main.storyboard similarity index 98% rename from PolyHack/PolyHack/Views/Base.lproj/Main.storyboard rename to PolyHack/PolyHack/Views/Login/Base.lproj/Main.storyboard index df4c111..7c26d48 100644 --- a/PolyHack/PolyHack/Views/Base.lproj/Main.storyboard +++ b/PolyHack/PolyHack/Views/Login/Base.lproj/Main.storyboard @@ -10,7 +10,7 @@ - + @@ -44,10 +44,11 @@ + - + @@ -141,7 +142,7 @@ - + diff --git a/PolyHack/PolyHack/Views/MyPage.storyboard b/PolyHack/PolyHack/Views/MyPage/MyPage.storyboard similarity index 78% rename from PolyHack/PolyHack/Views/MyPage.storyboard rename to PolyHack/PolyHack/Views/MyPage/MyPage.storyboard index e122344..9b18067 100644 --- a/PolyHack/PolyHack/Views/MyPage.storyboard +++ b/PolyHack/PolyHack/Views/MyPage/MyPage.storyboard @@ -9,16 +9,18 @@ - + - + + + @@ -26,6 +28,8 @@ + + diff --git a/PolyHack/PolyHack/Views/Statics/Static.storyboard b/PolyHack/PolyHack/Views/Statics/Static.storyboard new file mode 100644 index 0000000..fef99f2 --- /dev/null +++ b/PolyHack/PolyHack/Views/Statics/Static.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +