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 ক্লাউড প্ল্যাটফর্ম অ্যাকাউন্ট না থাকে এবং বিলিং সক্ষম করা একটি প্রকল্প থাকে, তাহলে একটি বিলিং অ্যাকাউন্ট এবং একটি প্রকল্প তৈরি করতে অনুগ্রহ করে 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. কোড পাওয়ার পর, starter/GoogleMapsSwiftUI ডাইরেক্টরিতে একটি টার্মিনাল cd
  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 অ্যাক্সেসযোগ্য করে তুলবে।

5. SwiftUI বনাম UIKit ব্যবহার করা

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

  • অবস্থা পরিবর্তন হলে ভিউ স্বয়ংক্রিয়ভাবে আপডেট হয়। স্টেট নামক বস্তু ব্যবহার করে, এতে থাকা অন্তর্নিহিত মানের যে কোনো পরিবর্তন UI স্বয়ংক্রিয়ভাবে আপডেট হবে।
  • লাইভ প্রিভিউ দ্রুত বিকাশ সক্ষম করে। লাইভ প্রিভিউগুলি Xcode-এ SwiftUI ভিউয়ের পূর্বরূপ হিসাবে দৃশ্যমান পরিবর্তনগুলি দেখতে একটি এমুলেটরে কোড তৈরি এবং স্থাপন করার প্রয়োজনীয়তাকে কমিয়ে দেয়।
  • সত্যের উৎস সুইফটে। 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 কী যোগ করুন

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

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

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

এখন যেহেতু আপনার এপিআই কী 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 এর মধ্যে MapViewControllerBridge এর প্রথম চাইল্ড ভিউ হিসেবে একটি ZStack তৈরি করুন যাতে অ্যাপে শহরের দৃশ্যের তালিকার পিছনে একটি মানচিত্র প্রদর্শিত হবে। এটি করার পরে, 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 নামে একটি সম্পত্তি ঘোষণা করে যা GMSMarker এর একটি তালিকা যা cities স্ট্যাটিক সম্পত্তিতে ঘোষিত প্রতিটি শহরের প্রতিনিধিত্ব করে। লক্ষ্য করুন যে এই সম্পত্তিটি 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
  }

লক্ষ্য করুন যে কন্টেন্টভিউ শহরের CitiesList ContentView পাস করার জন্য 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)
      }
    }
  }
}

বাইন্ডিংয়ের মাধ্যমে MapViewControllerBridge-এ রাজ্য পাস করুন

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

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

MapViewControllerBridge

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

পূর্ববর্তী ধাপে উল্লিখিত হিসাবে, যখনই অবস্থা পরিবর্তন হবে তখনই SwiftUI দ্বারা updateUIViewController 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. MapViewControllerBridge থেকে ContentView পর্যন্ত markers সম্পত্তি পাস করুন

যেহেতু আপনি MapViewControllerBridge এ একটি নতুন প্রপার্টি যোগ করেছেন, তাই এখন এই প্রপার্টির মানটি MapViewControllerBridge এর ইনিশিয়ালাইজারে পাস করতে হবে। সুতরাং, আপনি যদি অ্যাপটি তৈরি করার চেষ্টা করেন তবে আপনার লক্ষ্য করা উচিত যে এটি কম্পাইল হবে না। এটি ঠিক করতে, ContentView যেখানে 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 এই অবস্থার পরিবর্তন সম্পর্কে সচেতন হওয়া উচিত যাতে এটি নির্বাচিত মার্কারে মানচিত্রটিকে অ্যানিমেট করতে পারে। সুতরাং, MapViewControllerBridge টাইপের GMSMarker এর মধ্যে একটি নতুন বাইন্ডিং সংজ্ঞায়িত করুন এবং 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. MapViewControllerBridge-এ ContentView এর selectedMarker MapViewControllerBridge পাস করুন

একবার 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 অ্যানিমেশন আপনার পূর্বে যোগ করা ম্যাপ অ্যানিমেশন সিকোয়েন্সের পরে সঞ্চালিত হবে, তাই onAnimationEnded মধ্যে MapViewControllerBridge নামে একটি নতুন বন্ধ ঘোষণা করুন এবং 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. onAnimationEnded এ Animation Ended এ MapViewControllerBridge

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. MapViewCoordinator মধ্যে MapViewControllerBridge নামে একটি সমন্বয়কারী তৈরি করুন

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

MapViewControllerBridge

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

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

এরপর, MapViewControllerBridge-এর মধ্যে 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-এর মধ্যে একটি বুলিয়ান গ্রহণ করে যা MapViewControllerBridge নামে পরিচিত এবং mapViewWillMove এর মধ্যে প্রতিনিধি পদ্ধতি mapView(_, willMove) MapViewCoordinator এই বন্ধ করার আহ্বান জানান। 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-এর জন্য একটি মান পাস করতে mapWillMove আপডেট করুন

ContentView MapViewControllerBridge করুন। সেই বন্ধের মধ্যে, যদি সরানো ইভেন্টটি কোনও অঙ্গভঙ্গির সাথে সম্পর্কিত হয় তবে রাজ্য 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-এর জন্য Maps SDK - iOS- এর জন্য Maps SDK-এর অফিসিয়াল ডকুমেন্টেশন
  • iOS-এর জন্য SDK-এর স্থান - আপনার চারপাশে স্থানীয় ব্যবসা এবং আগ্রহের জায়গাগুলি খুঁজুন
  • maps-sdk-for-ios-samples - GitHub-এর নমুনা কোড iOS এর জন্য Maps SDK-এর মধ্যে সমস্ত বৈশিষ্ট্য প্রদর্শন করে৷
  • SwiftUI - SwiftUI-তে অ্যাপলের অফিসিয়াল ডকুমেন্টেশন
  • নীচের প্রশ্নের উত্তর দিয়ে আমাদেরকে এমন সামগ্রী তৈরি করতে সাহায্য করুন যা আপনি সবচেয়ে দরকারী বলে মনে করবেন:

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

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

আপনি যে কোডল্যাব চান তা কি উপরে তালিকাভুক্ত নয়? এখানে একটি নতুন সমস্যা সহ এটি অনুরোধ করুন