본문 바로가기
ios 뽀개기/ios 응용해보기

2 아이폰 ios 스위프트 계산기 만들기(컨트롤, 모델 분리해서 구현)

by 인생여희 2017. 12. 5.
반응형

2 아이폰 ios 스위프트 계산기 만들기



//  ViewController.swift

//  Calulatoer2

//

//  Created by MacBookPro on 2017. 12. 5..

//  Copyright © 2017년 MacBookPro. All rights reserved.

//



//controller 부분


//모듈: 클래스의 집합

import UIKit

//상속받음 , controller는 uiviewcontroller의 상속을 받는다.

class ViewController: UIViewController {


    //라벨 아웃렛 변수

    @IBOutlet weak var display: UILabel! //!를 붙여주면 값을 암묵적으로 추출해서 누구든 자유롭게 쓸수 있게 하겠다는 뜻, 만약 nil이면 앱이 멈춘다.

    

    //스위프트에서는 모든 변수가 초기값을 가져야 한다!

    var userIsInTheMiddleOfTyping: Bool = false

    

    //숫자 눌렀을 때

    @IBAction func touchDigit(_ sender: UIButton) {

        

        // 경고가 뜬다.

        //let을 넣어야 한다. 읽어오고 싶을 때..array나 dictionary를 사용할 때

        //"!" 는 옵셔널 강제적으로 값을 가져올때, 하지만 set 되지 않은 값이 있다면 충돌이 일어난다.

        //안전하게 꺼내오는 방법이 있다.

        

        let digit = sender.currentTitle! //!를 붙여줘서 옵셔널 -> stirng 타입으로 바뀌었다. 값이 nil 이면 충돌

        

        //숫자를 입력중이라면

        if(userIsInTheMiddleOfTyping){

            //text를 옵셔널 타입에 보낼수 없어서 생기는 에러(옵셔널은 텍스트를 이해할 수 없다.-> ullable 타입인 display의 연관값을 가져와야 한다.)

            //display의 값이 nil이라면 에러가 뜬다.

            let textCurrentlyInDisplay = display.text!

            display.text = textCurrentlyInDisplay + digit

        }else{

            //입력중이 아니라면(처음 키패드를 눌렀을 때 0이 나오게)

            display.text = digit

        }

        userIsInTheMiddleOfTyping = true

//뷰의 미니언이 컨트롤에게 위임한다

    }

    

    //================ 이부분 추가됨. =============================================//

    

    //계산 프로퍼티(라벨에 있는 값을 굳이 더블로 안바꿔줘도 되고 이 프로퍼티만 밑에서 호출 해주면 된다.)

    var displayValue: Double {

        get{

            

            return Double(display.text!)! //안의 값이 문자열이면 변환이 안될 수도 있으므로 !

        }

        

        set{

            //newValue 키워드

            display.text = String(newValue)

        }

    }

    

 //================ 이부분 추가됨. =============================================//

    

    //파이가 눌러졌을때

    @IBAction func performOperation(_ sender: UIButton) {

    

        //뒤에 느낌표 붙여서 옵셔널을 스트링값으로 바꾸기 (강제추출) , 값이 nil일 때 충돌남

        //let mathematicalSymbol = sender.currentTitle!

        

        //더 안전한 방법(set이 되었을 때)

        if let mathematicalSymbol = sender.currentTitle{

            //파이를 입력할 때 숫자들 지워버리기

            userIsInTheMiddleOfTyping = false

            if mathematicalSymbol == "π"{

                //display.text = String(M_PI). -- 계산 프로퍼티를 만들기 전

                displayValue = M_PI // -- 계산프로퍼티를 만들고 난 후

            }else if(mathematicalSymbol == "√"){

                //계산 프로퍼티가 없었으면 직접 라벨에서 값을 가져와서 double로 바꿔준다음에 다시 라발에 대입을 시켜줘야 한다.

                displayValue = sqrt(displayValue)

                

            }

            

        }

        

    }

    

    

}


이제 performOperation에 있는 계산 부분을 때내어 모델 부분으로 넣어 줄것이다. newfile에서 새로운 스위프트 파일을 만들어준다.

mvc 패턴을 구현해보자


변경된viewcontroller

//

//  ViewController.swift

//  Calulatoer2

//

//  Created by MacBookPro on 2017. 12. 5..

//  Copyright © 2017년 MacBookPro. All rights reserved.

//



//controller 부분


//모듈: 클래스의 집합

import UIKit

//상속받음 , controller는 uiviewcontroller의 상속을 받는다.

