SwiftUI (Swift) দিয়ে আপনার iOS অ্যাপে একটি মানচিত্র যোগ করুন

1. আপনি শুরু করার আগে

এই কোডল্যাব আপনাকে শেখায় কিভাবে SwiftUI এর সাথে iOS এর জন্য Maps SDK ব্যবহার করতে হয়।

স্ক্রিনশট-iphone-12-black@2x.png

পূর্বশর্ত

  • বেসিক সুইফট জ্ঞান
  • SwiftUI এর সাথে প্রাথমিক পরিচিতি

আপনি কি করবেন

  • SwiftUI ব্যবহার করে একটি iOS অ্যাপে Google Maps যোগ করতে iOS-এর জন্য Maps SDK চালু করুন এবং ব্যবহার করুন।
  • মানচিত্রে চিহ্নিতকারী যোগ করুন।
  • একটি SwiftUI এবং একটি GMSMapView অবজেক্টের মধ্যে পাসের অবস্থা।

আপনি কি প্রয়োজন হবে

2. সেট আপ করুন

নিম্নলিখিত সক্রিয়করণ পদক্ষেপের জন্য, iOS এর জন্য মানচিত্র SDK সক্ষম করুন৷

Google Maps প্ল্যাটফর্ম সেট আপ করুন

আপনার যদি ইতিমধ্যেই একটি Google ক্লাউড প্ল্যাটফর্ম অ্যাকাউন্ট না থাকে এবং বিলিং সক্ষম করা একটি প্রকল্প থাকে, তাহলে অনুগ্রহ করে একটি বিলিং অ্যাকাউন্ট এবং একটি প্রকল্প তৈরি করতে Google মানচিত্র প্ল্যাটফর্মের সাথে শুরু করা নির্দেশিকাটি দেখুন৷

  1. ক্লাউড কনসোলে , প্রকল্পের ড্রপ-ডাউন মেনুতে ক্লিক করুন এবং এই কোডল্যাবের জন্য আপনি যে প্রকল্পটি ব্যবহার করতে চান সেটি নির্বাচন করুন।

  1. Google ক্লাউড মার্কেটপ্লেসে এই কোডল্যাবের জন্য প্রয়োজনীয় Google মানচিত্র প্ল্যাটফর্ম API এবং SDK সক্ষম করুন৷ এটি করতে, এই ভিডিও বা এই ডকুমেন্টেশনের ধাপগুলি অনুসরণ করুন৷
  2. ক্লাউড কনসোলের শংসাপত্র পৃষ্ঠায় একটি API কী তৈরি করুন। আপনি এই ভিডিও বা এই ডকুমেন্টেশনের ধাপগুলি অনুসরণ করতে পারেন। Google মানচিত্র প্ল্যাটফর্মের সমস্ত অনুরোধের জন্য একটি API কী প্রয়োজন৷

3. স্টার্টার কোড ডাউনলোড করুন

যত তাড়াতাড়ি সম্ভব আপনাকে শুরু করতে, এই কোডল্যাবের সাথে আপনাকে অনুসরণ করতে সহায়তা করার জন্য এখানে কিছু স্টার্টার কোড রয়েছে৷ সমাধানে ঝাঁপ দিতে আপনাকে স্বাগত জানাই, তবে আপনি যদি এটি নিজে তৈরি করার সমস্ত পদক্ষেপগুলি অনুসরণ করতে চান তবে পড়তে থাকুন।

  1. আপনি যদি git ইনস্টল করে থাকেন তবে সংগ্রহস্থল ক্লোন করুন।
git clone https://github.com/googlecodelabs/maps-ios-swiftui.git

বিকল্পভাবে, আপনি সোর্স কোড ডাউনলোড করতে নিম্নলিখিত বোতামে ক্লিক করতে পারেন।

  1. কোডটি পাওয়ার পরে, একটি টার্মিনাল cd starter/GoogleMapsSwiftUI ডিরেক্টরিতে।
  2. iOS এর জন্য মানচিত্র SDK ডাউনলোড করতে carthage update --platform iOS চালান৷
  3. অবশেষে, Xcode-এ GoogleMapsSwiftUI.xcodeproj ফাইলটি খুলুন

4. কোড ওভারভিউ

আপনার ডাউনলোড করা স্টার্টার প্রকল্পে, আপনার জন্য নিম্নলিখিত ক্লাসগুলি সরবরাহ করা হয়েছে এবং প্রয়োগ করা হয়েছে:

  • AppDelegate - অ্যাপ্লিকেশনটির UIApplicationDelegate । এখানেই iOS এর জন্য Maps SDK সূচনা করা হবে৷
  • City - একটি কাঠামো যা একটি শহরের প্রতিনিধিত্ব করে (শহরের একটি নাম এবং স্থানাঙ্ক রয়েছে)।
  • MapViewController - একটি স্কোপ-ডাউন UIKit UIViewController যাতে একটি Google Map ( GMSMapView ) রয়েছে
    • SceneDelegate - অ্যাপ্লিকেশনটির UIWindowSceneDelegate যেখান থেকে ContentView তাৎক্ষণিকভাবে তৈরি করা হয়।

