From ca97dfc08abee9932ea3202ada34d009c7687b2a Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 04:20:00 +0900 Subject: [PATCH 01/30] Design:iphone:: #32 Add SearchList MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 검색할 때 아래에 리스트가 보여주도록 레이아웃 수정 --- Nav/View/MapView.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index e4327d8..dd5667a 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -112,6 +112,8 @@ struct MapView: View { } } } + List { + Text(searchQueryString) } } } From e615a4ee89a889f94b424e449bfc28dbc75e6436 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 04:21:13 +0900 Subject: [PATCH 02/30] Feat:sparkles:: #32 Add searching list visible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 검색 중에만 리스트를 보여주는 기능 추가 --- Nav/View/MapView.swift | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index dd5667a..550fe7e 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -10,6 +10,7 @@ struct MapView: View { private var mockDatas: [MockDatum] = MockDatum.allData @State var searchQueryString = "" + @State var isEdit = false // 서울 좌표 @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.5666791, longitude: 126.9782914), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) @@ -112,6 +113,7 @@ struct MapView: View { } } } + if isEdit { List { Text(searchQueryString) } @@ -123,6 +125,13 @@ struct MapView: View { placement: .navigationBarDrawer, prompt: "검색" ) + .onChange(of: searchQueryString) { newValue in + if newValue != "" { + isEdit = true + } else { + isEdit = false + } + } } } @@ -131,4 +140,4 @@ struct MapView_Previews: PreviewProvider { static var previews: some View { MapView() } -} \ No newline at end of file +}} From 0285b31d42d42aa786b364a6194300cf84f70954 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 04:27:18 +0900 Subject: [PATCH 03/30] Style:art:: Modify isEdit variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - List를 표시하기 위해 현재 검색어를 작성 중인지 판단하는 isEdit 변수의 이름을 isEditing으로 변경 --- Nav/View/MapView.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index 20d7fb9..fef6bde 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -10,7 +10,7 @@ struct MapView: View { private var mockDatas: [MockDatum] = MockDatum.allData @State var searchQueryString = "" - @State var isEdit = false + @State var isEditing = false // 서울 좌표 @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.5666791, longitude: 126.9782914), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) @@ -27,7 +27,7 @@ struct MapView: View { data in MapMarker(coordinate: data.coordinate) } - if isEdit { + if isEditing { List { Text(searchQueryString) } @@ -40,7 +40,7 @@ struct MapView: View { prompt: "검색" ) .onChange(of: searchQueryString) { newValue in - isEdit = (newValue != "" ? true : false) + isEditing = (newValue != "" ? true : false) } } } From af66783cef3ea374cd052ad2113c6ac2a4552bf1 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 16:34:00 +0900 Subject: [PATCH 04/30] Feat:sparkles:: Add AddressSearcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 주소 검색 기능을 담당하기 위한 AddressSearcher 클래스 추가 --- Nav.xcodeproj/project.pbxproj | 4 ++++ Nav/AddressSearcher.swift | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 Nav/AddressSearcher.swift diff --git a/Nav.xcodeproj/project.pbxproj b/Nav.xcodeproj/project.pbxproj index dcecd29..755c198 100644 --- a/Nav.xcodeproj/project.pbxproj +++ b/Nav.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 26A1500D29083A1300BC7355 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A1500C29083A1300BC7355 /* ContentView.swift */; }; 26A1500F29083A1400BC7355 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 26A1500E29083A1400BC7355 /* Assets.xcassets */; }; 26A1501929083B7B00BC7355 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A1501829083B7B00BC7355 /* MapView.swift */; }; + 26A82ED82A29CCDE00C23407 /* AddressSearcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A82ED72A29CCDE00C23407 /* AddressSearcher.swift */; }; CE2D8D3829C59D5F00E5C104 /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE2D8D3729C59D5F00E5C104 /* ImagePicker.swift */; }; CE2D8D3A29C59DF100E5C104 /* CategoryPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE2D8D3929C59DF100E5C104 /* CategoryPicker.swift */; }; DCE7EBCF2A172C1E00644745 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCE7EBCE2A172C1E00644745 /* Extensions.swift */; }; @@ -37,6 +38,7 @@ 26A1500C29083A1300BC7355 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 26A1500E29083A1400BC7355 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 26A1501829083B7B00BC7355 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + 26A82ED72A29CCDE00C23407 /* AddressSearcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressSearcher.swift; sourceTree = ""; }; CE2D8D3729C59D5F00E5C104 /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = ""; }; CE2D8D3929C59DF100E5C104 /* CategoryPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryPicker.swift; sourceTree = ""; }; DCE7EBCE2A172C1E00644745 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; @@ -92,6 +94,7 @@ 26A1501029083A1400BC7355 /* Preview Content */, CE2D8D3729C59D5F00E5C104 /* ImagePicker.swift */, CE2D8D3929C59DF100E5C104 /* CategoryPicker.swift */, + 26A82ED72A29CCDE00C23407 /* AddressSearcher.swift */, ); path = Nav; sourceTree = ""; @@ -227,6 +230,7 @@ CE2D8D3829C59D5F00E5C104 /* ImagePicker.swift in Sources */, 26A1500D29083A1300BC7355 /* ContentView.swift in Sources */, 262C17C2290D090C00450E54 /* Font+.swift in Sources */, + 26A82ED82A29CCDE00C23407 /* AddressSearcher.swift in Sources */, 262C17C6290E385E00450E54 /* Text+.swift in Sources */, 262C17C0290D06F700450E54 /* Color+.swift in Sources */, FDFD7A6129289926001BE945 /* Bundle+Ext.swift in Sources */, diff --git a/Nav/AddressSearcher.swift b/Nav/AddressSearcher.swift new file mode 100644 index 0000000..50ae1e6 --- /dev/null +++ b/Nav/AddressSearcher.swift @@ -0,0 +1,31 @@ +// +// AddressSearcher.swift +// Nav +// +// Created by 김민택 on 2023/06/02. +// + +import Combine +import Foundation +import MapKit +import SwiftUI + +class AddressSearcher: NSObject, ObservableObject, MKLocalSearchCompleterDelegate { + @Published var searchQuery = "" + var completer: MKLocalSearchCompleter + @Published var completions: [MKLocalSearchCompletion] = [] + var cancellable: AnyCancellable? + + override init() { + completer = MKLocalSearchCompleter() + super.init() + cancellable = $searchQuery.assign(to: \.queryFragment, on: self.completer) + completer.delegate = self + } + + func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) { + self.completions = completer.results + } +} + +extension MKLocalSearchCompletion: Identifiable {} From 0cfb8ffc407fd4f1020d72ad039c9ba603e948f4 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 04:21:49 +0900 Subject: [PATCH 05/30] Chore:wrench:: Delete wrong bracket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 잘못된 괄호 삭제 --- Nav/View/MapView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index 550fe7e..138922b 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -140,4 +140,4 @@ struct MapView_Previews: PreviewProvider { static var previews: some View { MapView() } -}} +} From 107bdda1543c69dd49287a42fd9a3194a3813f3f Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 16:35:05 +0900 Subject: [PATCH 06/30] Chore:wrench:: Modify searching variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 검색용 변수를 searchQueryString에서 AddressSearcher의 queryString으로 변경 --- Nav/View/MapView.swift | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index fef6bde..89e84f4 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -7,9 +7,7 @@ import MapKit import SwiftUI struct MapView: View { - private var mockDatas: [MockDatum] = MockDatum.allData - - @State var searchQueryString = "" + @ObservedObject var addressSearcher = AddressSearcher() @State var isEditing = false // 서울 좌표 @@ -18,6 +16,8 @@ struct MapView: View { @State private var isClickedYes: Bool = false @State private var isShowModal: Bool = false + private var mockDatas: [MockDatum] = MockDatum.allData + var body: some View { NavigationView { ZStack { @@ -28,23 +28,36 @@ struct MapView: View { } if isEditing { - List { - Text(searchQueryString) + List(addressSearcher.completions) { completion in + Button { + // 핀 포커싱 기능 추가 + addressSearcher.searchQuery = "" + } label: { + VStack(alignment: .leading) { + Text(completion.title) + if completion.subtitle != "" { + Text(completion.subtitle) + .font(.subheadline) + .foregroundColor(.gray) + } + } + } } } } .navigationTitle("NAV") .searchable( - text: $searchQueryString, + text: $addressSearcher.searchQuery, placement: .navigationBarDrawer, prompt: "검색" ) - .onChange(of: searchQueryString) { newValue in + .onChange(of: addressSearcher.searchQuery) { newValue in isEditing = (newValue != "" ? true : false) } } } } + struct MapView_Previews: PreviewProvider { static var previews: some View { MapView() From 864ad4c680374b67908f9b94e63a50b6f167e7b5 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 04:22:14 +0900 Subject: [PATCH 07/30] Chore:wrench:: Delete legacy code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 불필요한 레거시 코드 삭제 --- Nav/View/MapView.swift | 86 ------------------------------------------ 1 file changed, 86 deletions(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index 138922b..f6d3ff6 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -27,92 +27,6 @@ struct MapView: View { data in MapMarker(coordinate: data.coordinate) } - HStack { - Spacer() - - VStack { - Button(action: {}) { - Image(systemName: "gearshape") - .circleButton( - iconColor: .navWhite, - iconWidth: 20, - iconHeight: 20, - buttonColor: .primaryRed, - buttonSize: 50, - shadowRadius: 4, - shadowY: 4 - ) - .shadow(radius: 4, y: 4) - } - - NavigationLink { - ListView() - } label: { - Image(systemName: "list.bullet") - .circleButton( - iconColor: .navWhite, - iconWidth: 20, - iconHeight: 14.5, - buttonColor: .primaryRed, - buttonSize: 50, - shadowRadius: 4, - shadowY: 4 - ) - .shadow(radius: 4, y: 4) - } - - Spacer() - - Button { - if isLoggedIn { - isShowModal = true - } else { - isClickedYes = true - } - } label: { - Image(systemName: "plus") - .circleButton( - iconColor: .navWhite, - iconWidth: 17, - iconHeight: 16, - buttonColor: .primaryRed, - buttonSize: 50, - shadowRadius: 4, - shadowY: 4 - ) - .shadow(radius: 4, y: 4) - } - } - .padding(.trailing, 16) - .alert("로그인이 필요한 서비스입니다.", - isPresented: $isClickedYes, - actions: { - Button("취소", role: .cancel, action: {}) - Button("로그인", role: .none, action: {}) - }, - message: { - Text("로그인을 하시면 모든 서비스를 이용하실 수 있습니다. 로그인 하시겠습니까?") - } - ) - .sheet(isPresented: $isShowModal) { - NavigationView { - VStack { - PinCreationView() - } - .padding(16) - .navigationTitle("핀 추가") - .navigationBarTitleDisplayMode(.inline) - .toolbar { - ToolbarItem(placement: .navigationBarLeading) { - Button { - isShowModal = false - } label: { - Image(systemName: "xmark") - .foregroundColor(.black) - } - } - } - } if isEdit { List { Text(searchQueryString) From c368e9e68c5e39833be579219de855c10713fe21 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 16:35:24 +0900 Subject: [PATCH 08/30] Chore:wrench:: Delete Unused variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 더 이상 사용되지 않는 변수 삭제 --- Nav/View/MapView.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index 89e84f4..47212b1 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -12,9 +12,6 @@ struct MapView: View { // 서울 좌표 @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.5666791, longitude: 126.9782914), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) - @State private var isLoggedIn: Bool = true - @State private var isClickedYes: Bool = false - @State private var isShowModal: Bool = false private var mockDatas: [MockDatum] = MockDatum.allData From b251d449153885b35ae2560a6acddfbc3ede4dab Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 04:24:53 +0900 Subject: [PATCH 09/30] Style:art:: Modify control flow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 분기문 형태를 if문에서 삼항연산자로 수정 --- Nav/View/MapView.swift | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index f6d3ff6..852bcd6 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -40,11 +40,7 @@ struct MapView: View { prompt: "검색" ) .onChange(of: searchQueryString) { newValue in - if newValue != "" { - isEdit = true - } else { - isEdit = false - } + isEdit = (newValue != "" ? true : false) } } } From ac6dc158e2ee21eb26b68755129a0474223bccd8 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 16:47:21 +0900 Subject: [PATCH 10/30] Feat:sparkles:: Add returning address coordinate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 주소의 좌표 값을 반환하는 함수 추가 --- Nav/AddressSearcher.swift | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Nav/AddressSearcher.swift b/Nav/AddressSearcher.swift index 50ae1e6..84f2bce 100644 --- a/Nav/AddressSearcher.swift +++ b/Nav/AddressSearcher.swift @@ -26,6 +26,17 @@ class AddressSearcher: NSObject, ObservableObject, MKLocalSearchCompleterDelegat func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) { self.completions = completer.results } + + func loadAddressCoordinate(_ address: MKLocalSearchCompletion, completoinHandler: @escaping (Double, Double) -> Void) { + let searchRequest = MKLocalSearch.Request(completion: address) + let search = MKLocalSearch(request: searchRequest) + search.start { response, error in + guard error == nil else { return } + guard let placeMark = response?.mapItems[0].placemark else { return } + + completoinHandler(placeMark.coordinate.latitude, placeMark.coordinate.longitude) + } + } } extension MKLocalSearchCompletion: Identifiable {} From 48001203b81b285bc32bb0b5947930f347ee0e67 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 04:26:28 +0900 Subject: [PATCH 11/30] Style:art:: Delete space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 불필요한 공백 제거 --- Nav/View/MapView.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index 852bcd6..20d7fb9 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -44,7 +44,6 @@ struct MapView: View { } } } - } struct MapView_Previews: PreviewProvider { static var previews: some View { From ffd4e90cd4beb6cb9155d0234de8b0e98a369c4a Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 16:47:55 +0900 Subject: [PATCH 12/30] Feat:sparkles:: Add printing address coordinate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 주소의 좌표값을 출력하는 기능 추가 - 핀을 만들어 포커싱 하는 기능 추가 필요 --- Nav/View/MapView.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index 47212b1..00aeef8 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -28,6 +28,9 @@ struct MapView: View { List(addressSearcher.completions) { completion in Button { // 핀 포커싱 기능 추가 + addressSearcher.loadAddressCoordinate(completion) { latitude, longitude in + print(latitude, longitude) + } addressSearcher.searchQuery = "" } label: { VStack(alignment: .leading) { From 0080a85965b63db038dc50eaf875d6bf9301d940 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 04:27:18 +0900 Subject: [PATCH 13/30] Style:art:: #32 Modify isEdit variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - List를 표시하기 위해 현재 검색어를 작성 중인지 판단하는 isEdit 변수의 이름을 isEditing으로 변경 --- Nav/View/MapView.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index 20d7fb9..fef6bde 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -10,7 +10,7 @@ struct MapView: View { private var mockDatas: [MockDatum] = MockDatum.allData @State var searchQueryString = "" - @State var isEdit = false + @State var isEditing = false // 서울 좌표 @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.5666791, longitude: 126.9782914), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) @@ -27,7 +27,7 @@ struct MapView: View { data in MapMarker(coordinate: data.coordinate) } - if isEdit { + if isEditing { List { Text(searchQueryString) } @@ -40,7 +40,7 @@ struct MapView: View { prompt: "검색" ) .onChange(of: searchQueryString) { newValue in - isEdit = (newValue != "" ? true : false) + isEditing = (newValue != "" ? true : false) } } } From ef9b833bb42c9876e53dfcfa4fbd72c30f7ad4be Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 16:34:00 +0900 Subject: [PATCH 14/30] Feat:sparkles:: #32 Add AddressSearcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 주소 검색 기능을 담당하기 위한 AddressSearcher 클래스 추가 --- Nav.xcodeproj/project.pbxproj | 4 ++++ Nav/AddressSearcher.swift | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 Nav/AddressSearcher.swift diff --git a/Nav.xcodeproj/project.pbxproj b/Nav.xcodeproj/project.pbxproj index dcecd29..755c198 100644 --- a/Nav.xcodeproj/project.pbxproj +++ b/Nav.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 26A1500D29083A1300BC7355 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A1500C29083A1300BC7355 /* ContentView.swift */; }; 26A1500F29083A1400BC7355 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 26A1500E29083A1400BC7355 /* Assets.xcassets */; }; 26A1501929083B7B00BC7355 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A1501829083B7B00BC7355 /* MapView.swift */; }; + 26A82ED82A29CCDE00C23407 /* AddressSearcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A82ED72A29CCDE00C23407 /* AddressSearcher.swift */; }; CE2D8D3829C59D5F00E5C104 /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE2D8D3729C59D5F00E5C104 /* ImagePicker.swift */; }; CE2D8D3A29C59DF100E5C104 /* CategoryPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE2D8D3929C59DF100E5C104 /* CategoryPicker.swift */; }; DCE7EBCF2A172C1E00644745 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCE7EBCE2A172C1E00644745 /* Extensions.swift */; }; @@ -37,6 +38,7 @@ 26A1500C29083A1300BC7355 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 26A1500E29083A1400BC7355 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 26A1501829083B7B00BC7355 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; + 26A82ED72A29CCDE00C23407 /* AddressSearcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressSearcher.swift; sourceTree = ""; }; CE2D8D3729C59D5F00E5C104 /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = ""; }; CE2D8D3929C59DF100E5C104 /* CategoryPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryPicker.swift; sourceTree = ""; }; DCE7EBCE2A172C1E00644745 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; @@ -92,6 +94,7 @@ 26A1501029083A1400BC7355 /* Preview Content */, CE2D8D3729C59D5F00E5C104 /* ImagePicker.swift */, CE2D8D3929C59DF100E5C104 /* CategoryPicker.swift */, + 26A82ED72A29CCDE00C23407 /* AddressSearcher.swift */, ); path = Nav; sourceTree = ""; @@ -227,6 +230,7 @@ CE2D8D3829C59D5F00E5C104 /* ImagePicker.swift in Sources */, 26A1500D29083A1300BC7355 /* ContentView.swift in Sources */, 262C17C2290D090C00450E54 /* Font+.swift in Sources */, + 26A82ED82A29CCDE00C23407 /* AddressSearcher.swift in Sources */, 262C17C6290E385E00450E54 /* Text+.swift in Sources */, 262C17C0290D06F700450E54 /* Color+.swift in Sources */, FDFD7A6129289926001BE945 /* Bundle+Ext.swift in Sources */, diff --git a/Nav/AddressSearcher.swift b/Nav/AddressSearcher.swift new file mode 100644 index 0000000..50ae1e6 --- /dev/null +++ b/Nav/AddressSearcher.swift @@ -0,0 +1,31 @@ +// +// AddressSearcher.swift +// Nav +// +// Created by 김민택 on 2023/06/02. +// + +import Combine +import Foundation +import MapKit +import SwiftUI + +class AddressSearcher: NSObject, ObservableObject, MKLocalSearchCompleterDelegate { + @Published var searchQuery = "" + var completer: MKLocalSearchCompleter + @Published var completions: [MKLocalSearchCompletion] = [] + var cancellable: AnyCancellable? + + override init() { + completer = MKLocalSearchCompleter() + super.init() + cancellable = $searchQuery.assign(to: \.queryFragment, on: self.completer) + completer.delegate = self + } + + func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) { + self.completions = completer.results + } +} + +extension MKLocalSearchCompletion: Identifiable {} From c3b868a87b54506fee3c9fe6d47f9b82eb09ff97 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 16:35:05 +0900 Subject: [PATCH 15/30] Chore:wrench:: #32 Modify searching variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 검색용 변수를 searchQueryString에서 AddressSearcher의 queryString으로 변경 --- Nav/View/MapView.swift | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index fef6bde..89e84f4 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -7,9 +7,7 @@ import MapKit import SwiftUI struct MapView: View { - private var mockDatas: [MockDatum] = MockDatum.allData - - @State var searchQueryString = "" + @ObservedObject var addressSearcher = AddressSearcher() @State var isEditing = false // 서울 좌표 @@ -18,6 +16,8 @@ struct MapView: View { @State private var isClickedYes: Bool = false @State private var isShowModal: Bool = false + private var mockDatas: [MockDatum] = MockDatum.allData + var body: some View { NavigationView { ZStack { @@ -28,23 +28,36 @@ struct MapView: View { } if isEditing { - List { - Text(searchQueryString) + List(addressSearcher.completions) { completion in + Button { + // 핀 포커싱 기능 추가 + addressSearcher.searchQuery = "" + } label: { + VStack(alignment: .leading) { + Text(completion.title) + if completion.subtitle != "" { + Text(completion.subtitle) + .font(.subheadline) + .foregroundColor(.gray) + } + } + } } } } .navigationTitle("NAV") .searchable( - text: $searchQueryString, + text: $addressSearcher.searchQuery, placement: .navigationBarDrawer, prompt: "검색" ) - .onChange(of: searchQueryString) { newValue in + .onChange(of: addressSearcher.searchQuery) { newValue in isEditing = (newValue != "" ? true : false) } } } } + struct MapView_Previews: PreviewProvider { static var previews: some View { MapView() From aa730d5469c7d3df0d9ae63e8bc5c7786ca1df46 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 16:35:24 +0900 Subject: [PATCH 16/30] Chore:wrench:: #32 Delete Unused variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 더 이상 사용되지 않는 변수 삭제 --- Nav/View/MapView.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index 89e84f4..47212b1 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -12,9 +12,6 @@ struct MapView: View { // 서울 좌표 @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.5666791, longitude: 126.9782914), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) - @State private var isLoggedIn: Bool = true - @State private var isClickedYes: Bool = false - @State private var isShowModal: Bool = false private var mockDatas: [MockDatum] = MockDatum.allData From 29988603580415d69f5433e88aefae40768233c7 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 16:47:21 +0900 Subject: [PATCH 17/30] Feat:sparkles:: #32 Add returning address coordinate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 주소의 좌표 값을 반환하는 함수 추가 --- Nav/AddressSearcher.swift | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Nav/AddressSearcher.swift b/Nav/AddressSearcher.swift index 50ae1e6..84f2bce 100644 --- a/Nav/AddressSearcher.swift +++ b/Nav/AddressSearcher.swift @@ -26,6 +26,17 @@ class AddressSearcher: NSObject, ObservableObject, MKLocalSearchCompleterDelegat func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) { self.completions = completer.results } + + func loadAddressCoordinate(_ address: MKLocalSearchCompletion, completoinHandler: @escaping (Double, Double) -> Void) { + let searchRequest = MKLocalSearch.Request(completion: address) + let search = MKLocalSearch(request: searchRequest) + search.start { response, error in + guard error == nil else { return } + guard let placeMark = response?.mapItems[0].placemark else { return } + + completoinHandler(placeMark.coordinate.latitude, placeMark.coordinate.longitude) + } + } } extension MKLocalSearchCompletion: Identifiable {} From 445d06641af0bf43f88438cf23699fe80ba0af64 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 16:47:55 +0900 Subject: [PATCH 18/30] Feat:sparkles:: #32 Add printing address coordinate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 주소의 좌표값을 출력하는 기능 추가 - 핀을 만들어 포커싱 하는 기능 추가 필요 --- Nav/View/MapView.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index 47212b1..00aeef8 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -28,6 +28,9 @@ struct MapView: View { List(addressSearcher.completions) { completion in Button { // 핀 포커싱 기능 추가 + addressSearcher.loadAddressCoordinate(completion) { latitude, longitude in + print(latitude, longitude) + } addressSearcher.searchQuery = "" } label: { VStack(alignment: .leading) { From 44c6b045dfd7a3cc31f0f3aed6df5b798e6a6ee6 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 17:20:19 +0900 Subject: [PATCH 19/30] Feature:sparkles:: #32 Add showing coordinate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 검색한 주소의 좌표에 맵을 보여주는 기능 추가 --- Nav/AddressSearcher.swift | 4 ++-- Nav/View/MapView.swift | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Nav/AddressSearcher.swift b/Nav/AddressSearcher.swift index 84f2bce..c0bec01 100644 --- a/Nav/AddressSearcher.swift +++ b/Nav/AddressSearcher.swift @@ -27,14 +27,14 @@ class AddressSearcher: NSObject, ObservableObject, MKLocalSearchCompleterDelegat self.completions = completer.results } - func loadAddressCoordinate(_ address: MKLocalSearchCompletion, completoinHandler: @escaping (Double, Double) -> Void) { + func loadAddressCoordinate(_ address: MKLocalSearchCompletion, completoinHandler: @escaping (CLLocationCoordinate2D) -> Void) { let searchRequest = MKLocalSearch.Request(completion: address) let search = MKLocalSearch(request: searchRequest) search.start { response, error in guard error == nil else { return } guard let placeMark = response?.mapItems[0].placemark else { return } - completoinHandler(placeMark.coordinate.latitude, placeMark.coordinate.longitude) + completoinHandler(placeMark.coordinate) } } } diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index 00aeef8..d553fdf 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -28,8 +28,8 @@ struct MapView: View { List(addressSearcher.completions) { completion in Button { // 핀 포커싱 기능 추가 - addressSearcher.loadAddressCoordinate(completion) { latitude, longitude in - print(latitude, longitude) + addressSearcher.loadAddressCoordinate(completion) { coordinate in + region = MKCoordinateRegion(center: coordinate, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)) } addressSearcher.searchQuery = "" } label: { From 02c1f3a3beb6b1acf4e635e4413be66da16641c2 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 17:25:23 +0900 Subject: [PATCH 20/30] Style:art:: Delete Unused comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 사용되지 않는 주석 삭제 --- Nav/View/MapView.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index d553fdf..f5cbc40 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -27,7 +27,6 @@ struct MapView: View { if isEditing { List(addressSearcher.completions) { completion in Button { - // 핀 포커싱 기능 추가 addressSearcher.loadAddressCoordinate(completion) { coordinate in region = MKCoordinateRegion(center: coordinate, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)) } From 28c70de731a9d31900384d70b511b904d8380531 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Fri, 2 Jun 2023 17:29:50 +0900 Subject: [PATCH 21/30] Chore:wrench:: #32 Modify searching variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - isEditing이라는 별도의 변수 대신 searchQuery로 검색 중 여부 판단 --- Nav/View/MapView.swift | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index f5cbc40..cdf8a37 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -8,7 +8,6 @@ import MapKit import SwiftUI struct MapView: View { @ObservedObject var addressSearcher = AddressSearcher() - @State var isEditing = false // 서울 좌표 @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.5666791, longitude: 126.9782914), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) @@ -24,7 +23,7 @@ struct MapView: View { data in MapMarker(coordinate: data.coordinate) } - if isEditing { + if addressSearcher.searchQuery != "" { List(addressSearcher.completions) { completion in Button { addressSearcher.loadAddressCoordinate(completion) { coordinate in @@ -50,9 +49,6 @@ struct MapView: View { placement: .navigationBarDrawer, prompt: "검색" ) - .onChange(of: addressSearcher.searchQuery) { newValue in - isEditing = (newValue != "" ? true : false) - } } } } From 498fc8259204bb7e2c419df0c0f37284e742c870 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Tue, 13 Jun 2023 21:43:04 +0900 Subject: [PATCH 22/30] Chore:wrench:: #32 Modify Map Managing class name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 지도 및 주소와 관련된 정보를 처리하는 addressSearcher 클래스의 이름을 클래스 기능 확장에 따라 LocationManager로 변경 --- Nav.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Nav.xcodeproj/project.pbxproj b/Nav.xcodeproj/project.pbxproj index 755c198..d4de00c 100644 --- a/Nav.xcodeproj/project.pbxproj +++ b/Nav.xcodeproj/project.pbxproj @@ -16,7 +16,7 @@ 26A1500D29083A1300BC7355 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A1500C29083A1300BC7355 /* ContentView.swift */; }; 26A1500F29083A1400BC7355 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 26A1500E29083A1400BC7355 /* Assets.xcassets */; }; 26A1501929083B7B00BC7355 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A1501829083B7B00BC7355 /* MapView.swift */; }; - 26A82ED82A29CCDE00C23407 /* AddressSearcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A82ED72A29CCDE00C23407 /* AddressSearcher.swift */; }; + 26A82ED82A29CCDE00C23407 /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A82ED72A29CCDE00C23407 /* LocationManager.swift */; }; CE2D8D3829C59D5F00E5C104 /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE2D8D3729C59D5F00E5C104 /* ImagePicker.swift */; }; CE2D8D3A29C59DF100E5C104 /* CategoryPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE2D8D3929C59DF100E5C104 /* CategoryPicker.swift */; }; DCE7EBCF2A172C1E00644745 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCE7EBCE2A172C1E00644745 /* Extensions.swift */; }; @@ -38,7 +38,7 @@ 26A1500C29083A1300BC7355 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 26A1500E29083A1400BC7355 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 26A1501829083B7B00BC7355 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = ""; }; - 26A82ED72A29CCDE00C23407 /* AddressSearcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressSearcher.swift; sourceTree = ""; }; + 26A82ED72A29CCDE00C23407 /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = ""; }; CE2D8D3729C59D5F00E5C104 /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = ""; }; CE2D8D3929C59DF100E5C104 /* CategoryPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryPicker.swift; sourceTree = ""; }; DCE7EBCE2A172C1E00644745 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; @@ -94,7 +94,7 @@ 26A1501029083A1400BC7355 /* Preview Content */, CE2D8D3729C59D5F00E5C104 /* ImagePicker.swift */, CE2D8D3929C59DF100E5C104 /* CategoryPicker.swift */, - 26A82ED72A29CCDE00C23407 /* AddressSearcher.swift */, + 26A82ED72A29CCDE00C23407 /* LocationManager.swift */, ); path = Nav; sourceTree = ""; @@ -230,7 +230,7 @@ CE2D8D3829C59D5F00E5C104 /* ImagePicker.swift in Sources */, 26A1500D29083A1300BC7355 /* ContentView.swift in Sources */, 262C17C2290D090C00450E54 /* Font+.swift in Sources */, - 26A82ED82A29CCDE00C23407 /* AddressSearcher.swift in Sources */, + 26A82ED82A29CCDE00C23407 /* LocationManager.swift in Sources */, 262C17C6290E385E00450E54 /* Text+.swift in Sources */, 262C17C0290D06F700450E54 /* Color+.swift in Sources */, FDFD7A6129289926001BE945 /* Bundle+Ext.swift in Sources */, From cd250ead5113c1d4647fde91c83b1be3facc3cd5 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Tue, 13 Jun 2023 21:44:13 +0900 Subject: [PATCH 23/30] Chore:wrench:: #32 Modify loadAdressCoordinate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 검색한 주소의 좌표만 보내주던 loadAddressCoordinate 함수를 span까지 합쳐서 CoordinateRegion 객체로 반환하도록 변경 --- Nav/{AddressSearcher.swift => LocationManager.swift} | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) rename Nav/{AddressSearcher.swift => LocationManager.swift} (71%) diff --git a/Nav/AddressSearcher.swift b/Nav/LocationManager.swift similarity index 71% rename from Nav/AddressSearcher.swift rename to Nav/LocationManager.swift index c0bec01..45046d4 100644 --- a/Nav/AddressSearcher.swift +++ b/Nav/LocationManager.swift @@ -1,5 +1,5 @@ // -// AddressSearcher.swift +// LocationManager.swift // Nav // // Created by 김민택 on 2023/06/02. @@ -10,7 +10,7 @@ import Foundation import MapKit import SwiftUI -class AddressSearcher: NSObject, ObservableObject, MKLocalSearchCompleterDelegate { +class LocationManager: NSObject, ObservableObject, MKLocalSearchCompleterDelegate { @Published var searchQuery = "" var completer: MKLocalSearchCompleter @Published var completions: [MKLocalSearchCompletion] = [] @@ -27,14 +27,15 @@ class AddressSearcher: NSObject, ObservableObject, MKLocalSearchCompleterDelegat self.completions = completer.results } - func loadAddressCoordinate(_ address: MKLocalSearchCompletion, completoinHandler: @escaping (CLLocationCoordinate2D) -> Void) { + func loadAddressCoordinate(_ address: MKLocalSearchCompletion, completoinHandler: @escaping (MKCoordinateRegion) -> Void) { let searchRequest = MKLocalSearch.Request(completion: address) let search = MKLocalSearch(request: searchRequest) search.start { response, error in guard error == nil else { return } - guard let placeMark = response?.mapItems[0].placemark else { return } + guard let coordinate = response?.boundingRegion.center else { return } + guard let span = response?.boundingRegion.span else { return } - completoinHandler(placeMark.coordinate) + completoinHandler(MKCoordinateRegion(center: coordinate, span: span)) } } } From add7d24152cc4b44323d4737c2ff61ec9e520244 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Tue, 13 Jun 2023 21:44:29 +0900 Subject: [PATCH 24/30] Style:art:: Add Space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 공백 추가 --- Nav/View/MapView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index cdf8a37..40f4b59 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -19,7 +19,7 @@ struct MapView: View { ZStack { Map(coordinateRegion: $region, showsUserLocation: false, - annotationItems: mockDatas){ + annotationItems: mockDatas) { data in MapMarker(coordinate: data.coordinate) } From 0906d0af8acd26b1996a25430e30f2228b95ba15 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Tue, 13 Jun 2023 21:45:11 +0900 Subject: [PATCH 25/30] Chore:wrench:: #32 add animation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 검색한 좌표로 이동할 때, 순간이동하듯 넘어가지 않고 애니메이션으로 자연스럽게 이동하도록 변경 --- Nav/View/MapView.swift | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index 40f4b59..dfb1c38 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -7,7 +7,7 @@ import MapKit import SwiftUI struct MapView: View { - @ObservedObject var addressSearcher = AddressSearcher() + @ObservedObject var locationManager = LocationManager() // 서울 좌표 @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.5666791, longitude: 126.9782914), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) @@ -23,13 +23,15 @@ struct MapView: View { data in MapMarker(coordinate: data.coordinate) } - if addressSearcher.searchQuery != "" { - List(addressSearcher.completions) { completion in + if locationManager.searchQuery != "" { + List(locationManager.completions) { completion in Button { - addressSearcher.loadAddressCoordinate(completion) { coordinate in - region = MKCoordinateRegion(center: coordinate, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)) + locationManager.loadAddressCoordinate(completion) { location in + withAnimation { + region = location + } } - addressSearcher.searchQuery = "" + locationManager.searchQuery = "" } label: { VStack(alignment: .leading) { Text(completion.title) @@ -45,7 +47,7 @@ struct MapView: View { } .navigationTitle("NAV") .searchable( - text: $addressSearcher.searchQuery, + text: $locationManager.searchQuery, placement: .navigationBarDrawer, prompt: "검색" ) From e5e998efec847d2b7d1dd7001ec3258d509a0aff Mon Sep 17 00:00:00 2001 From: taek0622 Date: Tue, 13 Jun 2023 22:09:28 +0900 Subject: [PATCH 26/30] Chore:wrench:: #32 Seperate searchedView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MapView에서 검색한 결과만을 다루는 SearchedView 분리 - locationManager의 queryString의 유무가 아닌 isSearching 변수로 검색 중인지 여부 판단 - dismissSearch로 좌표 선택 완료시 자동으로 검색 종료 상태로 전환 --- Nav/View/MapView.swift | 54 +++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index dfb1c38..bdfccb7 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -22,28 +22,7 @@ struct MapView: View { annotationItems: mockDatas) { data in MapMarker(coordinate: data.coordinate) } - - if locationManager.searchQuery != "" { - List(locationManager.completions) { completion in - Button { - locationManager.loadAddressCoordinate(completion) { location in - withAnimation { - region = location - } - } - locationManager.searchQuery = "" - } label: { - VStack(alignment: .leading) { - Text(completion.title) - if completion.subtitle != "" { - Text(completion.subtitle) - .font(.subheadline) - .foregroundColor(.gray) - } - } - } - } - } + SearchedView(locationManager: locationManager, region: $region) } .navigationTitle("NAV") .searchable( @@ -55,6 +34,37 @@ struct MapView: View { } } +private struct SearchedView: View { + let locationManager: LocationManager + @Binding var region: MKCoordinateRegion + @Environment(\.isSearching) private var isSearching + @Environment(\.dismissSearch) private var dismissSearch + + var body: some View { + if isSearching { + List(locationManager.completions) { completion in + Button { + locationManager.loadAddressCoordinate(completion) { location in + withAnimation { + region = location + } + } + dismissSearch() + } label: { + VStack(alignment: .leading) { + Text(completion.title) + if completion.subtitle != "" { + Text(completion.subtitle) + .font(.subheadline) + .foregroundColor(.gray) + } + } + } + } + } + } +} + struct MapView_Previews: PreviewProvider { static var previews: some View { MapView() From 0f2007ee4b0ec08d9b939e579d97d46b226d3ec4 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Tue, 13 Jun 2023 22:25:55 +0900 Subject: [PATCH 27/30] Chore:wrench:: #32 Modify ObservedObject MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - locationManager를 StateObject와 EnvrionmentObject를 사용하는 방식으로 변경 --- Nav/View/MapView.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index bdfccb7..dfb644b 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -7,7 +7,7 @@ import MapKit import SwiftUI struct MapView: View { - @ObservedObject var locationManager = LocationManager() + @StateObject var locationManager = LocationManager() // 서울 좌표 @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.5666791, longitude: 126.9782914), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) @@ -22,7 +22,8 @@ struct MapView: View { annotationItems: mockDatas) { data in MapMarker(coordinate: data.coordinate) } - SearchedView(locationManager: locationManager, region: $region) + SearchedView(region: $region) + .environmentObject(locationManager) } .navigationTitle("NAV") .searchable( @@ -35,7 +36,7 @@ struct MapView: View { } private struct SearchedView: View { - let locationManager: LocationManager + @EnvironmentObject var locationManager: LocationManager @Binding var region: MKCoordinateRegion @Environment(\.isSearching) private var isSearching @Environment(\.dismissSearch) private var dismissSearch From 7efbd915c070c3fbba0b64697f0d8fb6b401cbbd Mon Sep 17 00:00:00 2001 From: taek0622 Date: Wed, 14 Jun 2023 18:36:09 +0900 Subject: [PATCH 28/30] Chore:wrench:: #32 Modify navigationstack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - iOS 17 이후로 Deprecate될 NavigationView에서 NavigationStack으로 변경 --- Nav/View/MapView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index dfb644b..d5338bd 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -15,7 +15,7 @@ struct MapView: View { private var mockDatas: [MockDatum] = MockDatum.allData var body: some View { - NavigationView { + NavigationStack { ZStack { Map(coordinateRegion: $region, showsUserLocation: false, From 40806c23f197d78f34f8627b179e20c273ed73cb Mon Sep 17 00:00:00 2001 From: taek0622 Date: Wed, 14 Jun 2023 18:36:52 +0900 Subject: [PATCH 29/30] Chore:wrench:: #21 Modify SearchedView Logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - NavigationStack으로 변경됨에 따라 부자연스러워진 동작 개선 --- Nav/View/MapView.swift | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index d5338bd..bbc7493 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -22,8 +22,11 @@ struct MapView: View { annotationItems: mockDatas) { data in MapMarker(coordinate: data.coordinate) } - SearchedView(region: $region) - .environmentObject(locationManager) + + if locationManager.searchQuery != "" { + SearchedView(region: $region) + .environmentObject(locationManager) + } } .navigationTitle("NAV") .searchable( @@ -38,27 +41,24 @@ struct MapView: View { private struct SearchedView: View { @EnvironmentObject var locationManager: LocationManager @Binding var region: MKCoordinateRegion - @Environment(\.isSearching) private var isSearching @Environment(\.dismissSearch) private var dismissSearch var body: some View { - if isSearching { - List(locationManager.completions) { completion in - Button { - locationManager.loadAddressCoordinate(completion) { location in - withAnimation { - region = location - } + List(locationManager.completions) { completion in + Button { + locationManager.loadAddressCoordinate(completion) { location in + withAnimation { + region = location } - dismissSearch() - } label: { - VStack(alignment: .leading) { - Text(completion.title) - if completion.subtitle != "" { - Text(completion.subtitle) - .font(.subheadline) - .foregroundColor(.gray) - } + } + dismissSearch() + } label: { + VStack(alignment: .leading) { + Text(completion.title) + if completion.subtitle != "" { + Text(completion.subtitle) + .font(.subheadline) + .foregroundColor(.gray) } } } From f60e0612d4e2530d134b6d8a819048c912214029 Mon Sep 17 00:00:00 2001 From: taek0622 Date: Wed, 13 May 2026 20:42:28 +0900 Subject: [PATCH 30/30] wip --- Nav.xcodeproj/project.pbxproj | 8 ---- Nav/ContentView.swift | 72 +++++++++++++++++++++++------ Nav/View/ListView.swift | 87 +++++++++++++++-------------------- Nav/View/MapView.swift | 79 +++++++++++++++++++++++++++---- 4 files changed, 166 insertions(+), 80 deletions(-) diff --git a/Nav.xcodeproj/project.pbxproj b/Nav.xcodeproj/project.pbxproj index d4de00c..16a84ec 100644 --- a/Nav.xcodeproj/project.pbxproj +++ b/Nav.xcodeproj/project.pbxproj @@ -149,14 +149,6 @@ path = Extension; sourceTree = ""; }; - 26FE54E62949B90100B4E0E9 /* Data */ = { - isa = PBXGroup; - children = ( - FDFD7A642928993A001BE945 /* MockData.json */, - ); - path = Data; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ diff --git a/Nav/ContentView.swift b/Nav/ContentView.swift index e85df69..8b7dc42 100644 --- a/Nav/ContentView.swift +++ b/Nav/ContentView.swift @@ -5,24 +5,68 @@ // Created by 김민택 on 2022/10/26. // +import MapKit import SwiftUI struct ContentView: View { + @State private var selectedTab = 0 + @State private var isOpen = false + @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.5666791, longitude: 126.9782914), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) + @StateObject var locationManager = LocationManager() + var body: some View { - TabView { - MapView() - .tabItem { - Image(systemName: "map") - } - - ListView() - .tabItem { - Image(systemName: "list.bullet") - } - - PinCreationView() - .tabItem { - Image(systemName: "plus") +// TabView { +// MapView() +// .tabItem { +// Image(systemName: "map") +// } +// +// ListView() +// .tabItem { +// Image(systemName: "list.bullet") +// } +// +// PinCreationView() +// .tabItem { +// Image(systemName: "plus") +// } +// } + ZStack { + MapView(selectedTab: $selectedTab, isOpen: $isOpen, region: $region) + .environmentObject(locationManager) + VStack {} + .toolbar { + ToolbarItemGroup(placement: .bottomBar) { + Spacer() + + Button { + selectedTab = 0 + } label: { + Image(systemName: "map.fill") + .foregroundColor(selectedTab == 0 ? .blue : .gray) + } + + Spacer() + + Button { + selectedTab = 1 + isOpen = true + } label: { + Image(systemName: "list.bullet") + .foregroundColor(selectedTab == 1 ? .blue : .gray) + } + + Spacer() + + Button { + selectedTab = 2 + } label: { + Image(systemName: "gear") + .foregroundColor(selectedTab == 2 ? .blue : .gray) + } + + Spacer() + } } } } diff --git a/Nav/View/ListView.swift b/Nav/View/ListView.swift index 45fe054..68f33c4 100644 --- a/Nav/View/ListView.swift +++ b/Nav/View/ListView.swift @@ -11,58 +11,45 @@ import SwiftUI struct ListView: View { private var mockDatas: [MockDatum] = MockDatum.allData @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.5666791, longitude: 126.9782914), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) - @State var searchText = "" - @State var inSearchMode = false - + var body: some View { - - VStack(alignment: .leading){ - - Text("Nav") - .font(.system(size: 40,weight: .semibold)) - .padding(EdgeInsets(top: 0, leading: 30, bottom: -10, trailing: 0)) - - SearchBar(text: $searchText, isEditing: $inSearchMode) - .padding() - - Map(coordinateRegion: $region, - showsUserLocation: false, - annotationItems: mockDatas){ - data in MapMarker(coordinate: data.coordinate) - } - - Text("주소 리스트") - .font(.system(size: 20,weight: .semibold)) - .padding(EdgeInsets(top: 0, leading: 150, bottom: 8, trailing: 0)) - HStack { - Text("카페") - .font(.system(size: 16,weight: .semibold)) - .foregroundColor(.indigo) - .padding(EdgeInsets(top: 0, leading: 30, bottom: 0, trailing: 0)) - Spacer() - Text("최신순") - .font(.system(size: 16,weight: .semibold)) - .foregroundColor(.blue) - Image(systemName: "arrow.down.square") - .foregroundColor(.blue) - .padding(EdgeInsets(top: 0, leading: -7, bottom: 0, trailing: 20)) - } - - List{ - ForEach(mockDatas, id: \.id) { - mockDatum in - HStack{ - Image(systemName: "cup.and.saucer") - .foregroundColor(.redBean) - Text("\(mockDatum.title.rawValue)") - .font(.system(size: 15)) - .swipeActions { - Button(role: .destructive) { - // code - } label: { - Label("Delete", systemImage: "trash.fill") + NavigationStack { + VStack(alignment: .leading) { + List{ + ForEach(mockDatas, id: \.id) { + mockDatum in + HStack{ + Image(systemName: "cup.and.saucer") + .foregroundColor(.redBean) + Text("\(mockDatum.title.rawValue)") + .font(.system(size: 15)) + .swipeActions { + Button(role: .destructive) { + // code + } label: { + Label("Delete", systemImage: "trash.fill") + } } - } + } + } + } + } + .navigationTitle("주소리스트") + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .navigationBarLeading) { + Button { + + } label: { + Text("카페") + } + } + ToolbarItem(placement: .navigationBarTrailing) { + Button { + + } label: { + Text("최신순") + Image(systemName: "arrow.down.square") } } } diff --git a/Nav/View/MapView.swift b/Nav/View/MapView.swift index bbc7493..a88b2aa 100644 --- a/Nav/View/MapView.swift +++ b/Nav/View/MapView.swift @@ -6,13 +6,20 @@ // import MapKit import SwiftUI + struct MapView: View { - @StateObject var locationManager = LocationManager() +// @StateObject var locationManager = LocationManager() +// @State private var selectedTab = 0 +// @State private var isOpen = false + @Binding var selectedTab: Int + @Binding var isOpen: Bool // 서울 좌표 - @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.5666791, longitude: 126.9782914), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) +// @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.5666791, longitude: 126.9782914), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) + @Binding var region: MKCoordinateRegion + @EnvironmentObject var locationManager: LocationManager - private var mockDatas: [MockDatum] = MockDatum.allData + var mockDatas: [MockDatum] = MockDatum.allData var body: some View { NavigationStack { @@ -22,6 +29,22 @@ struct MapView: View { annotationItems: mockDatas) { data in MapMarker(coordinate: data.coordinate) } + VStack { + Spacer() + if selectedTab == 2 { + NavigationStack { + ListView() + } + .frame(height: UIScreen.main.bounds.height / 2) + .cornerRadius(16) + } + } + .sheet(isPresented: $isOpen) { + selectedTab = (selectedTab == 1 ? 0 : 2) + } content: { + ListView() + .presentationDetents([.fraction(0.25), .medium, .fraction(0.8)]) + } if locationManager.searchQuery != "" { SearchedView(region: $region) @@ -34,6 +57,46 @@ struct MapView: View { placement: .navigationBarDrawer, prompt: "검색" ) +// .toolbar { +// ToolbarItemGroup(placement: .bottomBar) { +// Spacer() +// +// Button { +// selectedTab = 0 +// } label: { +// Image(systemName: "map.fill") +// .foregroundColor(selectedTab == 0 ? .blue : .gray) +// } +// +// Spacer() +// +// Button { +// selectedTab = 1 +// isOpen = true +// } label: { +// Image(systemName: "list.bullet") +// .foregroundColor(selectedTab == 1 ? .blue : .gray) +// } +// +// Spacer() +// +// Button { +// selectedTab = 2 +// } label: { +// Image(systemName: "gear") +// .foregroundColor(selectedTab == 2 ? .blue : .gray) +// } +// +// Spacer() +// } +// } +// .sheet(isPresented: $isOpen) { +// selectedTab = (selectedTab == 1 ? 0 : 2) +// } content: { +// ListView() +// .presentationDetents([.fraction(0.25), .medium, .large]) +// } + } } } @@ -66,8 +129,8 @@ private struct SearchedView: View { } } -struct MapView_Previews: PreviewProvider { - static var previews: some View { - MapView() - } -} +//struct MapView_Previews: PreviewProvider { +// static var previews: some View { +// MapView() +// } +//}