묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
프로필 수정 후 변경된 내용을 피드에 바로 반영되도록 하고 싶습니다.
안녕하세요. 강의 유익하게 들었습니다!지금 마지막까지 강의를 다 듣고 코드 작성도 완료한 상태인데, 현재는 ProfileEditingView에서 정보 수정 후, 피드에 수정된 유저의 정보가 바로 반영되지 않는 상태입니다.저는 프로필 수정 후 피드에 수정된 유저 정보가 바로 반영 되도록 추가적으로 작업을 하려고 하는데, 가장 최선의 방법이 무엇일지 궁금합니다. 현재로선 FeedCellView에 .onAppear를 걸어서 내부에 유저 정보를 한 번 더 가져오는 식으로 작성하거나, 아니면 새로고침을 했을 때만 가져오는 방법을 생각했는데, 이렇게 하면 모든 게시물에서 유저 정보를 업데이트 해야해서 그만큼 딜레이가 많이 발생하는 문제점이 있어 또 다른 나은 방법이 있을지, 이게 최선인지 알고싶습니다! 감사합니다.
-
미해결Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
15강에서 발생한 문제에 대해서 질문이 있습니다!
SDK 설치시 FirebaseFirestoreSwift 체크가 표시되지 않습니다 ios18 버전부터 없어진걸까요?Firebase Storage 빌드를 하려면 프로젝트 업그레이드가 필요하다고 합니다 결제요금제로 업그레이드 하라고 나오는데 결제를 진행해야 하나요?
-
미해결Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
13강 코드 작성 후 피드의 유저 데이터가 보이지 않는 문제
안녕하세요, 강의 잘 듣고 있습니다! 12강까지는 다른 유저의 게시물이 잘 보이고, 피드 상단 선택 시 프로필까지 잘 넘어갔었는데,13강을 끝까지 듣고 코드 작성 후 빌드를 했더니아래 화면처럼 유저의 데이터가 불러와지지 않고, 프로필로 이동도 안되며 어떤 동작도 하지 않습니다 ㅜㅜ FeedCellView에서 계속 ProfileViewModel(user: user) 을 생성하는 부분에서 문제가 되는 것 같은데,,어떻게 해결해야 할 지 모르겠습니다.아래 오류 이미지도 첨부하겠습니다. 감사합니다
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
혹시 다음 강의 대략 언제쯤 완료되시는지 알 수 있을까요??
안녕하세요, 강의 정말 인상깊게 봤습니다!! 다른 글에서 다음 강의로 Combine 관련 내용으로 제작중이라고 하셨는데, 대략 언제쯤 다음 강의 제작이 끝나시는지 궁금하여 이렇게 글을 남깁니다. 강의 나오면 바로 구매할 예정입니다! 감사합니다.
-
미해결한 조각씩 배우는 SwiftUI - 레벨3
이전 강의와 같이 자막은 제공되지 않나요?
ㅈㄱㄴ
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
섹션7 뷰 리팩토링 질문있습니다.
ViewBuilder를 활용해서 리팩토링하여 중복되는 코드를 줄이는것에 대해서.. 실제로 현업이나 개발할때 강의처럼 일단 뷰를 전체적으로 다 만들어놓고 중복되어보이는 코드를 리팩토링하면서 common으로 분리하나요 ? 아니면 처음부터 중복되는것처럼 보이면 바로 common으로 분리하면서 하나요? 아무래도 후자이려나요 ?
-
미해결Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)
ToDo 앱 @Observable 기능(?) 질문입니다
안녕하세요 강사님 좋은 강의 잘 수강하고 있습니다!강의에서 @Observable 사용시 큰 설명 없이 넘어가셔서 개인적으로 알아보는 중입니다[SwiftUI] Observable macro를 통해 모델 데이터를 만들고 관리하는 방법 (tistory.com)[SwiftUI] iOS17 이후의 상태 관리 (velog.io)[SwiftUI] @Observable 매크로 (1) (tistory.com)Discover Observation in SwiftUI (feat. WWDC 2023) :: iOYES (tistory.com)등 위의 링크들을 살펴보았지만 초보자인 제가 이해하기엔 어려운 내용들이었습니다그래서 강사님 강의 중 SwiftUI의 Property Wrapper(@State, @Binding...)를 구입해봤지만 아쉽게도 @Observable이 아닌 구 버전의 프로퍼티 래퍼인 @ObservableObject를 설명해주시더라구요(이 부분은 아쉬웠지만 나머지 래퍼들을 공부하는 데에는 정말 좋은 강의라고 생각합니다!)일단 강의의 흐름을 보면 @State와 묶어서 설명하시길래 @State는 변수의 변화를 감지하기 위한 래퍼이고 @Observable은 class나 구조체 내 멤버 프로퍼티 값들이 변경되는 걸 감지하기 위한 래퍼라고 이해했는데 맞게 이해한 걸까요..? 답변 주시면 감사하겠습니다!!좋은 하루 보내세요!
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
firebase에서 데이터를 불러오는데 오류가 발생합니다.
grpc.resource_quota=0x600000cab5a0, grpc.server_uri=dns:///firestore.googleapis.com}}: connect failed (UNKNOWN:(domain:NSPOSIXErrorDomain, code:50, description:The operation couldn’t be completed. Network is down)위의 오류가 발생하는데 로그인 정보는 제대로 출력되는데 다른 부분에서 데이터를 불러오지 못하는데 어떤 부분을 수정해보면 좋을까요?
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
Xcode16 업데이트 후 앱이 죽는 이슈
안녕하세요. 에구마님올려주신 강의를 다 듣고,완성된 코드 기준으로이번에 Xcode16으로 업데이트 한 후로 로그인 후에 앱이 죽는 문제가 발생하는데,이에 대한 해결책이 있을까요?
-
해결됨[Lv.2] 레벨업 - SwiftUI intermediate with Core Data, SwiftData
Apple 공식 문서 보는법
안녕하세요 좋은 강의 잘 듣고 있습니다.다름이 아니라 혹시 애플 공식 문서보는 강사님만의 꿀팁 같은게 있을까요?공식문서를 찾아볼 수 있긴 한데 찾고자 하는걸 정확하게 검색해야 결과를 얻을 수 있고 뭔가 보기가 어렵게 되어 있는 것 같아서요...그리고 제가 원하는 기능을 구현하려면 물론 구글링도 있지만 공식문서를 최대한 참고해서 구현 방법을 익히고 싶은데 이런 것들은 공식 문서에서 어떻게 검색해야 하나요?예를 들어 SwiftUI에서 반복문으로 이루어진 텍스트들을 한번에 지우는 기능을 구현하고 싶은데 이에 연관된 것들을 공식 문서에서 쉽게 찾는 방법 등을 알고 싶습니다.감사합니다.
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
프로필 편집 앱을 끄면 사진이 유지가 되지 않아요.
FeedView만들기 전 단계, 리팩토링하기 전단계까지 모두 동일하게 코드를 작성하고, 틀린부분 있는지 빠트린 부분 있는지 확인을 다했는데요. 프로필 편집 사진과 네임, 유저네임, 소개 모두 다 시뮬레이터 홈버튼 더블클릭 후 밀어내기해서 끄고, cmd + R이나 시뮬레잍터 상의 앱을 클릭해서 키면 모든게 리셋되네요. 그런데 로그아웃 후 재로그인하면 또 사진과 네임, 유저네임, 소개가 제대로 뜹니다. 어디 부분이 문제가 있는걸까요??
-
해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)
Todo 앱 @Observable 질문입니다
안녕하세요 @Observable 이 부분에서 에러가 발생해서 질문드립니다현재 맥북 버전은 Sequoia 15.0이며 Xcode 버전은 16.0을 사용 중입니다 Observable()' is only available in iOS 17.0 or newer라는 에러가 발생한 상황입니다 구글링을 해도 해결방법을 찾지 못해서 질문드립니다..! 그리고 추가적으로 Xcode 16으로 업뎃 후 프리뷰 화면 보여주는 단축키인 cmd+option+enter를 아무리 눌러도 프리뷰가 xcode에서 보이지 않는 상황입니다.. 마지막으로 제가 질문드렸던 다른 게시글인데 확인 한 번 부탁드리겠습니다VStack, HStack으로 뷰 구성하기 강의 padding 질... - 인프런 | 커뮤니티 질문&답변 (inflearn.com)답변 주시면 감사하겠습니다!
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
Xcode 관련 질문 할 곳이없어 여기에 질문올려요
2024년 9월 20일경 업데이트 있어서 했더니 이상하게 새 프로젝트부터는 네비게이션창의 파일들이 드래그 엔 드롭이 안됩니다.ㅠㅠ 파일이 폴더를 오고가긴해도 기존버전처럼 파일 순서를 의지대로 변경 못하고, 알파벳 순으로 고정되네요. 찾아서 자동정렬 같은걸 비활성화 하는걸 해보려고해도 찾질 못해서 질문드려요.
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
navigationBarTitle에 대해 (질문X, 공유O)
안녕하세요.먼저, macOS를 Sequoia로 업데이트 하면서 Xcode도 15에서 16으로 업데이트 했습니다.강의 6분 50초 정도부터 navigationTitle 관련된 코드 작성을 해주시는데 이전 OS나 Xcode15에서는 강의 내용대로 작성하면 제대로 되었던게 업데이트를 하고나니 안되더라구요.찾아보니 Xcode 16에서는 내비게이션 타이틀과 툴바의 상호작용이 일부 변경되었다고 합니다.하단에 .navigationBarTitleDisplayMode(.inline)을 추가하니 강의 내용과 동일하게 나타났습니다. 코드는 아래에 첨부하겠습니다..navigationTitle("프로필 편집") .navigationBarTitleDisplayMode(.inline) .navigationBarBackButtonHidden() .toolbar { ToolbarItem(placement: .topBarLeading) { Button { dismiss() } label: { Image(systemName: "arrow.backward") .tint(.black) } } }게시판 내용과 어긋나거나 잘못된 정보면 말씀해 주세요.감사합니다.
-
해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)
VStack, HStack으로 뷰 구성하기 강의 padding 질문입니다
안녕하세요 강의 수강 중 이해가 안되는 부분이 있어서 질문 드립니다 import SwiftUI struct ContentView: View { var body: some View { VStack{ HStack{ Image("dogProfile") .resizable() .frame(width: 120, height: 120) .clipShape(Circle()) .overlay( Circle() .stroke(Color.teal, lineWidth: 3) ) VStack(alignment: .leading){ Text("이름: 키도") Text("시바견") Text("2017년 5월생") } // VStack 안에 있는 뷰에 모디파어어를 일괄 적용하고 싶을 경우 이런 식으로 구성할 수 있다(일괄 적용이라는 표현보단 Vstack 자체에 모디파이어를 적용했다는 표현이 더 옳을지도? .font(.system(size: 20)) // 정보 글의 폰트 사이즈 .padding(.leading, 20) // 그림과 정보 글 사이의 공백 } .padding(.bottom, 20) VStack(alignment: .leading, spacing: 10){ Text("좋아하는 것") .font(.system(size: 20)) .bold() Divider() // 좋아하는 것 밑에 있는 선을 그려주는 함수 Text("- 각종 고기(🐮 = 🐷 = 🐔 > 🐟)") Text("- 장본 게 담겨 있는 종량제 봉투") Text("- 집에 새로 온 사람") } .padding() .background( RoundedRectangle(cornerRadius: 15) .fill(.mint) .opacity(0.2) // 색의 투명도를 지정하는 모디파이어 0이면 완전 투명 .shadow(radius: 5) ) VStack(alignment: .leading, spacing: 10){ Text("스킬") .font(.system(size: 20)) .bold() Divider() // 좋아하는 것 밑에 있는 선을 그려주는 함수 HStack(alignment: .top, spacing: 30){ VStack(alignment: .leading, spacing: 10){ Text("- 앉아") Text("- 엎드려(앉아와 자주 혼동함)") Text("- 하우스(집으로 들어가기)") } VStack(alignment: .leading, spacing: 10){ Text("- 손") Text("- 코") } } } .padding() .background( RoundedRectangle(cornerRadius: 15) .fill(.pink) .opacity(0.2) // 색의 투명도를 지정하는 모디파이어 0이면 완전 투명 .shadow(radius: 5) ) } .padding() // 질문인 부분 } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } }위 코드 맨 마지막 padding을 보면 가장 처음 사용하는 VStack에 .padding을 적용하는 코드입니다 궁금한 건 저 padding의 값을 50, 100 이렇게 설정해도 Vstack의 위 아래 여백은 변하지 않는다는 점입니다. 분명 .padding에 값을 넣어주지 않으면 기본적으로 상하좌우 모든 부분에 여백을 주는 걸로 알고 있는데 만 상하 부분의 여백이 변하지 않는 것을 확인했습니다. 개인적으로 여백을 넓게 잡으면 여백을 잡기 위해 글자나 사진 사이즈 등이 뭉개지는 현상이 발생할 줄 알았는데 좌우는 뭉개지는 데 상하는 뭉개지지 않더라구요 Vstack이 기본적으로 가지고 있는 공간이 있는 최소한의 건지... 혹시 뭉개지지 않는 이유를 알 수 있을까요?? 그리고 혹시 // VStack 안에 있는 뷰에 모디파어어를 일괄 적용하고 싶을 경우 이런 식으로 구성할 수 있다(일괄 적용이라는 표현보단 Vstack 자체에 모디파이어를 적용했다는 표현이 더 옳을지도? 이 주석 제가 맞게 이해한 건지도 알려주시면 정말 감사하겠습니다..! 좋은 하루 보내세요! 감사합니다!
-
미해결간단하게 만들어 보는 iOS 설정앱
@ViewBuilder 사용 질문입니다
안녕하세요! 다름이 아니라 강의를 보면 @ViewBuilder 어노테이션을 사용하시는데 강사님이 쓰신 블로그인지는 모르겠지만https://dev200ok.blogspot.com/2022/05/swiftui.html(블로그 주인 이름이 강사님과 동일)위 링크에 따르면SwiftUI에서 UI를 그리다 보면, 뷰를 따로 떼어내서 작업을 해야하는 경우들이 발생@ViewBuilder 어노테이션을 붙여 뷰를 만들어 주는 메소드를 만들어 줄 수 있습니다. 뷰를 코드와 분리하기 때문에 코드의 가독성을 높여주며 다른 뷰를 독립적으로 보기 좋음@ViewBuilder를 붙여서 만든다면 암시적으로 해당 뷰 안에서만들어 사용하겠다는 뜻위와 같은 이유로 @ViewBuilder를 사용한다고 되어 있습니다 근데 제 코드를 보시면import SwiftUI struct ContentView: View { @State private var airplaneMode: Bool = false func Profile() -> some View{ NavigationLink{ Text("프로필 화면") } label: { HStack{ Image(systemName: "person.fill") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 40, height: 40) .padding(.all, 10) .background(.green) .clipShape(Circle()) VStack(alignment: .leading, spacing: 3){ Text("홍길동") .font(.system(size: 24)) .fontWeight(.regular) Text("Apple ID, iCloud, 미디어 및 구입") .font(.system(size: 14)) } .padding(.leading, 6) } .padding(.vertical, 10) } } func ImageDesign(sysName: String, imgColor: Color) -> some View{ Image(systemName: sysName) .resizable() .aspectRatio(contentMode: .fit) .frame(width: 20, height: 20) .padding(.all, 4) .background(imgColor) .foregroundColor(.white) .cornerRadius(6) } func ListMenuLetter(sysName: String, NaviLinkText: String, imgColor: Color) -> some View{ HStack{ NavigationLink{ switch NaviLinkText{ case "WI-FI": Text("WI-FI 화면") case "Bluetooth": Text("Bluetooth 화면") default: EmptyView() // 빈 뷰를 반환 } } label: { switch NaviLinkText{ case "WI-FI": ImageDesign(sysName: sysName, imgColor: imgColor) HStack{ Text("WI-FI") Spacer() Text("IPTIME") .foregroundColor(.gray) } case "Bluetooth": ImageDesign(sysName: sysName, imgColor: imgColor) HStack{ Text("Bluetooth") Spacer() Text("켬") .foregroundColor(.gray) } default: EmptyView() // 빈 뷰를 반환 } } } } func ListMenu(sysName: String, NaviLinkText: String, imgColor: Color) -> some View{ HStack{ ImageDesign(sysName: sysName, imgColor: imgColor) if NaviLinkText != "에어플레인 모드"{ NavigationLink(NaviLinkText){ // 여기에 지금 label이 따로 지정되어 있지 않은데 이럴 경우 괄호 안에 있는 NaviLinkText가 label 역할을 함 switch NaviLinkText{ case "셀룰러": Text("셀룰러 화면") case "개인용 핫스팟": Text("개인용 핫스팟 화면") case "스크린 타임": Text("스크린 타임 화면") case "일반": Text("일반 화면") case "손쉬운 사용": Text("손쉬운 사용 화면") case "개인 정보 보호": Text("개인 정보 보호 화면") case "암호": Text("암호 화면") default: EmptyView() // 빈 뷰를 반환 } } } else{ Toggle("에어플레인 모드", isOn: $airplaneMode) } } } var body: some View { NavigationView { List{ Section{ Profile() } Section{ ListMenu(sysName: "airplane", NaviLinkText: "에어플레인 모드", imgColor: .orange) ListMenuLetter(sysName: "wifi", NaviLinkText: "WI-FI", imgColor: .blue) ListMenuLetter(sysName: "b.circle", NaviLinkText: "Bluetooth", imgColor: .blue) ListMenu(sysName: "antenna.radiowaves.left.and.right", NaviLinkText: "셀룰러", imgColor: .green) ListMenu(sysName: "personalhotspot", NaviLinkText: "개인용 핫스팟", imgColor: .green) } Section{ ListMenu(sysName: "hourglass", NaviLinkText: "스크린 타임", imgColor: .blue) } Section{ ListMenu(sysName: "gear", NaviLinkText: "일반", imgColor: .gray) ListMenu(sysName: "person.crop.circle", NaviLinkText: "손쉬운 사용", imgColor: .blue) ListMenu(sysName: "hand.raised.fill", NaviLinkText: "개인 정보 보호", imgColor: .blue) } Section{ ListMenu(sysName: "key.fill", NaviLinkText: "암호", imgColor: .gray) } } .navigationTitle(Text("설정")) // 타이틀 위치 코드가 맨 위가 아닌데 정상 동작하는 이유는 무엇인가 } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }Profile 함수나 ImageDesign 등 뷰를 함수로 따로 빼서 독립적인 코드를 구성했는데 @ViewBuilder를 사용하지 않고도 아무런 문제가 없이 정상적으로 동작합니다. 사용하지 않아도 문제가 없는데 강의에서 @ViewBulider를 사용하시는 이유가 궁금합니다 답변 주시면 감사하겠습니다!
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
class와 struct
안녕하세요. 궁금한게 있어 글 남깁니다. Model과 View에는 struct를 사용해주셨고ViewModel에는 class를 사용해주셨는데 이렇게 사용하는 것이 일반적이라고 생각하면 좋을까요? 강의를 보고 궁금하여 좀 찾아보니 참조 타입이나 값 타입에 대해 좀 알게 되었는데 크게 와닿지 않아서 일단은 외우고 진행해야하나 싶더라구요
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
중급, 고급 강의 계획도 있으신가요?
안녕하세요.열심히 강의 수강하고 있는 학생입니다.강의가 너무 알차고 설명도 잘 해주셔서 즐겁게 보며 배우고 있는데 제목과 같이 중급, 고급 강의 계획도 있으신지 궁금합니다.하신다면 무조건 구매(?) 할 생각인데 계획이 없으셨다면 고민 한번 부탁드리며 좋은 강의 다시금 감사드립니다.
-
해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)
@State 특성(?) 질문입니다
import SwiftUI struct ContentView: View { @State private var ToggleCheck: Bool = false // @State 없으면 에러 왜? / 연산자 토글을 누른 후의 숫자 입력인지 체크하기 위한 변수 @State private var isAdditionActive = false // 덧셈 토글 체크 @State private var isSubtractionActive = false // 뺄셈 토글 체크 @State private var isMultiplicationActive = false // 곱셈 토글 체크 @State private var isDivisionActive = false // 나눗셈 토글 체크 @State private var printNumber: String = "0" // 계산식에 사용 or 화면에 출력한 내용을 담은 변수 @State private var totalNumber: Int = 0 // 토탈 계산 값 @State private var op: Character = " " @State private var buttonData: [[String]] = [ // 키패드 모음 2차원 배열 ["AC", "+/-", "%", "÷"], ["7", "8", "9", "X"], ["4", "5", "6", "-"], ["1", "2", "3", "+"], ["0", ".", "="]] var body: some View { ZStack{ Color.black.ignoresSafeArea() // 화면 전체 여백 없이 배경색 지정 VStack { Spacer() HStack{ Spacer() Text("\(Int(printNumber)!)") // 계산기의 숫자 출력 .padding() .font(.system(size: 73)) .foregroundColor(.white) } ButtonPosition() // C, +/-, %를 제외한 버튼을 화면에 추가 } } } func Reset(){ printNumber = "0" // 출력된 계산 숫자 UI 초기화 totalNumber = 0 // 연산의 토탈값을 담고 있는 변수도 당연히 초기화 ToggleCheck = false op = " " buttonData[0][0] = "AC" isAllfalse() // 버튼의 토글값 및 연산자 버튼 토글 UI도 모두 초기화 } func isAllfalse(){ // 연산자의 토글 버튼을 전부 해제 하기 위한 함수 isAdditionActive = false isSubtractionActive = false isMultiplicationActive = false isDivisionActive = false } func opIfSwitch(){ // 실질적인 계산을 위한 switch문 if op == " "{ totalNumber = Int(printNumber)! } else{ switch op{ case "÷": totalNumber /= Int(printNumber)! if printNumber == "0"{ // 비정상 종료.. 왜? printNumber = "오류" } case "X": totalNumber *= Int(printNumber)! case "-": totalNumber -= Int(printNumber)! case "+": totalNumber += Int(printNumber)! default: break } } printNumber = String(totalNumber) } // 내 코드의 계산 방식 작성할 것 이따가 func Division(){ // 나눗셈 opIfSwitch() } func Multiplication(){ // 곱셈 opIfSwitch() } func Minus(){ // 뺄셈 opIfSwitch() } func Plus(){ // 덧셈 opIfSwitch() } func Equal(){ // 등호 opIfSwitch() isAllfalse() ToggleCheck = false // =을 누른 후 결과 값에 추가로 연산을 진행할 때 이 코드 없으면 정상적으로 진행되지 않음 } func ButtonPosition() -> some View{ // 버튼 디자인 및 포지셔닝 함수 ForEach(buttonData, id: \.self){ line in HStack{ ForEach(line, id: \.self){ row in switch row{ case "AC", "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 { switch value { case "÷": isDivisionActive = true // 나눗셈 버튼 토글 isAdditionActive = false isSubtractionActive = false isMultiplicationActive = false case "X": isMultiplicationActive = true // 곱셈 버튼 토글 isDivisionActive = false isAdditionActive = false isSubtractionActive = false case "-": isSubtractionActive = true // 뺄셈 버튼 토글 isAdditionActive = false isMultiplicationActive = false isDivisionActive = false case "+": isAdditionActive = true // 덧셈 버튼 토글 isSubtractionActive = false isMultiplicationActive = false isDivisionActive = false default: break } ButtonAction(value) } label: { Text(value) .frame(width: value == "0" ? 160 : 80, height: 80, alignment: value == "0" ? .leading : .center) .background((value == "÷" && isDivisionActive) || (value == "X" && isMultiplicationActive) || (value == "-" && isSubtractionActive) || (value == "+" && isAdditionActive) ? Color.white : backcolor) //.background(value == "÷" && isDivisionActive ? Color.white : backcolor) //.background(value == "X" && isMultiplicationActive ? Color.white : backcolor) .foregroundColor(value == "÷" && isDivisionActive || (value == "X" && isMultiplicationActive) || (value == "-" && isSubtractionActive) || (value == "+" && isAdditionActive) ? Color.orange : fcolor) .font(.system(size: 33)) .cornerRadius(40) } } func ButtonAction(_ value: String){ switch value { // 버튼을 누르면 case "AC", "C": // C를 누르면 Reset() // 초기화 버튼을 누르면 각종 상수 및 변수들이 초기화 됨 case "÷": // 나누기를 누르면 Division() // 실질적인 계산을 하는 함수 op = "÷" ToggleCheck = false case "X": // 곱하기를 누르면 Multiplication() // 실질적인 계산을 하는 함수 op = "X" ToggleCheck = false case "-": // 빼기를 누르면 Minus() // 실질적인 계산을 하는 함수 op = "-" ToggleCheck = false case "+": // 더하기를 누르면 Plus() // 실질적인 계산을 하는 함수 op = "+" ToggleCheck = false case "+/-": printNumber = String(Int(printNumber)! * -1) case "=": Equal() // 최종 결과를 출력하기 위한 스위치문 호출 op = " " // 내가 원하는 기능을 구현하기 위해 꼭 필요한 코드 printNumber = String(totalNumber) // 연산의 결과 값을 출력 totalNumber = Int(printNumber)! default: if printNumber == "0"{ printNumber = value // 숫자 첫 입력시 화면에 출력 buttonData[0][0] = "C" } else if (isDivisionActive || isMultiplicationActive || isSubtractionActive || isAdditionActive) && ToggleCheck == false{ printNumber = value ToggleCheck = true // 연산자 버튼이 눌러짐 } else{ if printNumber.count < 9{ printNumber += value } } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }안녕하세요! 다름이 아니라 강의에 있는 프로젝트 외에 따로 계산기를 하나 만들어보고 있습니다 근데 @State 어노테이션에 대해 이해가 안되는 부분이 있습니다 구글링도 해보고 여러 방면으로 알아봤는데 원하는 답을 얻지 못해서 질문 올립니다 @State는 뷰의 상태 변화를 체크하는 어노테이션이라고 알고 있습니다. 변수 선언부의 주석을 보시면 @State 없으면 에러 왜? 이런 내용의 주석이 달려 있는 변수가 지금 저의 의문점입니다 ToggleCheck 변수와 totalNumber 변수는 뷰의 상태 변경에 직접적인 영향을 미치지 않기 때문에 @State가 필요 없다고 생각합니다. 근데 저 두 변수에 @State를 지우면 에러가 발생합니다. 일단 뷰의 변화는 실질적으로 totalNumber 변수의 값을 대입 받는 printNumber 변수이니 printNumber 변수에만 @State가 필요하다고 생각하는데 왜 에러가 발생하는 걸까요 마찬가지로 ToggleCheck 변수도 마찬가지로 체크용으로 사용하고 저 값이 변한다고 해서 직접적으로 뷰에 미치는 영향이 없는데 왜 @State가 필요한 걸까요... 혹시 알고 계시면 꼭 답변 부탁드리겠습니다...!감사합니다!
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
섹션4 MVVM 강의 전체가 영상이 안나옵니다.
안녕하세요. 애구마님. 강의 잘 듣고있습니다.다른게 아니라 다른 강의 잘 보다가 섹션4 MVVM 강의에서 11~14(MVVM 전체) 강의가 소리만 나오고 영상이 나오지 않습니다. 다른 강의는 잘 나옵니다.확인 부탁드립니다.