অতিরিক্তভাবে, নিম্নলিখিত ক্লাসগুলির আংশিক বাস্তবায়ন রয়েছে এবং এই কোডল্যাবের শেষে আপনার দ্বারা সম্পন্ন হবে:

  • ContentView - আপনার অ্যাপ ধারণকারী শীর্ষ-স্তরের SwiftUI ভিউ।
  • MapViewControllerBridge - একটি শ্রেণী যা একটি UIKit ভিউকে একটি SwiftUI ভিউতে সেতু করে। বিশেষত, এটি সেই ক্লাস যা MapViewController SwiftUI-তে অ্যাক্সেসযোগ্য করে তুলবে।

5. SwiftUI বনাম UIKit

SwiftUI iOS 13-এ iOS অ্যাপ্লিকেশন তৈরির জন্য UIKit-এর উপর একটি বিকল্প UI ফ্রেমওয়ার্ক হিসেবে চালু করা হয়েছিল। এর পূর্বসূরি UIKit-এর তুলনায়, SwiftUI বেশ কিছু সুবিধা প্রদান করে। কয়েকটি নাম বলতে:

  • অবস্থা পরিবর্তন হলে ভিউ স্বয়ংক্রিয়ভাবে আপডেট হয়। স্টেট নামক বস্তু ব্যবহার করে, এতে থাকা অন্তর্নিহিত মানের যে কোনো পরিবর্তন UI স্বয়ংক্রিয়ভাবে আপডেট হবে।
  • লাইভ প্রিভিউ দ্রুত বিকাশ সক্ষম করে। লাইভ প্রিভিউগুলি Xcode-এ সুইফটইউআই ভিউয়ের পূর্বরূপ হিসাবে দৃশ্যমান পরিবর্তনগুলি দেখতে একটি এমুলেটরে কোড তৈরি এবং স্থাপন করার প্রয়োজনীয়তা কমিয়ে দেয়।
  • সত্যের উৎস সুইফটে। SwiftUI-এর সমস্ত ভিউ সুইফটে ঘোষণা করা হয়েছে তাই ইন্টারফেস বিল্ডার ব্যবহার করার আর প্রয়োজন নেই।
  • UIKit এর সাথে ইন্টারঅপারেটিং করে। UIKit-এর সাথে ইন্টারঅপারেবিলিটি নিশ্চিত করে যে বিদ্যমান অ্যাপগুলি তাদের বিদ্যমান ভিউগুলির সাথে ক্রমবর্ধমানভাবে SwiftUI ব্যবহার করতে পারে। এছাড়াও, যে লাইব্রেরিগুলি এখনও SwiftUI সমর্থন করে না, যেমন iOS এর জন্য Maps SDK , এখনও SwiftUI-তে ব্যবহার করা যেতে পারে।

এছাড়াও কিছু অপূর্ণতা আছে:

  • SwiftUI শুধুমাত্র iOS 13 বা তার পরে উপলব্ধ।
  • Xcode প্রিভিউতে ভিউ হায়ারার্কি পরীক্ষা করা যাবে না।

SwiftUI রাজ্য এবং ডেটা প্রবাহ

সুইফটইউআই একটি ঘোষণামূলক পদ্ধতি ব্যবহার করে UI তৈরি করার একটি অভিনব উপায় অফার করে—আপনি SwiftUI-কে বলুন যে আপনি কীভাবে আপনার দৃষ্টিভঙ্গি এর জন্য বিভিন্ন রাজ্যের সাথে দেখতে চান, এবং সিস্টেম বাকিটা করবে। যখনই কোনো ইভেন্ট বা ব্যবহারকারীর ক্রিয়াকলাপের কারণে অন্তর্নিহিত অবস্থা পরিবর্তিত হয় তখন SwiftUI ভিউ আপডেট করে। এই নকশাটিকে সাধারণত একমুখী ডেটা প্রবাহ বলা হয়। এই কোডল্যাবে এই ডিজাইনের সুনির্দিষ্ট বিষয়গুলি সুযোগের বাইরে থাকলেও, আমরা অ্যাপলের স্টেট এবং ডেটা ফ্লো সংক্রান্ত ডকুমেন্টেশনে এটি কীভাবে কাজ করে তা পড়ার পরামর্শ দিই।

UIViewRepresentable বা UIViewControllerRepresentable ব্যবহার করে ব্রিজ UIKit এবং SwiftUI

যেহেতু iOS-এর জন্য মানচিত্র SDK UIKit-এর উপরে তৈরি করা হয়েছে এবং এটি একটি SwiftUI- সামঞ্জস্যপূর্ণ ভিউ প্রদান করে না, তাই SwiftUI-তে এটি ব্যবহার করার জন্য UIViewRepresentable বা UIViewControllerRepresentable সাথে সামঞ্জস্যপূর্ণ হওয়া প্রয়োজন। এই প্রোটোকলগুলি SwiftUI কে যথাক্রমে UIKit-নির্মিত UIView s এবং UIViewController অন্তর্ভুক্ত করতে সক্ষম করে। আপনি একটি SwiftUI ভিউতে একটি Google মানচিত্র যোগ করার জন্য যেকোনো একটি প্রোটোকল ব্যবহার করতে পারেন, পরবর্তী ধাপে, আমরা একটি মানচিত্র ধারণকারী একটি UIViewController অন্তর্ভুক্ত করার জন্য একটি UIViewControllerRepresentable ব্যবহার করে দেখব।

6. একটি মানচিত্র যোগ করুন

