티스토리 뷰

 

 

오늘은 swiftUI에서 제공하는 List를 활용한 TodoList를 만들어보자!

 


 

 

핵심기능

  • + 버튼을 누르면 팝업 창 띄워서 할 일 입력받기
  • 입력받은 할 일을 토글 형태로 리스트에 추가

 

UI

 

 

 

 

 

팝업창 띄우기

 

위에 UI를 보면 + 버튼을 눌렀을 때 할 일을 입력할 수 있는 textfield가 들어있는 팝업창을 띄우도록 해보겠다.

처음엔 버튼을 만들고 Alert를 활용해 구현해보려고 하였으나 Button(action: {}, label:{})을 활용해서 구현하였는데 alert창에서 textfield를 넣으려고 하면 자꾸 오류가 생겼다.

 

그래서 버튼을 눌렀을 때 다른 뷰로 이동하게 만들었고, PopUpView라는 파일을 하나 더 만들어 팝업창에 대한 기능만 구현하도록 했다.

 

struct TodoItem: Identifiable {
    let id: UUID = UUID()
    var title : String
    var isCompleted: Bool = false //토글 완료 상태
    
}

struct PopUpView: View {
    
    @State var todo = ""
    @Binding var showing: Bool
    @State var toggleOn = false
    @Binding var items : [TodoItem]
    
    var body: some View {
        VStack {
            TextField("입력하세요.", text: $todo)
                .padding()
            
            Button(action: {
                AddData()
            }, label: {
                ZStack {
                    RoundedRectangle(cornerRadius: 20)
                    Text("next")
                        .font(.title3)
                        .foregroundColor(.white)
                        .padding()
                }
                
            })
        }
        .fixedSize(horizontal: false, vertical: true)
        .padding()
        .background(.white)
        .clipShape(RoundedRectangle(cornerRadius: 20))
        .shadow(radius: 30)
    }
    
    func AddData() {
        let newItem = TodoItem(title: todo, isCompleted: false)
                items.append(newItem)
                todo = ""
        print(items)
        showing = false
    }
}

 

  • @State var todo = ""   : textfield값을 저장할 문자열 형식의 변수 
  • @State var toggleOn = false : 토글의 on/off를 식별할 bool 타입 변수 선언
  • @Binding var items : [TodoItem] : PopUpView에서의 items 배열을 Binding 프로퍼티로 받아 사용자가 항목을 추가할 때 ContentView의 배열을 업데이트하기 위해 사용
  • @Binding var showing: Bool : 팝업창을 띄우고 숨기기 위해 Bool 타입으로 showing 변수 선언
    • ContentView에서 + 버튼을 누르면 PopUpView의 팝업이 띄워지므로 @Binding 프로퍼티 사용

 

struct TodoItem 구조체 

할 일 항목을 추가 할 때 완료되었으면 토글 상태를 변경시키는 등 TodoItem 인스턴스를 사용해야 한다. 뷰가 렌더링 되고 업데이트할 때

TodoItem 안에 구조체를 식별할 수 있게 하기 위해 Identifiable 프로토콜을 채택하여 구조체를 선언하였다.

 

  • let id : UUID = UUID() : UUID는 범용 고유 식별자로, 실행할 때마다 고유한 값을 생성한다. 배열에 들어간 각 할 일 목록을 고유한 id 식별자로 나타내기 위해 사용하였다.
  • var title: String : 할 일의 내용 문자열 형식으로 저장하기 위한 변수 선언
  • var isCompleted: Bool = false : 토글의 완료 상태를 나타내기 위해 bool 값으로 변수 선언

 

 

 

ContentView

import SwiftUI

struct ContentView: View {
    
    @State private var showing = false
    @State private var todoItems: [TodoItem] = []
    
    var body: some View {
        
        ZStack {
            VStack {

                VStack {
                    
                    Button(action: {
                        showing = true
                        
                    }, label: {
                        Image(systemName: "plus.circle")
                            .aspectRatio(contentMode: .fill)
                            .foregroundColor(Color.red)
                            .font(.title2)
                    })
                    
                }
                .frame(width: 350, height: 30, alignment: .trailing)
                
                
                VStack(alignment: .leading, spacing: 0) {
                    
                    Text("Todo List")
                        .font(.title)
                        .fontWeight(.bold)
                        .multilineTextAlignment(.leading)
                        .padding()
                    
                    
                    List($todoItems) { $item in
                        Toggle(isOn: $item.isCompleted) {
                        
                            Text(item.title)
                        }
                        
                    }
                    
                }
                
            }
            if showing {
                PopUpView(showing: $showing, items: $todoItems)
            }

        }
    }
}

#Preview {
    ContentView()
}

 

ContentView에서 + 버튼을 눌렀을 때 팝업창이 나오도록 상태를 관리할 수 있는 showingPop 변수를 초기값으로 false로 선언해 주었고, 버튼을 누를 때마다 true값이 되게 버튼에 action으로 넣어주었다.

 

Todo 항목을 표시할 수 있는 List값에 Todo항목을 저장할 수 있는 배열을 추가하여 todoItems 배열의 각 요소를 반복하여 리스트 형식으로 목록을 생성하도록 하였고, List 내부에서 todoItems 배열의 요소들에 대한 바인딩을 생성하여 데이터의 변경사항이 배열에 반영되도록 하였다. 

리스트가 추가되는 형태가 토글형태가 되도록 토글 스위치를 생성해 주고 Toggle(isOn: $item.isCompleted) { Text(item.title) }를 통해 TodoItem의 isCompledted속성에 바인딩되도록 하여 토글스위치의 상태변경을 직접 반영하도록 해주었다.

 

 

 

느낀 점

처음에 구현하려고 할 때 꽤 쉬운거 같은데..?라는 생각이 들었지만 + 버튼을 통해 팝업창을 띄우고 거기서 입력한 값을 리스트에 실시간으로 불러오는 것과, 파일 두 개를 연동해서 작업하는 게 생각보다 어려워서 블로그도 많이 찾아보고 유튜브 자료도 많이 찾아본 후에 구현할 수 있었다..

 

Binding, $, @Observed.. 데이터 바인딩에 대한 개념에 대해 잘 모르고 개발을 시작하다 보니 삽질하는 시간이 길어졌던 거 같다.. 

 

그래도 이번 과제를 통해 데이터 바인딩에 대한 개념은 확실히 이해한 거 같다!

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함