본문 바로가기
iOS

SwiftUI - @ObservableObject ,@Published, @ObservedObject

by minsol Kim 2024. 7. 16.

 @ObservableObject

어떠한 객체가 채택하게 되면, 해당 객체는 Publisher 를 가지게 된다.

Publisher는 해당 객체에 어떠한 변화를 감지하게 되면, 해당 object를 바라보고 있는, 뷰에 이벤트를 방출하게 되고,

뷰는 refresh 된다. 

@ Published

속성레퍼 구조체이다. 

propertyWrapper 이다.

 

@ObservedObject 

https://developer.apple.com/documentation/swiftui/observedobject

 

ObservedObject | Apple Developer Documentation

A property wrapper type that subscribes to an observable object and invalidates a view whenever the observable object changes.

developer.apple.com

 

ObservableObject를 준수하는 모델을 만들고,  그 모델에서 값이 변경되면 뷰에 반영하기로 위한 것이다.

 

예시 사용법 

import Foundation

class ActivityCardViewModel: ObservableObject, Identifiable {
    let id = UUID()
    @Published var title: String
    @Published var date: String
    @Published var location: String
    @Published var daysLeft: Int
    @Published var imageName: String
    @Published var isPast: Bool
    
    init(title: String, date: String, location: String, daysLeft: Int, imageName: String, isPast: Bool = false) {
        self.title = title
        self.date = date
        self.location = location
        self.daysLeft = daysLeft
        self.imageName = imageName
        self.isPast = isPast
    }
}

 

import SwiftUI

struct ActivityCardView: View {
    @ObservedObject var viewModel: ActivityCardViewModel
    
    var body: some View {
        HStack {
            Image(viewModel.imageName)
                .resizable()
                .scaledToFit()
                .frame(width: 60, height: 60)
            
            VStack(alignment: .leading) {
                Text(viewModel.title)
                    .font(.headline)
                Text(viewModel.date)
                    .font(.subheadline)
                Text(viewModel.location)
                    .font(.subheadline)
            }
            
            Spacer()
            
            Text("D-\(viewModel.daysLeft)")
                .font(.headline)
                .foregroundColor(viewModel.isPast ? .gray2 : .black)
        }
        .padding()
        .background(viewModel.isPast ? Color.gray.opacity(0.2) : Color.white)
        .cornerRadius(8)
        .shadow(radius: 1)
    }
}
class MyInvitationsViewModel: ObservableObject {
    @Published var activities: [ActivityCardViewModel]
    
    init() {
        self.activities = [
            ActivityCardViewModel(title: "스시 먹부림", date: "7월 30일 화요일", location: "안서초등학교", daysLeft: 10, imageName: "image1"),
            ActivityCardViewModel(title: "냉면 만들기 파", date: "6월 1일 수요일", location: "안서 동보아파트", daysLeft: 0, imageName: "naengmyeon", isPast: true)
        ]
    }
}
import SwiftUI

struct MyInvitationsView: View {
    @ObservedObject var viewModel = MyInvitationsViewModel()

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            ForEach(viewModel.activities) { activity in
                ActivityCardView(viewModel: activity)
            }
        }
        .padding()
    }
}
struct MyInvitationsView_Previews: PreviewProvider {
    static var previews: some View {
        MyInvitationsView()
    }
}

 

댓글