এই বিভাগে, আপনি একটি SwiftUI ভিউতে Google মানচিত্র যোগ করবেন।

add-a-map-screenshot@2x.png

আপনার API কী যোগ করুন

আপনি একটি আগের ধাপে যে API কী তৈরি করেছেন তা অ্যাপে প্রদর্শিত মানচিত্রের সাথে আপনার অ্যাকাউন্টকে সংযুক্ত করতে iOS-এর জন্য Maps SDK-কে প্রদান করতে হবে।

আপনার API কী প্রদান করতে, AppDelegate.swift ফাইলটি খুলুন এবং application(_, didFinishLaunchingWithOptions) পদ্ধতিতে নেভিগেট করুন। "YOUR_API_KEY" স্ট্রিং সহ GMSServices.provideAPIKey() ব্যবহার করে SDK শুরু করা হয়েছে। আপনার API কী দিয়ে সেই স্ট্রিংটি প্রতিস্থাপন করুন। এই ধাপটি সম্পূর্ণ করলে iOS এর জন্য Maps SDK চালু হবে যখন অ্যাপ্লিকেশনটি চালু হবে।

MapViewControllerBridge ব্যবহার করে একটি Google মানচিত্র যোগ করুন

এখন যেহেতু আপনার API কী SDK-এ প্রদান করা হচ্ছে, পরবর্তী ধাপ হল অ্যাপে মানচিত্র প্রদর্শন করা।

স্টার্টার কোডে যে ভিউ কন্ট্রোলার দেওয়া আছে, MapViewController ভিউতে একটি GMSMapView রয়েছে। যাইহোক, যেহেতু এই ভিউ কন্ট্রোলারটি UIKit-এ তৈরি করা হয়েছিল, তাই আপনাকে এই ক্লাসটিকে SwiftUI-তে ব্রিজ করতে হবে যাতে এটি ContentView ভিতরে ব্যবহার করা যায়। এটি করতে:

  1. Xcode এ MapViewControllerBridge ফাইলটি খুলুন।

এই ক্লাসটি UIViewControllerRepresentable- এর সাথে সামঞ্জস্যপূর্ণ যা একটি UIKit UIViewController মোড়ানোর জন্য প্রয়োজনীয় প্রোটোকল যাতে এটি একটি SwiftUI ভিউ হিসাবে ব্যবহার করা যায়। অন্য কথায়, এই প্রোটোকলের সাথে সামঞ্জস্য করা একটি UIKit ভিউকে একটি SwiftUI ভিউতে ব্রিজ করার সুবিধা দেয়। এই প্রোটোকল মেনে চলার জন্য দুটি পদ্ধতির বাস্তবায়ন প্রয়োজন:

  • makeUIViewController(context) - অন্তর্নিহিত UIViewController তৈরি করতে এই পদ্ধতিটিকে SwiftUI দ্বারা বলা হয়। এখানেই আপনি আপনার UIViewController ইনস্ট্যান্টিয়েট করবেন এবং এটির প্রাথমিক অবস্থা পাস করবেন।
  • updateUIViewController(_, context) - যখনই অবস্থা পরিবর্তন হয় তখন এই পদ্ধতিটি SwiftUI দ্বারা বলা হয়। রাজ্য পরিবর্তনের প্রতিক্রিয়ায় প্রতিক্রিয়া জানাতে আপনি অন্তর্নিহিত UIViewController এ কোনো পরিবর্তন করতে পারবেন।
  1. একটি MapViewController তৈরি করুন

makeUIViewController(context) ফাংশনের ভিতরে, একটি নতুন MapViewController ইনস্ট্যান্টিয়েট করুন এবং ফলস্বরূপ এটি ফেরত দিন। এটি করার পরে, আপনার MapViewControllerBridge এখন এইরকম হওয়া উচিত:

MapViewControllerBridge

import GoogleMaps
import SwiftUI

struct MapViewControllerBridge: UIViewControllerRepresentable {

  func makeUIViewController(context: Context) -> MapViewController {
    return MapViewController()
  }

  func updateUIViewController(_ uiViewController: MapViewController, context: Context) {
  }
}

ContentView এ MapViewControllerBridge ব্যবহার করুন

এখন যেহেতু MapViewControllerBridge MapViewController এর একটি উদাহরণ তৈরি করছে, পরবর্তী পদক্ষেপটি হল একটি মানচিত্র প্রদর্শনের জন্য ContentView মধ্যে এই কাঠামোটি ব্যবহার করা।

  1. Xcode এ ContentView ফাইলটি খুলুন।

ContentView SceneDelegate এ ইনস্ট্যান্টিয়েট করা হয়েছে এবং এতে শীর্ষ-স্তরের অ্যাপ্লিকেশন ভিউ রয়েছে। মানচিত্র এই ফাইলের মধ্যে থেকে যোগ করা হবে.

  1. body সম্পত্তির মধ্যে একটি MapViewControllerBridge তৈরি করুন।