class ViewController: UIViewController {


    //라벨 아웃렛 변수

    @IBOutlet private weak var display: UILabel! //!를 붙여주면 값을 암묵적으로 추출해서 누구든 자유롭게 쓸수 있게 하겠다는 뜻, 만약 nil이면 앱이 멈춘다.

    

    //스위프트에서는 모든 변수가 초기값을 가져야 한다!

   private var userIsInTheMiddleOfTyping: Bool = false

    

    //숫자 눌렀을 때

    @IBAction private func touchDigit(_ sender: UIButton) {

        

        // 경고가 뜬다.

        //let을 넣어야 한다. 읽어오고 싶을 때..array나 dictionary를 사용할 때

        //"!" 는 옵셔널 강제적으로 값을 가져올때, 하지만 set 되지 않은 값이 있다면 충돌이 일어난다.

        //안전하게 꺼내오는 방법이 있다.

        

        let digit = sender.currentTitle! //!를 붙여줘서 옵셔널 -> stirng 타입으로 바뀌었다. 값이 nil 이면 충돌

        

        //숫자를 입력중이라면

        if(userIsInTheMiddleOfTyping){

            //text를 옵셔널 타입에 보낼수 없어서 생기는 에러(옵셔널은 텍스트를 이해할 수 없다.-> ullable 타입인 display의 연관값을 가져와야 한다.)

            //display의 값이 nil이라면 에러가 뜬다.

            let textCurrentlyInDisplay = display.text!

            display.text = textCurrentlyInDisplay + digit

        }else{

            //입력중이 아니라면(처음 키패드를 눌렀을 때 0이 나오게)

            display.text = digit

        }

        userIsInTheMiddleOfTyping = true

//뷰의 미니언이 컨트롤에게 위임한다

    }

    

    //계산 프로퍼티(라벨에 있는 값을 굳이 더블로 안바꿔줘도 되고 이 프로퍼티만 밑에서 호출 해주면 된다.)

   private var displayValue: Double {

        get{

            return Double(display.text!)! //안의 값이 문자열이면 변환이 안될 수도 있으므로 !

        }

        set{

            //newValue 키워드

            display.text = String(newValue)

        }

    }

    //=============================변경된 부분 ============================

    //모델 클래스 인스턴스 생성

    private var brain = CalculatorBrain()

    

    //연산자가 눌러졌을때

    @IBAction private func performOperation(_ sender: UIButton) {

    

        //연속으로 숫자가 입력되고 있을때, 처음숫자 입력이 아닐때

        if userIsInTheMiddleOfTyping {

            //라벨에 있는 값을 모델 클래스인 CalulatorBrain으로 넘겨준다.

            brain.setOperation(operand: displayValue)

            //다시 처음으로 숫자가 입력되게 바꿔준다.

            userIsInTheMiddleOfTyping = false

        }

        

        //더 안전한 방법(set이 되었을 때)- 심볼 텍스트가 있으면

        if let mathematicalSymbol = sender.currentTitle{

            //모델 클래스인 CalulatorBrain에게 심볼텍스트를 넘겨 준다.

            brain.performOperation(symbol: mathematicalSymbol)

        }

        //마지막으로 화면에 보여질 값은 모델 클래스 brain이 리턴한 accumulator(최종결과값) 이다

        displayValue = brain.result

    }

    

     //=============================변경된 부분 ============================

}


새로 생성된 모델단 CalculatorBrain.swift

//

//  CalculatorBrain.swift

//  Calulatoer2

//

//  Created by MacBookPro on 2017. 12. 5..

//  Copyright © 2017년 MacBookPro. All rights reserved.

//

// 모델부분은 Foundation으로 임포트 한다.

import Foundation



class CalculatorBrain

{

    //값들이 누적해서 더해진 결과값

    private var accumulator = 0.0

    

    //컨트롤러에서 값을 인자로 넘겨주면 값을 accumulator로 할당한다.

    func setOperation(operand: Double){

        accumulator = operand

    }

    

    //컨트롤러에서 호출한 뒤 매개변수를 넘겨주면 심볼값을 대조한뒤 해당 연산을 accumulator에 대입해준다.

    func performOperation(symbol: String){

        switch symbol {

        case "π":

            accumulator = M_PI

        case "√":

            accumulator = sqrt(accumulator)

        default:

            break

        }

        

    }

    

    //읽기전용 프로퍼티

    var result: Double {

        get {

            return accumulator

        }

        

    }

}



반응형

댓글