diff --git a/iOS_Study_B.xcodeproj/project.pbxproj b/iOS_Study_B.xcodeproj/project.pbxproj index 9763af9..b386b98 100644 --- a/iOS_Study_B.xcodeproj/project.pbxproj +++ b/iOS_Study_B.xcodeproj/project.pbxproj @@ -7,10 +7,11 @@ objects = { /* Begin PBXBuildFile section */ + 2D6D0B0D2B0BCBF2007F19CA /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 2D6D0B0C2B0BCBF2007F19CA /* SnapKit */; }; + 2D6D0B0F2B0BCBF2007F19CA /* SnapKit-Dynamic in Frameworks */ = {isa = PBXBuildFile; productRef = 2D6D0B0E2B0BCBF2007F19CA /* SnapKit-Dynamic */; }; 954B6B812AC57DAA00FDCFAB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954B6B802AC57DAA00FDCFAB /* AppDelegate.swift */; }; 954B6B832AC57DAA00FDCFAB /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954B6B822AC57DAA00FDCFAB /* SceneDelegate.swift */; }; 954B6B852AC57DAA00FDCFAB /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954B6B842AC57DAA00FDCFAB /* ViewController.swift */; }; - 954B6B882AC57DAA00FDCFAB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 954B6B862AC57DAA00FDCFAB /* Main.storyboard */; }; 954B6B8A2AC57DAB00FDCFAB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 954B6B892AC57DAB00FDCFAB /* Assets.xcassets */; }; 954B6B8D2AC57DAB00FDCFAB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 954B6B8B2AC57DAB00FDCFAB /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ @@ -20,7 +21,6 @@ 954B6B802AC57DAA00FDCFAB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 954B6B822AC57DAA00FDCFAB /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 954B6B842AC57DAA00FDCFAB /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 954B6B872AC57DAA00FDCFAB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 954B6B892AC57DAB00FDCFAB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 954B6B8C2AC57DAB00FDCFAB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 954B6B8E2AC57DAB00FDCFAB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -31,6 +31,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 2D6D0B0D2B0BCBF2007F19CA /* SnapKit in Frameworks */, + 2D6D0B0F2B0BCBF2007F19CA /* SnapKit-Dynamic in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -59,7 +61,6 @@ 954B6B802AC57DAA00FDCFAB /* AppDelegate.swift */, 954B6B822AC57DAA00FDCFAB /* SceneDelegate.swift */, 954B6B842AC57DAA00FDCFAB /* ViewController.swift */, - 954B6B862AC57DAA00FDCFAB /* Main.storyboard */, 954B6B892AC57DAB00FDCFAB /* Assets.xcassets */, 954B6B8B2AC57DAB00FDCFAB /* LaunchScreen.storyboard */, 954B6B8E2AC57DAB00FDCFAB /* Info.plist */, @@ -83,6 +84,10 @@ dependencies = ( ); name = iOS_Study_B; + packageProductDependencies = ( + 2D6D0B0C2B0BCBF2007F19CA /* SnapKit */, + 2D6D0B0E2B0BCBF2007F19CA /* SnapKit-Dynamic */, + ); productName = iOS_Study_B; productReference = 954B6B7D2AC57DAA00FDCFAB /* iOS_Study_B.app */; productType = "com.apple.product-type.application"; @@ -111,6 +116,9 @@ Base, ); mainGroup = 954B6B742AC57DAA00FDCFAB; + packageReferences = ( + 2D6D0B0B2B0BCBF2007F19CA /* XCRemoteSwiftPackageReference "SnapKit" */, + ); productRefGroup = 954B6B7E2AC57DAA00FDCFAB /* Products */; projectDirPath = ""; projectRoot = ""; @@ -127,7 +135,6 @@ files = ( 954B6B8D2AC57DAB00FDCFAB /* LaunchScreen.storyboard in Resources */, 954B6B8A2AC57DAB00FDCFAB /* Assets.xcassets in Resources */, - 954B6B882AC57DAA00FDCFAB /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -147,14 +154,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ - 954B6B862AC57DAA00FDCFAB /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 954B6B872AC57DAA00FDCFAB /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; 954B6B8B2AC57DAB00FDCFAB /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( @@ -291,7 +290,6 @@ INFOPLIST_FILE = iOS_Study_B/Info.plist; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; LD_RUNPATH_SEARCH_PATHS = ( @@ -318,7 +316,6 @@ INFOPLIST_FILE = iOS_Study_B/Info.plist; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; LD_RUNPATH_SEARCH_PATHS = ( @@ -356,6 +353,30 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 2D6D0B0B2B0BCBF2007F19CA /* XCRemoteSwiftPackageReference "SnapKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/SnapKit/SnapKit.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.6.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 2D6D0B0C2B0BCBF2007F19CA /* SnapKit */ = { + isa = XCSwiftPackageProductDependency; + package = 2D6D0B0B2B0BCBF2007F19CA /* XCRemoteSwiftPackageReference "SnapKit" */; + productName = SnapKit; + }; + 2D6D0B0E2B0BCBF2007F19CA /* SnapKit-Dynamic */ = { + isa = XCSwiftPackageProductDependency; + package = 2D6D0B0B2B0BCBF2007F19CA /* XCRemoteSwiftPackageReference "SnapKit" */; + productName = "SnapKit-Dynamic"; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 954B6B752AC57DAA00FDCFAB /* Project object */; } diff --git a/iOS_Study_B.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/iOS_Study_B.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..009c162 --- /dev/null +++ b/iOS_Study_B.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,14 @@ +{ + "pins" : [ + { + "identity" : "snapkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SnapKit/SnapKit.git", + "state" : { + "revision" : "f222cbdf325885926566172f6f5f06af95473158", + "version" : "5.6.0" + } + } + ], + "version" : 2 +} diff --git a/iOS_Study_B/Base.lproj/Main.storyboard b/iOS_Study_B/Base.lproj/Main.storyboard deleted file mode 100644 index 25a7638..0000000 --- a/iOS_Study_B/Base.lproj/Main.storyboard +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/iOS_Study_B/Info.plist b/iOS_Study_B/Info.plist index dd3c9af..0eb786d 100644 --- a/iOS_Study_B/Info.plist +++ b/iOS_Study_B/Info.plist @@ -15,8 +15,6 @@ Default Configuration UISceneDelegateClassName $(PRODUCT_MODULE_NAME).SceneDelegate - UISceneStoryboardFile - Main diff --git a/iOS_Study_B/SceneDelegate.swift b/iOS_Study_B/SceneDelegate.swift index 9987c27..ebae390 100644 --- a/iOS_Study_B/SceneDelegate.swift +++ b/iOS_Study_B/SceneDelegate.swift @@ -13,10 +13,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { 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 } + window = UIWindow(windowScene: windowScene) // SceneDelegate의 프로퍼티에 설정해줌 + let mainViewController = ViewController() // 맨 처음 보여줄 ViewController + + window?.rootViewController = mainViewController + window?.makeKeyAndVisible() } func sceneDidDisconnect(_ scene: UIScene) { diff --git a/iOS_Study_B/ViewController.swift b/iOS_Study_B/ViewController.swift index f3577b5..728801a 100644 --- a/iOS_Study_B/ViewController.swift +++ b/iOS_Study_B/ViewController.swift @@ -6,14 +6,257 @@ // import UIKit +import SnapKit class ViewController: UIViewController { - + let titleLabel: UILabel = { + let label = UILabel() + label.text = "계산기" + label.font = UIFont.boldSystemFont(ofSize: 20) + label.textAlignment = .center + label.textColor = UIColor.white + + return label + }() + + let number1TextField: UITextField = { + let textField = UITextField() + textField.layer.cornerRadius = 6 + textField.layer.borderWidth = 1 + textField.layer.borderColor = UIColor.black.cgColor + textField.backgroundColor = .white + textField.placeholder = "숫자 1 입력" + + let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: textField.frame.height)) + textField.leftView = paddingView + textField.leftViewMode = .always + + return textField + }() + + let number2TextField: UITextField = { + let textField = UITextField() + textField.layer.cornerRadius = 6 + textField.layer.borderWidth = 1 + textField.layer.borderColor = UIColor.black.cgColor + textField.backgroundColor = .white + textField.placeholder = "숫자 2 입력" + + let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: textField.frame.height)) + textField.leftView = paddingView + textField.leftViewMode = .always + + return textField + }() + + let resultLabel: UILabel = { + let label = UILabel() + label.text = "연산자를 선택해주세요." + label.textColor = .white + label.textAlignment = .center + label.font = UIFont.systemFont(ofSize: 18) + return label + }() + + let plusButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle("+", for: .normal) + button.setTitleColor(.white, for: .normal) + button.backgroundColor = UIColor(red: 233/255, green: 164/255, blue: 61/255, alpha: 1.0) + button.layer.cornerRadius = 20 + button.titleLabel?.font = .systemFont(ofSize: 18) + + //클릭시 실행할 동작 + button.addTarget(self, action: #selector(plusButtonPressed), for: .touchUpInside) + + return button + }() + + let subButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle("-", for: .normal) + button.setTitleColor(.white, for: .normal) + button.backgroundColor = UIColor(red: 233/255, green: 164/255, blue: 61/255, alpha: 1.0) + button.layer.cornerRadius = 20 + button.titleLabel?.font = .systemFont(ofSize: 18) + + //클릭시 실행할 동작 + button.addTarget(self, action: #selector(subButtonPressed), for: .touchUpInside) + + return button + }() + + let mulButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle("×", for: .normal) + button.setTitleColor(.white, for: .normal) + button.backgroundColor = UIColor(red: 233/255, green: 164/255, blue: 61/255, alpha: 1.0) + button.layer.cornerRadius = 20 + button.titleLabel?.font = .systemFont(ofSize: 18) + + //클릭시 실행할 동작 + button.addTarget(self, action: #selector(mulButtonPressed), for: .touchUpInside) + + return button + }() + + let divButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle("÷", for: .normal) + button.setTitleColor(.white, for: .normal) + button.backgroundColor = UIColor(red: 233/255, green: 164/255, blue: 61/255, alpha: 1.0) + button.layer.cornerRadius = 20 + button.titleLabel?.font = .systemFont(ofSize: 18) + + //클릭시 실행할 동작 + button.addTarget(self, action: #selector(divButtonPressed), for: .touchUpInside) + + return button + }() + + let resetButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle("초기화", for: .normal) + button.setTitleColor(.white, for: .normal) + button.backgroundColor = UIColor(red: 233/255, green: 164/255, blue: 61/255, alpha: 1.0) + button.layer.cornerRadius = 20 + button.titleLabel?.font = .systemFont(ofSize: 18) + + //클릭시 실행할 동작 + button.addTarget(self, action: #selector(resetButtonPressed), for: .touchUpInside) + + return button + }() + + + + override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view. + view.backgroundColor = .black + + configureSubviews() + makeConstraints() + } + + func configureSubviews() { + view.addSubview(titleLabel) + view.addSubview(number1TextField) + view.addSubview(number2TextField) + view.addSubview(resultLabel) + view.addSubview(plusButton) + view.addSubview(subButton) + view.addSubview(mulButton) + view.addSubview(divButton) + view.addSubview(resetButton) + } + + func makeConstraints() { + titleLabel.snp.makeConstraints { make in + make.top.equalToSuperview().offset(57) + make.centerX.equalToSuperview() + make.width.equalTo(114) + make.height.equalTo(23) + } + number1TextField.snp.makeConstraints { make in + make.top.equalToSuperview().offset(111) + make.centerX.equalToSuperview() + make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading).offset(36) + make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-36) + make.height.equalTo(38) + } + number2TextField.snp.makeConstraints { make in + make.top.equalToSuperview().offset(172) + make.centerX.equalToSuperview() + make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading).offset(36) + make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-36) + make.height.equalTo(38) + } + resultLabel.snp.makeConstraints { make in + make.top.equalToSuperview().offset(250) + make.centerX.equalToSuperview() + make.width.equalTo(188) + make.height.equalTo(28) + } + plusButton.snp.makeConstraints { make in + make.top.equalToSuperview().offset(316) + make.centerX.equalToSuperview() + make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading).offset(36) + make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-36) + make.height.equalTo(45) + } + subButton.snp.makeConstraints { make in + make.top.equalToSuperview().offset(377) + make.centerX.equalToSuperview() + make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading).offset(36) + make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-36) + make.height.equalTo(45) + } + mulButton.snp.makeConstraints { make in + make.top.equalToSuperview().offset(438) + make.centerX.equalToSuperview() + make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading).offset(36) + make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-36) + make.height.equalTo(45) + } + divButton.snp.makeConstraints { make in + make.top.equalToSuperview().offset(499) + make.centerX.equalToSuperview() + make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading).offset(36) + make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-36) + make.height.equalTo(45) + } + resetButton.snp.makeConstraints { make in + make.top.equalToSuperview().offset(560) + make.centerX.equalToSuperview() + make.leading.equalTo(view.safeAreaLayoutGuide.snp.leading).offset(36) + make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-36) + make.height.equalTo(45) + } + } + func performCalculation(operation: (Int, Int) -> Int) { + // 입력이 숫자로 변환 가능한 경우 + if let inputText1 = number1TextField.text, let number1 = Int(inputText1), + let inputText2 = number2TextField.text, let number2 = Int(inputText2) { + let result = operation(number1, number2) + resultLabel.text = String(result) + } + // 빈 문자열이 있는 경우 + else if number1TextField.text?.isEmpty == true { + resultLabel.text = "숫자를 모두 입력해주세요." + } else if number2TextField.text?.isEmpty == true { + resultLabel.text = "숫자를 모두 입력해주세요." + } + // 빈 문자열이 아닌데 숫자로 변환이 불가능한 경우 + else { + resultLabel.text = "숫자만 입력해주세요." + } + + + } + + @objc func plusButtonPressed() { + performCalculation(operation: +) + } + @objc func subButtonPressed() { + performCalculation(operation: -) + } + @objc func mulButtonPressed() { + performCalculation(operation: *) + } + @objc func divButtonPressed() { + if number2TextField.text?.isEmpty == true { + performCalculation(operation: /) + } + else if let inputText2 = number2TextField.text, !inputText2.isEmpty, let divisor = Int(inputText2), divisor != 0 { + performCalculation(operation: /) + } else { + resultLabel.text = "0으로 나눌 수 없습니다." + } + } + @objc func resetButtonPressed() { + number1TextField.text = "" + number2TextField.text = "" + resultLabel.text = "연산자를 선택해주세요." } - - } -