এই ফাইলের body সম্পত্তির মধ্যে, একটি ZStack ইতিমধ্যেই আপনার জন্য প্রদান করা হয়েছে এবং প্রয়োগ করা হয়েছে। ZStack শহরগুলির একটি মিথস্ক্রিয়াযোগ্য এবং টেনে আনা যায় এমন তালিকা রয়েছে যা আপনি পরবর্তী ধাপে ব্যবহার করবেন। আপাতত, ZStack এর মধ্যে ZStack এর প্রথম চাইল্ড ভিউ হিসেবে একটি MapViewControllerBridge তৈরি করুন যাতে অ্যাপে শহরের দৃশ্যের তালিকার পিছনে একটি মানচিত্র প্রদর্শিত হবে। এটি করার পরে, ContentView মধ্যে body সম্পত্তির বিষয়বস্তু এইরকম হওয়া উচিত:

কন্টেন্টভিউ

var body: some View {

  let scrollViewHeight: CGFloat = 80

  GeometryReader { geometry in
    ZStack(alignment: .top) {
      // Map
      MapViewControllerBridge()

      // Cities List
      CitiesList(markers: $markers) { (marker) in
        guard self.selectedMarker != marker else { return }
        self.selectedMarker = marker
        self.zoomInCenter = false
        self.expandList = false
      }  handleAction: {
        self.expandList.toggle()
      } // ...
    }
  }
}
  1. এখন এগিয়ে যান এবং অ্যাপ্লিকেশন চালান. আপনি এখন আপনার ডিভাইসের স্ক্রিনে মানচিত্র লোড দেখতে পাবেন এবং স্ক্রিনের নীচের দিকে শহরগুলির একটি টেনে আনা যাবে।

7. মানচিত্রে চিহ্নিতকারী যোগ করুন

পূর্ববর্তী ধাপে, আপনি শহরগুলির একটি তালিকা প্রদর্শন করে একটি ইন্টারঅ্যাক্টেবল তালিকার পাশাপাশি একটি মানচিত্র যুক্ত করেছেন৷ এই বিভাগে, আপনি সেই তালিকায় প্রতিটি শহরের জন্য চিহ্নিতকারী যোগ করবেন।

map-with-markers@2x.png

রাজ্য হিসাবে চিহ্নিতকারী

ContentView markers নামে একটি সম্পত্তি ঘোষণা করে যা cities স্ট্যাটিক সম্পত্তিতে ঘোষিত প্রতিটি শহরের প্রতিনিধিত্ব করে GMSMarker একটি তালিকা। লক্ষ্য করুন যে এই সম্পত্তিটি SwiftUI প্রপার্টি র‍্যাপার স্টেটের সাথে টীকা করা হয়েছে যাতে বোঝানো যায় যে এটি SwiftUI দ্বারা পরিচালনা করা উচিত। সুতরাং, যদি এই সম্পত্তির সাথে কোনও পরিবর্তন সনাক্ত করা হয়, যেমন একটি মার্কার যোগ করা বা সরানো, এই অবস্থা ব্যবহার করে দেখাগুলি আপডেট করা হবে।

কন্টেন্টভিউ

  static let cities = [
    City(name: "San Francisco", coordinate: CLLocationCoordinate2D(latitude: 37.7576, longitude: -122.4194)),
    City(name: "Seattle", coordinate: CLLocationCoordinate2D(latitude: 47.6131742, longitude: -122.4824903)),
    City(name: "Singapore", coordinate: CLLocationCoordinate2D(latitude: 1.3440852, longitude: 103.6836164)),
    City(name: "Sydney", coordinate: CLLocationCoordinate2D(latitude: -33.8473552, longitude: 150.6511076)),
    City(name: "Tokyo", coordinate: CLLocationCoordinate2D(latitude: 35.6684411, longitude: 139.6004407))
  ]

  /// State for markers displayed on the map for each city in `cities`
  @State var markers: [GMSMarker] = cities.map {
    let marker = GMSMarker(position: $0.coordinate)
    marker.title = $0.name
    return marker
  }

লক্ষ্য করুন যে ContentView শহরের তালিকাকে CitiesList ক্লাসে পাস করার জন্য markers বৈশিষ্ট্য ব্যবহার করে।

শহরের তালিকা

struct CitiesList: View {

  @Binding var markers: [GMSMarker]

  var body: some View {
    GeometryReader { geometry in
      VStack(spacing: 0) {
        // ...
        // List of Cities
        List {
          ForEach(0..<self.markers.count) { id in
            let marker = self.markers[id]
            Button(action: {
              buttonAction(marker)
            }) {
              Text(marker.title ?? "")
            }
          }
        }.frame(maxWidth: .infinity)
      }
    }
  }
}

@Binding ব্যবহার করে MapViewControllerBridge-এ রাজ্য পাস করুন

markers সম্পত্তি থেকে ডেটা প্রদর্শন করা শহরগুলির তালিকা ছাড়াও, এই বৈশিষ্ট্যটি MapViewControllerBridge স্ট্রাকটে পাস করুন যাতে এটি মানচিত্রে সেই মার্কারগুলি প্রদর্শন করতে ব্যবহার করা যেতে পারে। এটি করতে:

  1. MapViewControllerBridge মধ্যে একটি নতুন markers সম্পত্তি ঘোষণা করুন যা @Binding Binding-এর সাথে টীকাযুক্ত

MapViewControllerBridge

struct MapViewControllerBridge: : UIViewControllerRepresentable {
  @Binding var markers: [GMSMarker]
  // ...
}
  1. MapViewControllerBridge এ, markers সম্পত্তি ব্যবহার করতে updateUIViewController(_, context) পদ্ধতি আপডেট করুন

