인프런 커뮤니티 질문&답변

(알 수 없음)님의 프로필 이미지

작성한 질문수

계산기앱으로 시작해보는 SwiftUI

Button에 대해 이해가 되지 않는 부분이 있어서 질문드립니다

24.08.18 01:07 작성

·

23

·

수정됨

0

import SwiftUI

struct ContentView: View {
    
    @State private var Number: Int = 0 // @State 없으면 에러 발생 왜? 추후에 알아보자
    @State private var op: String = "" // 연산자 저장 변수
    @State private var totalNumber: String = "0" // 실제로 계산기에 출력할 값
    private let buttonData: [[String]] = [ // 키패드 모음 2차원 배열
        ["C", "+/-", "%", "÷"],
        ["7", "8", "9", "X"],
        ["4", "5", "6", "-"],
        ["1", "2", "3", "+"],
        ["0", ".", "="]]
    
    var body: some View {
        ZStack{
            Color.black.ignoresSafeArea() // 화면 전체 여백 없이 배경색 지정
            
            VStack {
                Spacer()
                HStack{
                    Spacer()
                    Text(totalNumber) // 초기값 0 출력
                        .padding()
                        .font(.system(size: 73))
                        .foregroundColor(.white)
                }
                ButtonPosition() // C, +/-, %를 제외한 버튼을 화면에 추가
            }
        }
    }
    
    func ButtonPosition() -> some View{ // 버튼 디자인 및 포지셔닝 함수
        ForEach(buttonData, id: \.self){ line in
            HStack{
                ForEach(line, id: \.self){ row in
                    switch row{
                    case "C", "+/-", "%":
                        ButtonDesign(row, .gray, .black)
                    case "÷", "X", "-", "+", "=":
                        ButtonDesign(row, .orange, .white)
                    default:
                        ButtonDesign(row, .init("NumberButton"), .white)
                    }
                }
            }
        }
    }
    
    
    
    func ButtonDesign(_ value: String, _ backcolor: Color, _ fcolor: Color) -> some View{ // 공통 버튼 디자인
        Button{
            ButtonAction(value) // value는 버튼에 들어갈 글자 및 계산 값
        } label: {
            Text(value)
            // 버튼 크기 및 각 버튼의 숫자 위치 지정
                .frame(width: value == "0" ? 160 : 80, height: 80, alignment: value == "0" ? .leading : .center)
            // "0"일 때만 여백 추가, 대괄호로 값 패스 가능
            //.padding(value == "0" ? .leading : [])
                .background(backcolor) // 버튼 배경색
                .cornerRadius(40) // 버튼 모양 다듬기
                .foregroundColor(fcolor) // 글자색
                .font(.system(size: 33)) // 글자 사이즈
            
        }
    }
    
    func ButtonAction(_ value: String){

        // 내일 이 스위치문에 프로퍼티 옵저버 사용해볼 것
        switch value { // value는 버튼에 들어갈 내용 및 배열에서 받아온 값
        case "C": // C를 누르면
            totalNumber = "0" // 계산기 초기화
        case "÷" ,"X", "-", "+":
            Number = Int(totalNumber)!
            totalNumber = "0"
        case "=":
            totalNumber = String(Int(totalNumber)! + Int(Number))
        default:
            if totalNumber == "0" { // 값이 0인 상태에서 입력이 들어오면 계산기의 첫 입력이니
                totalNumber = value // 누른 버튼의 숫자가 출력됨
                
                if Int(value) == nil{ // 첫 입력이라 숫자를 입력해야 하는데 숫자 외 다른 걸 입력받으면
                    totalNumber = "0" // 별다른 동작 없이 초기값 그대로 0을 유지한다
                }
            }
            else{
                if Int(value) != nil{ // value가 숫자형 문자열이면
                    totalNumber += value // 계산기에 실제로 입력한다
                    Number = Int(totalNumber)!
                }
            }
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
}

제공해주신 강의를 보면서 제가 알고 있는 스위프트 문법 지식과 접목시켜서 코딩 해보고 있는 수강생입니다 제가 이해가 안되는 부분은 ButtonDesign 함수 내에서 ButtonAction 함수를 호출하면서 value를 넘겨주는 부분이 이해가 되지 않아서 글을 올립니다 계산기의 버튼을 누르면 value에 누른 버튼의 값이 들어가게 되는데 이 구조가 이해가 되지 않습니다 label은 ForEach를 통해 value에 값을 넘겨서 뷰를 띄운 게 이해가 되는데 ButtonAction 함수의 매개 변수로 넘기는 value는 ForEach를 사용하는 것도 아니고 도대체 어떻게 누른 버튼의 값을 알고 계산기에 출력을 하는 건지 모르겠습니다!

좋은 강의 만들어주셔서 감사합니다 남은 강의도 열심히 수강하겠습니다 감사합니다!

답변 1

0

인프런 AI 인턴님의 프로필 이미지

2024. 08. 19. 01:11

안녕하세요, 인프런 AI 인턴입니다.

님의 질문에 답변드리겠습니다. SwiftUI에서 ButtonAction 함수 호출 시 value가 어떻게 넘어가는지에 대한 궁금증이시군요.

SwiftUI에서 Button 컴포넌트는 두 부분으로 이루어져 있습니다: 실행할 액션과 라벨을 정의하는 부분입니다. 여기서 ButtonAction 함수는 버튼이 눌렸을 때 실행할 코드 블록(액션)을 정의합니다. 이 코드 블록 내에서 value 매개변수를 사용하여 특정 동작을 수행합니다.

ButtonDesign 함수에서 Button의 액션으로 ButtonAction(value)를 정의하고 있습니다. 여기서 valueButtonDesign 함수의 인자로 받고 있는 값을 그대로 넘겨주고 있습니다. ForEach를 이용하여 buttonData의 각 요소(즉, 버튼의 값)를 순회할 때, ButtonDesign을 호출하면서 현재 순회 중인 버튼 값(value)을 넘겨주고 있기 때문에, 각 버튼은 자신의 값을 액션 함수로 전달할 수 있습니다.

즉, 사용자가 버튼을 클릭하는 순간, value에 설정된 값이 ButtonAction으로 전달되어 해당 버튼에 설정된 값에 따라 계산기 상에서 다르게 동작하게 되는 것입니다. 이렇게 value를 통해 버튼 각각에 고유한 값을 액션 함수로 전달하여, 클릭된 버튼에 따라 다른 동작을 구현할 수 있는 것입니다.

이해가 되셨길 바라며, 계속해서 학습에 열정을 가져주셔서 감사합니다. SwiftUI를 사용해 프로젝트를 진행하면서 더 많은 것을 배우게 되실 것입니다. 추가적인 질문이 있으시면 언제든지 질문해주세요.

(알 수 없음)님의 프로필 이미지

2024. 08. 19. 03:41

버튼을 눌렀을 때 실행할 코드 블록인 액션의 매개 변수는 label에서 사용한 매개 변수의 값이 그대로 넘어간다는 이야기인가요? 버튼을 누르는 시점은 label 영역을 만든 후 이미 ForEach가 종료된 시점일텐데 어떻게 액션 부분이 각 버튼의 값을 매개변수로 가지고 있는지가 궁금합니다..!