묻고 답해요
137만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결간단하게 만들어 보는 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 전체) 강의가 소리만 나오고 영상이 나오지 않습니다. 다른 강의는 잘 나옵니다.확인 부탁드립니다.
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
39강 ProfileViewModel 연결할때 궁금합니다.(초보)
잘 알고 넘어가야 할 것 같아서 질문해요.ProfileView에는@State var viewModel = ProfileViewModel() ProfileEditingView에는@Bindable var viewModel : ProfileViewModel 클래스 연결할땐 @Bindable이라 하셨는데 첫번째에도 연결할때 클래스 연결하는거니 @Bindable 써야하는거 아닌가여? 같은 클래스를 적용하는데 다르게 하는 이유가 궁금하고, @State var viewModel = ProfileViewModel()@Bindable var viewModel : ProfileViewModel하나는 변수에 담는 식이고, 하나는 타입식으로 한건지 궁금해요. 제가 초보라 질문이 엉뚱할 수 있는데 궁금해요~
-
미해결Apple 출신 개발자의 SwiftUI Basic Part 1 기초튼튼
마지막 생성자 코드에서 enum이 안쓰이고 있는거 같아요
enum CarBrand 다 정의되고나서는마지막 생성자 코드가 init(country: String, brand: CarBrand) { self.country = country switch brand { case .Hyundai: self.title = "Hyundai" self.backgroundColor = Color.yellow case .Tesla: self.title = "Tesla" self.backgroundColor = Color.pink }}이렇게 switch 구문 패턴매칭으로 쓰는게 enum 타입을 활용해야 하지 않나요?강의에서 마지막 코드는 생성자에서 country 국가명을 if문으로 조건 분기해서 뷰를 그리고 있습니다 (brand 파라미터가 뷰를 그리는데 안쓰이고 있어요)
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
15강 firebase 셋팅하기 중 오류 질문
따라서 셋팅하던 중 2가지 오류가 나있어서 질문 드립니다.어떻게 수정하면 좋을까요? 디펜던시 설정 중 FirebaseFirestoreSwift 는 없어서 나머지 3개만 설정 완료 했었습니다. 그 차이점 때문일까요?
-
해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)
6-7) 이미지 사이즈 지정 위치 질문드립니다.
안녕하세요 애구마님!6-7) 7:50 쯤에 이미지의 사이즈를 지정해주기 위해 frame() 작성하시는 부분에 질문이 있습니다.bigBanner의 이미지 사이즈 지정 시AsyncImage(url:URL(string:bigBanner)) { image in image .resizable() .cornerRadius(10) .aspectRatio(contentMode: .fit) // 여기서 사이즈 지정 .frame(width: 300, height: 525) }poster의 이미지 사이즈 지정 시 AsyncImage(url: url) { image in image .resizable() } placeholder: { ProgressView() .tint(Color.white) } // 여기서 사이즈 지정 .frame(width: 100, height: 175) 첫 번째 AsyncImage를 작성하셨을 때 이미지 사이즈는 image에서 직접적으로 작성하셨는데 두번째 포스터들의 이미지 사이즈를 작성하실 때는 placeholder 아래쪽에 작성하신 이유가 궁금합니다.답변 부탁드립니다.감사합니다 :)
-
미해결계산기앱으로 시작해보는 SwiftUI
Button에 대해 이해가 되지 않는 부분이 있어서 질문드립니다
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를 사용하는 것도 아니고 도대체 어떻게 누른 버튼의 값을 알고 계산기에 출력을 하는 건지 모르겠습니다! 좋은 강의 만들어주셔서 감사합니다 남은 강의도 열심히 수강하겠습니다 감사합니다!
-
해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)
강의 자료를 모아보는 프로그램을 제작해보려고 합니다!
안녕하세요! 다름이 아니라 강의 자료를 모아보는 앱을 하나 만드려고 하는 상황입니다이 앱을 만들기 위해 애구마님 강의도 열심히 들을 예정입니다ㅎㅎ 예를 들어 1강부터~ 12강까지 강의가 있고 각각 pdf나 ppt 등의 강의 자료가 있다고 가정했을 때스위프트UI의 List 기능을 이용해서 리스트로 만들어 자료를 쉽게 찾아볼 수 있도록 만들고 싶습니다다만 지금 막힌 부분이 일단 List의 각각의 제목을 작성해줘야 하는데 제목을 파일명에서 긁어오고 싶습니다그리고 막힌 부분이 하나 더 있는데 파일을 불러오는 코드를 작성하고 싶은데 잘 모르겠습니다 구글링을 해보니까 PDFKIT이라는 라이브러리가 있는 것 같은데 제가 자료를 못 찾은 건지 UIKIT으로 작성된 예제 코드들 뿐이어서 파일 불러오기부터 막힌 상황입니다...! 혹시 괜찮으시다면 번거로우시겠지만 도와주실 수 있으실까요?? 구현하고자 하는 앱의 구조는 대강 아래와 같습니다일단 앱을 설치하면 아이폰이나 아이패드 내부에 해당 앱에서 볼 강의 자료 파일들을 담을 폴더가 자동으로 생성각각의 강의 자료들을 폴더로 옮김폴더에 파일이 들어올 때마다 순서대로 List에 추가(파일 이름에 1강 or 1. 등 순서를 구분할 수 있는 인덱스를 포함할 예정)실제로 뷰에서 보이는 List의 각각의 이름들은 파일 이름을 그대로 긁어오고 싶음 이 정도입니다..! 아 참고로 아주 기본적인 내용 뿐이지만 Text 뷰나 Button, (V, H, Z)Stack 등 아주 아주 기본적인 내용은 이해하고 있는 상황입니다 ㅎㅎ 아직 강의를 초반까지 밖에 듣지 않았지만 굉장히 쉽게 설명해주시려고 노력하는 부분이 저 같은 초심자에게는 굉장히 크게 와닿는 것 같습니다 남은 강의도 열공 해보겠습니다 좋은 하루 보내세요! 감사합니다!
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
깃허브 문의
안녕하세요. 애구마님 현재 강의는 구매했고 먼저 하던 공부를 끝낸 후 보려고 준비중인데 현재 이 강의를 공부하면서 클론 코딩을 할때 저의 깃허브에 공개용으로 코드나 강의에서 중요한 설명을 코드에 주석처리해서 업로드해도 괜찮을까요? 출처는 Readme로 남기려고 합니다. 깃허브는 이력서 제출시 포트폴리오와 함께 사용하고 있습니다.감사합니다.
-
해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)
NavigationLink 질문
NavigationLink를 통해서 화면 전환을 하게 되면 기본적으로 > Back 버튼이 생성이 됩니다.혹시 이걸 제가 원하는 형태로 커스텀 할 수 있을까요?
-
해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)
서적 추천 부탁드립니다!
안녕하세요! 이제 막 섹션 0을 수강 완료한 수강생입니다 다름이 아니라 강의랑 함께 볼만한 내용의 서적이 있는지 궁금해서 글을 남기게 되었습니다. 제가 개인적으로 강의 내용들을 책에다가 정리하면서 공부하는 타입이라서 혹시 강의해주시는 내용과 비슷한 서적 추천해주실만한 거 있으시면 추천 부탁드리겠습니다. 좋은 강의 만들어주셔서 감사합니다! 남은 강의도 성실하게 수강하겠습니다 ㅎㅎ
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
@Bindable VS @Environment + @Bindable
안녕하세요. 강의 잘 듣고 있습니다.첫번째 질문.다름이 아니라, 처음에 회원가입 기능을 구현할 때, ViewModel을 @Observable을 통해 관찰 가능한 상태로 두고, ViewModel을 다루는 가장 상위 View인 ContentView에서 @State로 선언하는 것까지는 이해가 됩니다.ContentView의 하위 뷰들 중에서,로그인과 관련한 뷰는Login - EnterEmail - EnterPassword - EnterName - EnterUserName - Complete인데,강사님께서 코드로 작성해주신 간접적으로 접근하는 방법 말고, @Environment(SignupViewModel.self) var signupViewModel var body: some View { @Bindable var signupViewModel = signupViewModel 처음 설명해주신 직접적인 접근 방식을 활용했습니다.@Bindable var signupViewModel: SignupViewModel var body: some View{와 같이, ViewModel에 read-write가 가능하기 위해 @Bindable을 사용한다는 사실은 알고 있습니다.하지만 문제는 아래와 같이 입력한 결과에 대해서 출력도 잘 하는데, @Bindable을 적용하였을 때, 마지막 CompleteView에서 아래의 완료 버튼을 눌렀을 때 MainTabView으로 넘어가지 않은 문제가 생겼습니다.기존Auth.auth().currentUser 을 사용했을 때, swiftUI에서 변화를 감지 못하기 때문에, 알려주신대로 ViewModel 내부에서 var currentUserSession: FirebaseAuth.User? 프로퍼티를 만들어 했는데.. 왜 이러한 문제점이 생기는걸까요?if signupViewModel.currentUserSession != nil{ MainTabView() } else { LoginView() .environment(signupViewModel) }물론, 강사님이 알려주신 방법대로 하면 잘 넘어갑니다 ^^.두 번째 질문간접적인 방법 .environment를 사용했을 때, 오류가 떠서 CANVAS를 끄고 작업을 하셨는데 오류를 없앨수 있는 방법이 있을까요?1) 최상단 InstagramCloneApp에 ViewModel을 적용?2) environment로 설정되는 모든 뷰의 #Preview에 .enivronment() 적용?긴 글 읽어주셔서 감사합니다 😃 답변 기다리겠습니다.
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
17강 firebase로 이미지 업로드하기에서 업로드가 안됩니다~
선생님! 캡쳐사진 공유드립니다!!
-
해결됨Part2: 초중급 iOS 인스타그램 클론(SwiftUI, MVVM, Firebase, 2024)
17강 firebase로 이미지 업로드하기에서 업로드가 안됩니다~
Thread 9: Fatal error: Unexpectedly found nil while unwrapping an Optional value위와같은 오류가 뜨면서,,, 업로드가 안됩니다..
-
해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)
질문합니다. 섹션 4 - 10 [투두 삭제기능 구현하기(onDelete)]
완전 초보이다보니 궁금증이 생겨서요.투두 타이틀 반복문 쓸땐 List { } 안에서 todoList 의 타이틀들을 반복할땐 Foreach 쓰시고, .onDelete에선 for _ in을 쓰셨는데 서로 적용할 조건이 다른건가요???
-
해결됨SwiftUI의 Property Wrapper(@State, @Binding...)
@State 관련 질문입니다
//정상 작동 하지 않는 코드 import SwiftUI struct MiniView: View { @State var numb: Int var body: some View { Text("\(numb)") .padding() } } struct ContentView: View { @State var number: Int = 0 var body: some View { VStack { Text("\(number)") } Button(action: { number += 1 }, label: { number%2 == 0 ? Text("짝") : Text("홀") }) MiniView(numb: number) } } #Preview { ContentView() }위의 코드는 작동하지 않습니다. 하지만 여기서MiniView 아래 numb 변수의 @State 를 지워주면정상 작동합니다. (아래코드) 이유가 뭘까요.. ㅜㅠ ?? //정상 작동 하는 코드 import SwiftUI struct MiniView: View { var numb: Int var body: some View { Text("\(numb)") .padding() } } struct ContentView: View { @State var number: Int = 0 var body: some View { VStack { Text("\(number)") } Button(action: { number += 1 }, label: { number%2 == 0 ? Text("짝") : Text("홀") }) MiniView(numb: number) } } #Preview { ContentView() }
-
해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)
섹션4-4 'NavigationStack' 오류가 납니다
'NavigationStack' is only available in iOS 16.0 or newer라고 뜹니다