পূর্ববর্তী ধাপে উল্লিখিত হিসাবে, যখনই অবস্থা পরিবর্তন হবে তখনই SwiftUI দ্বারা updateUIViewController(_, context) কল করা হবে। এই পদ্ধতির মধ্যেই আমরা মানচিত্র আপডেট করতে চাই তাই markers মার্কারগুলি প্রদর্শন করুন। এটি করার জন্য, আপনাকে প্রতিটি চিহ্নিতকারীর map বৈশিষ্ট্য আপডেট করতে হবে। এই ধাপটি সম্পূর্ণ করার পরে, আপনার MapViewControllerBridge দেখতে এইরকম হওয়া উচিত:

import GoogleMaps
import SwiftUI

struct MapViewControllerBridge: UIViewControllerRepresentable {

  @Binding var markers: [GMSMarker]

  func makeUIViewController(context: Context) -> MapViewController {
    return MapViewController()
  }

  func updateUIViewController(_ uiViewController: MapViewController, context: Context) {
    // Update the map for each marker
    markers.forEach { $0.map = uiViewController.map }
  }
}
  1. ContentView থেকে MapViewControllerBridge পর্যন্ত markers সম্পত্তি পাস করুন

যেহেতু আপনি MapViewControllerBridge এ একটি নতুন প্রপার্টি যোগ করেছেন, তাই এখন এই প্রপার্টির মানটি MapViewControllerBridge এর ইনিশিয়ালাইজারে পাস করতে হবে। সুতরাং, আপনি যদি অ্যাপটি তৈরি করার চেষ্টা করেন তবে আপনার লক্ষ্য করা উচিত যে এটি কম্পাইল হবে না। এটি ঠিক করতে, MapViewControllerBridge যেখানে MapViewControllerBridge তৈরি করা হয়েছে সেখানে ContentView এ একটি আপডেট করুন এবং markers প্রপার্টিতে পাস করুন এভাবে:

struct ContentView: View {
  // ...
  var body: some View {
    // ...
    GeometryReader { geometry in
      ZStack(alignment: .top) {
        // Map
        MapViewControllerBridge(markers: $markers)
        // ...
      }
    }
  }
}

লক্ষ্য করুন $ উপসর্গটি MapViewControllerBridgemarkers পাস করার জন্য ব্যবহৃত হয়েছিল কারণ এটি একটি আবদ্ধ সম্পত্তি আশা করে। $ একটি সংরক্ষিত উপসর্গ সুইফট সম্পত্তি মোড়কের সাথে ব্যবহারের জন্য। একটি রাজ্যে প্রয়োগ করা হলে, এটি একটি বাইন্ডিং ফিরিয়ে দেবে।

  1. ম্যাপে প্রদর্শিত মার্কারগুলি দেখতে এগিয়ে যান এবং অ্যাপটি চালান৷

8. একটি নির্বাচিত শহরে অ্যানিমেট করুন

পূর্ববর্তী ধাপে, আপনি একটি সুইফটইউআই ভিউ থেকে অন্যটিতে স্টেট পাস করে একটি মানচিত্রে চিহ্নিতকারী যোগ করেছেন। এই ধাপে, ইন্টারঅ্যাক্টেবল তালিকায় ট্যাপ করার পরে আপনি একটি শহর বা চিহ্নিতকারীতে অ্যানিমেট করবেন। অ্যানিমেশন সঞ্চালন করার জন্য, যখন পরিবর্তন ঘটে তখন আপনি মানচিত্রের ক্যামেরা অবস্থান পরিবর্তন করে একটি রাজ্যে পরিবর্তনের প্রতিক্রিয়া জানাবেন। মানচিত্রের ক্যামেরার ধারণা সম্পর্কে আরও জানতে, ক্যামেরা এবং ভিউ দেখুন।

animate-city@2x.png

নির্বাচিত শহরের মানচিত্র অ্যানিমেট করুন

একটি নির্বাচিত শহরে মানচিত্র অ্যানিমেট করতে:

  1. MapViewControllerBridge এ একটি নতুন বাইন্ডিং সংজ্ঞায়িত করুন

ContentView একটি স্টেট প্রপার্টি রয়েছে যার নাম selectedMarker যা শূন্য থেকে শুরু করা হয় এবং যখনই তালিকায় একটি শহর নির্বাচন করা হয় তখন আপডেট করা হয়। এটি ContentView মধ্যে CitiesList view buttonAction দ্বারা পরিচালিত হয়।

কন্টেন্টভিউ

CitiesList(markers: $markers) { (marker) in
  guard self.selectedMarker != marker else { return }
  self.selectedMarker = marker
  // ...
}

যখনই selectedMarker পরিবর্তন হয়, MapViewControllerBridge এই অবস্থার পরিবর্তন সম্পর্কে সচেতন হওয়া উচিত যাতে এটি নির্বাচিত মার্কারে মানচিত্রটিকে অ্যানিমেট করতে পারে। সুতরাং, GMSMarker টাইপের MapViewControllerBridge এর মধ্যে একটি নতুন বাইন্ডিং সংজ্ঞায়িত করুন এবং selectedMarker সম্পত্তির নাম দিন।

MapViewControllerBridge

struct MapViewControllerBridge: UIViewControllerRepresentable {
  @Binding var selectedMarker: GMSMarker?
}
  1. যখনই selectedMarker পরিবর্তন হয় তখন মানচিত্রটিকে অ্যানিমেট করতে MapViewControllerBridge আপডেট করুন

একবার একটি নতুন বাইন্ডিং ঘোষণা করা হলে, আপনাকে MapViewControllerBridge এর updateUIViewController_, context) ফাংশন আপডেট করতে হবে যাতে মানচিত্রটি নির্বাচিত মার্কারে অ্যানিমেট হয়। এগিয়ে যান এবং নিম্নলিখিত কোড অনুলিপি করে তা করুন:

struct MapViewControllerBridge: UIViewControllerRepresentable {
  @Binding var selectedMarker: GMSMarker?

  func updateUIViewController(_ uiViewController: MapViewController, context: Context) {
    markers.forEach { $0.map = uiViewController.map }
    selectedMarker?.map = uiViewController.map
    animateToSelectedMarker(viewController: uiViewController)
  }

  private func animateToSelectedMarker(viewController: MapViewController) {
    guard let selectedMarker = selectedMarker else {
      return
    }

    let map = viewController.map
    if map.selectedMarker != selectedMarker {
      map.selectedMarker = selectedMarker
      DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
        map.animate(toZoom: kGMSMinZoomLevel)
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
          map.animate(with: GMSCameraUpdate.setTarget(selectedMarker.position))
          DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
            map.animate(toZoom: 12)
          })
        }
      }
    }
  }
}

animateToSelectedMarker(viewController) ফাংশন GMSMapView এর animate(with) ফাংশন ব্যবহার করে মানচিত্র অ্যানিমেশনের একটি ক্রম সম্পাদন করবে।

  1. MapViewControllerBridgeContentView এর selectedMarker পাস করুন

একবার MapViewControllerBridge নতুন বাইন্ডিং ঘোষণা করা হলে, এগিয়ে যান এবং selectedMarker মার্কারে পাস করতে ContentView আপডেট করুন যেখানে MapViewControllerBridge ইনস্ট্যান্টিয়েট করা হয়েছে।

কন্টেন্টভিউ

struct ContentView: View {
  // ...
  var body: some View {
    // ...
    GeometryReader { geometry in
      ZStack(alignment: .top) {
        // Map
        MapViewControllerBridge(markers: $markers, selectedMarker: $selectedMarker)
        // ...
      }
    }
  }
}

এই ধাপটি সম্পূর্ণ করার ফলে যখনই তালিকায় একটি নতুন শহর নির্বাচন করা হবে তখনই মানচিত্রটিকে অ্যানিমেট করবে।

শহরের উপর জোর দিতে SwiftUI ভিউ অ্যানিমেট করুন

SwiftUI ভিউ অ্যানিমেট করার প্রক্রিয়াকে সহজ করে, কারণ এটি স্টেট ট্রানজিশনের জন্য অ্যানিমেশনগুলি পরিচালনা করবে। এটি প্রদর্শন করার জন্য, মানচিত্র অ্যানিমেশন সম্পূর্ণ হওয়ার পরে আপনি নির্বাচিত শহরের দৃশ্যে ফোকাস করে আরও অ্যানিমেশন যোগ করবেন। এটি সম্পন্ন করতে, নিম্নলিখিত পদক্ষেপগুলি সম্পূর্ণ করুন:

  1. MapViewControllerBridge এ একটি onAnimationEnded ক্লোজার যোগ করুন

যেহেতু SwiftUI অ্যানিমেশন আপনার আগে যোগ করা ম্যাপ অ্যানিমেশন সিকোয়েন্সের পরে সঞ্চালিত হবে, তাই MapViewControllerBridge মধ্যে onAnimationEnded নামে একটি নতুন বন্ধ ঘোষণা করুন এবং animateToSelectedMarker(viewController) পদ্ধতির মধ্যে শেষ মানচিত্র অ্যানিমেশনের পরে 0.5 সেকেন্ড বিলম্বের পরে এই বন্ধের আহ্বান করুন।

MapViewControllerBridge

struct MapViewControllerBridge: UIViewControllerRepresentable {
    var onAnimationEnded: () -> ()

    private func animateToSelectedMarker(viewController: MapViewController) {
    guard let selectedMarker = selectedMarker else {
      return
    }

    let map = viewController.map
    if map.selectedMarker != selectedMarker {
      map.selectedMarker = selectedMarker
      DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
        map.animate(toZoom: kGMSMinZoomLevel)
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
          map.animate(with: GMSCameraUpdate.setTarget(selectedMarker.position))
          DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
            map.animate(toZoom: 12)
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
              // Invoke onAnimationEnded() once the animation sequence completes
              onAnimationEnded()
            })
          })
        }
      }
    }
  }
}
  1. MapViewControllerBridgeonAnimationEnded প্রয়োগ করুন

onAnimationEnded ক্লোজার প্রয়োগ করুন যেখানে MapViewControllerBridge ContentView মধ্যে ইনস্ট্যান্টিয়েট করা হয়েছে। নিম্নলিখিত কোডটি অনুলিপি করুন এবং পেস্ট করুন যা zoomInCenter নামক একটি নতুন রাজ্য যোগ করে এবং এটি clipShape ব্যবহার করে ভিউ পরিবর্তন করে এবং zoomInCenter এর মানের উপর নির্ভর করে ক্লিপ করা আকৃতির ব্যাস পরিবর্তিত হয়

কন্টেন্টভিউ

struct ContentView: View {
  @State var zoomInCenter: Bool = false
  // ...
  var body: some View {
    // ...
    GeometryReader { geometry in
      ZStack(alignment: .top) {
        // Map
        let diameter = zoomInCenter ? geometry.size.width : (geometry.size.height * 2)
        MapViewControllerBridge(markers: $markers, selectedMarker: $selectedMarker, onAnimationEnded: {
          self.zoomInCenter = true
        })
        .clipShape(
           Circle()
             .size(
               width: diameter,
               height: diameter
             )
             .offset(
               CGPoint(
                 x: (geometry.size.width - diameter) / 2,
                 y: (geometry.size.height - diameter) / 2
               )
             )
        )
        .animation(.easeIn)
        .background(Color(red: 254.0/255.0, green: 1, blue: 220.0/255.0))
      }
    }
  }
}
  1. এগিয়ে যান এবং অ্যানিমেশন দেখতে অ্যাপ চালান!

9. SwiftUI এ একটি ইভেন্ট পাঠান

এই ধাপে, আপনি GMSMapView থেকে নির্গত ইভেন্টগুলি শুনবেন এবং সেই ইভেন্টটিকে SwiftUI-তে পাঠাবেন। বিশেষত, আপনি ম্যাপ ভিউতে একজন প্রতিনিধি সেট করবেন এবং ক্যামেরা মুভ ইভেন্টগুলি শুনবেন যাতে যখন একটি শহর ফোকাস করা হয় এবং ম্যাপ ক্যামেরা একটি অঙ্গভঙ্গি থেকে সরে যায়, তখন ম্যাপ ভিউটি আনফোকাস হয়ে যায় যাতে আপনি ম্যাপের আরও দেখতে পারেন।

SwiftUI সমন্বয়কারী ব্যবহার করুন

GMSMapView ইভেন্টগুলি নির্গত করে যেমন ক্যামেরার অবস্থান পরিবর্তন বা যখন একটি মার্কার ট্যাপ করা হয়। এই ইভেন্টগুলি শোনার ব্যবস্থা হল GMSMapViewDelegate প্রোটোকলের মাধ্যমে। SwiftUI একটি সমন্বয়কারীর ধারণা প্রবর্তন করে যা বিশেষভাবে UIKit ভিউ কন্ট্রোলারের প্রতিনিধি হিসেবে কাজ করার জন্য ব্যবহৃত হয়। সুতরাং, SwiftUI বিশ্বে, একজন সমন্বয়কারীকে GMSMapViewDelegate প্রোটোকল মেনে চলার দায়িত্বে থাকা উচিত। এটি করার জন্য, নিম্নলিখিত পদক্ষেপগুলি সম্পূর্ণ করুন:

  1. MapViewControllerBridge মধ্যে MapViewCoordinator নামে একটি সমন্বয়কারী তৈরি করুন

MapViewControllerBridge ক্লাসের ভিতরে একটি নেস্টেড ক্লাস তৈরি করুন এবং এটিকে MapViewCoordinator বলুন। এই ক্লাসটি GMSMapViewDelegate সাথে সঙ্গতিপূর্ণ হওয়া উচিত এবং MapViewControllerBridge একটি সম্পত্তি হিসাবে ঘোষণা করা উচিত।

MapViewControllerBridge

struct MapViewControllerBridge: UIViewControllerRepresentable {
  // ...
  final class MapViewCoordinator: NSObject, GMSMapViewDelegate {
    var mapViewControllerBridge: MapViewControllerBridge

    init(_ mapViewControllerBridge: MapViewControllerBridge) {
      self.mapViewControllerBridge = mapViewControllerBridge
    }
  }
}
  1. MapViewControllerBridgemakeCoordinator() প্রয়োগ করুন

এরপর, MapViewControllerBridge মধ্যে makeCoordinator() পদ্ধতিটি প্রয়োগ করুন এবং পূর্ববর্তী ধাপে আপনার তৈরি করা MapViewCoodinator এর একটি উদাহরণ ফেরত দিন।

MapViewControllerBridge

struct MapViewControllerBridge: UIViewControllerRepresentable {
  // ...
  func makeCoordinator() -> MapViewCoordinator {
    return MapViewCoordinator(self)
  }
}
  1. মানচিত্র দৃশ্যের প্রতিনিধি হিসাবে MapViewCoordinator কে সেট করুন

কাস্টম সমন্বয়কারী তৈরি করা হলে, পরবর্তী ধাপ হল ভিউ কন্ট্রোলারের ম্যাপ ভিউয়ের জন্য প্রতিনিধি হিসেবে সমন্বয়কারীকে সেট করা। এটি করার জন্য, makeUIViewController(context) এ ভিউ কন্ট্রোলার ইনিশিয়ালাইজেশন আপডেট করুন। পূর্ববর্তী ধাপ থেকে তৈরি সমন্বয়কারী প্রসঙ্গ বস্তু থেকে অ্যাক্সেসযোগ্য হবে।

MapViewControllerBridge

struct MapViewControllerBridge: UIViewControllerRepresentable {
  // ...
  func makeUIViewController(context: Context) -> MapViewController {
    let uiViewController = MapViewController()
    uiViewController.map.delegate = context.coordinator
    return uiViewController
  }
}
  1. MapViewControllerBridge এ একটি ক্লোজার যোগ করুন যাতে ক্যামেরা সরে যাবে ইভেন্টটি প্রচার করা যেতে পারে

যেহেতু লক্ষ্য হল ক্যামেরা মুভের সাথে ভিউ আপডেট করা, তাই একটি নতুন ক্লোজার প্রপার্টি ঘোষণা করুন যা MapViewControllerBridge মধ্যে একটি বুলিয়ান গ্রহণ করে যা mapViewWillMove নামে পরিচিত এবং MapViewCoordinator মধ্যে প্রতিনিধি পদ্ধতি mapView(_, willMove) এ এই বন্ধ করার আহ্বান জানান। gesture মানটি বন্ধে পাস করুন যাতে SwiftUI ভিউ শুধুমাত্র অঙ্গভঙ্গি-সম্পর্কিত ক্যামেরা মুভ ইভেন্টগুলিতে প্রতিক্রিয়া জানাতে পারে।

MapViewControllerBridge

struct MapViewControllerBridge: UIViewControllerRepresentable {
  var mapViewWillMove: (Bool) -> ()
  //...

  final class MapViewCoordinator: NSObject, GMSMapViewDelegate {
    // ...
    func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
      self.mapViewControllerBridge.mapViewWillMove(gesture)
    }
  }
}
  1. mapWillMove জন্য একটি মান পাস করতে ContentView আপডেট করুন

MapViewControllerBridge এ ঘোষিত নতুন বন্ধের সাথে, এই নতুন বন্ধের জন্য একটি মান পাস করতে ContentView আপডেট করুন। সেই বন্ধের মধ্যে, যদি সরানো ইভেন্টটি কোনও অঙ্গভঙ্গির সাথে সম্পর্কিত হয় তবে রাজ্য zoomInCenter false টগল করুন৷ এটি কার্যকরভাবে মানচিত্রটিকে সম্পূর্ণ দৃশ্যে আবার দেখাবে যখন মানচিত্রটি একটি অঙ্গভঙ্গির দ্বারা সরানো হয়।

কন্টেন্টভিউ

struct ContentView: View {
  @State var zoomInCenter: Bool = false
  // ...
  var body: some View {
    // ...
    GeometryReader { geometry in
      ZStack(alignment: .top) {
        // Map
        let diameter = zoomInCenter ? geometry.size.width : (geometry.size.height * 2)
        MapViewControllerBridge(markers: $markers, selectedMarker: $selectedMarker, onAnimationEnded: {
          self.zoomInCenter = true
        }, mapViewWillMove: { (isGesture) in
          guard isGesture else { return }
          self.zoomInCenter = false
        })
        // ...
      }
    }
  }
}
  1. এগিয়ে যান এবং নতুন পরিবর্তনগুলি দেখতে অ্যাপটি চালান!

10. অভিনন্দন

এই পর্যন্ত পাওয়ার জন্য অভিনন্দন! আপনি অনেক জায়গা কভার করেছেন এবং আশা করি আপনি যে পাঠগুলি শিখেছেন তা আপনাকে এখন iOS এর জন্য Maps SDK ব্যবহার করে আপনার নিজস্ব SwiftUI অ্যাপ তৈরি করতে দেয়৷

আপনি যা শিখেছেন

  • SwiftUI এবং UIKit এর মধ্যে পার্থক্য
  • কিভাবে UIViewControllerRepresentable ব্যবহার করে SwiftUI এবং UIKit এর মধ্যে সেতু করা যায়
  • স্টেট এবং বাইন্ডিং সহ ম্যাপ ভিউতে কীভাবে পরিবর্তন করবেন
  • একটি সমন্বয়কারী ব্যবহার করে কিভাবে মানচিত্র দৃশ্য থেকে SwiftUI এ একটি ইভেন্ট পাঠাতে হয়

এরপর কি?

  • iOS এর জন্য মানচিত্র SDK
    • iOS এর জন্য Maps SDK-এর অফিসিয়াল ডকুমেন্টেশন
  • iOS-এর জন্য SDK-এর স্থান - আপনার আশেপাশে স্থানীয় ব্যবসা এবং আগ্রহের জায়গাগুলি খুঁজুন
  • ম্যাপ-এসডিকে-ফর-আইওএস-নমুনা
    • GitHub-এর নমুনা কোড iOS এর জন্য Maps SDK-এর মধ্যে সমস্ত বৈশিষ্ট্য প্রদর্শন করে।
  • SwiftUI - SwiftUI-তে অ্যাপলের অফিসিয়াল ডকুমেন্টেশন
  • নিম্নোক্ত সমীক্ষার উত্তর দিয়ে আপনি যে বিষয়বস্তুকে সবচেয়ে বেশি উপযোগী মনে করবেন তা তৈরি করতে আমাদের সাহায্য করুন:

আপনি অন্য কোন কোডল্যাব দেখতে চান?

মানচিত্রে ডেটা ভিজ্যুয়ালাইজেশন আমার মানচিত্রের শৈলী কাস্টমাইজ করার বিষয়ে আরও মানচিত্রে 3D মিথস্ক্রিয়া জন্য বিল্ডিং

আপনি সবচেয়ে আগ্রহী কোডল্যাব খুঁজে পাচ্ছেন না? এখানে একটি নতুন সমস্যা সহ এটি অনুরোধ করুন