Kata Pengantar
Halo teman-teman , pada awalnya saya akan segera menguraikan tujuan artikel:
menghemat waktu Anda jika Anda perlu
memperbarui atau menyematkan peta Yandex di klien seluler iOS Anda, ditambah keinginan untuk berbagi pengalaman Anda.
Kami pernah membangun aplikasi YandexMapkit (sekitar Oktober 2017) alih-alih kartu email (bukan pribadi - hanya bisnis). Setelah sekitar 3 bulan, pada hari musim dingin yang indah, kartu versi Androyd menjadi rusak pada hari ke-2 karena kunci, kartu hanya berubah menjadi labu). Apa tip dari manual: "Pada android kartu rusak, mereka tidak tahu cara memperbaikinya" Pada saat itu sebagai klien iOS, ini tidak mempengaruhi. Orang miskin di android ... kali ini orang-orang itu tidak ada hubungannya. Pada masa itu
, banyak penginapan jatuh : jabatan Rusia, Platypus, mungkin kalian ingat?

Ini untuk mengatakan bahwa ketika aplikasi Anda terikat ke layanan pihak ketiga, alangkah baiknya jika Anda memiliki rencana "B" untuk kasus ini, misalnya, beralih ke versi kartu yang sebelumnya dari Apple, dan tidak mengganti satu sama lain ...
Setelah 3 bulan berikutnya, di suatu tempat di bulan Maret, sebuah surat tiba dari Yandex bahwa mereka akhirnya memperbarui SDK, (sangat sedikit waktu telah berlalu, 4-5 tahun dari pembaruan sebelumnya):
"-Perbarui, matikan yang lama dalam setahun," singkatnya. Sebelum itu, hanya ada versi lama 1.0

Yah, tentu saja, setelah peringatan seperti itu, kami tidak menarik dan segera memulai transisi ... setelah 3 bulan)) pada bulan Agustus.
Tahap "berkomentar"! (Menonaktifkan fungsi)
Anda berkata, ha ... apa yang diperbarui di sana, pod diperbarui, diperbaiki beberapa tempat dan itu saja. Jadi tidak, teman-teman, API peta baru sama sekali tidak kompatibel dengan yang lama, dan terlebih lagi, ternyata kemudian, bahkan ada banyak kebutuhan vital yang tidak tersedia di versi lama dan perpustakaan kartu lainnya!
Jadi, mapkit 3.0 (saat menulis artikel versi 3.1 dirilis),
tautan ke dokumentasi .
Dan mengapa selain peringatan dari Yandex? Sementara itu, pada versi beta Xcode 10, sebuah proyek dengan paus tua tidak akan melakukannya dengan bodoh, karena C ++ digunakan di suatu tempat di dalam, yang dihilangkan dalam versi baru. Perlu untuk mengubah nama di sub-daftar, bahkan memperbaruinya di sana, dll, singkatnya, saya tidak melakukan ini, karena pada akhirnya saya masih perlu memperbarui
1) Kami memperbarui SDK, bukan versi 1.0 segera 3.0, tentu saja API telah berubah, tetapi begitu banyak ....
Jadi Protokol Catatan YMKA yang lama hilang begitu saja

Dalam gerakan cepat, itu terlihat seperti batang yang dipalsukan secara paksa (: itu tidak berdengung, dan kemudian Anda berkeliling membawa tanda "!" Ke diri sendiri ... Contoh implementasi protokol:

Baiklah, mari kita tulis kembali) milik kita sendiri, hanya alih-alih metode koordinat () kita akan membuat propertinya, semuanya sederhana, metode ini berlebihan; judul! () diganti dengan judul yang belum terbentuk (), di sisi lain, Anda dapat membuat properti, well, ada banyak tempat Anda harus mengubah proyek, jadi saya baru saja menghapus tanda seru.
Dalam proyek kami, perlu untuk mengganti 3 pengendali beberapa kali, mengimpor CoreLocation di yang lain, karena sekarang tidak diimpor di salah satu header Yandex MapPocket.
Agar tidak mengubah nama YMKMapCoordinate (paus lama) yang sudah dikenal sepanjang proyek, buatlah typealias untuk YMKPoint (paus baru)

2) Juga, mari deklarasikan beberapa properti yang akan kita perlukan di masa depan untuk bekerja dengan peta, terutama pengambil:

3) Hal pertama yang harus dibuat adalah YMKMapView (semuanya baik-baik saja dengan itu, objek seperti itu masih tersedia). Sebelumnya, saya langsung menginisialisasi, sekarang Anda tidak dapat melakukan ini, itu akan macet, karena pertama-tama Anda harus meletakkan kunci! Kunci saat ini tidak akan berfungsi dan Anda perlu meminta yang baru. Tambahkan ke AppDelegate, sesuai dengan dokumentasi. Hanya setelah mengatur kunci, dapatkah kita membuat YMKMapView dan mengkonfigurasinya dengan cara yang kita butuhkan dalam metode setupMap ()

Apa yang terjadi di sini, kami akan menganalisis secara rinci nanti dalam rangka kebutuhan untuk pengaturan yang sesuai
4) Apa selanjutnya?, Dan kemudian kami memiliki lokasi awal CLLocation, tetapi sekarang untuk menggunakannya Anda perlu menambahkan kerangka kerja CoreLocation secara manual, atau ... atau menggantinya dengan YMKPoint dari mapkit Yandex

5) Selanjutnya, peta dipusatkan pada koordinat ini dengan metode yang sangat sederhana, tetapi sekarang tidak ada yang sederhana

Tetapi ada sedikit lebih rumit dan sedikit lebih dalam, objek peta) ... mapView.mapWindow.map! .Move. Di sini kita belajar tentang keberadaan objek seperti YMKCameraPosition.

6) Selanjutnya, kami mengomentari konfigurasi peta, karena tidak ada api / properti seperti itu. Sekarang kita hanya menghilangkannya untuk memulai setidaknya secara minimal.
Kami berkomentar tentang menambahkan anotasi, (Saya akan memperhatikan bahwa ini adalah fungsi standar), kami juga mengomentari untuk menunjukkan poin terdekat (ini sudah semacam fungsi kami).
Dan keseluruhan YMKMapViewDelegate juga merupakan komentar, yang tidak saya temukan dalam kerangka kerja baru, dan analog yang serupa juga.

Saya mengabaikan implementasinya, hanya metodenya sendiri:
- apakah akan menampilkan lokasi pengguna,
- tampilan yang digunakan untuk pin,
- Reaksi untuk mengklik anotasi,
- info apa untuk anotasi,
- Reaksi terhadap mengklik callout, yaitu, semua yang biasa kita gunakan. Pada akhirnya, ada beberapa jenis metode kami, yang juga menggunakan kartu API tertentu.
SEGALA SESUATU tahu dengan MapVC - ini adalah kelas utama di mana mapkit digunakan
7) Sedikit komentar tentang info khusus, itu tidak akan mewarisi YMKCalloutView lagi, tidak ada lagi di paus baru.
Hore, sekarang proyek telah berkumpul, saya dapat memulai segalanya dan ... melihat buku catatan di dalam kotak, karena setelah dimulai, Anda perlu memberi waktu untuk "pemanasan")), tetapi saya tidak tahu tentang hal itu dan berpikir bahwa ada sesuatu yang tidak jadi, meskipun saya menyarankan agar perlu waktu untuk mengaktifkan kunci. Ternyata anggapan itu benar. Anda perlu menunggu sekitar satu jam (mungkin sesuatu telah berubah sekarang).
Dengan upaya lain untuk memodifikasi api lama dengan cara baru, peta ditampilkan.
Tahap dua - "pencarian" (bagaimana menerapkan fungsi lama dengan cara baru)
Mari kita mulai mengembalikan fungsionalitas yang hilang. Jadi, Anda perlu menampilkan kunci pengguna, tetapi dengan cara lama hanya mengubah properti dan pengaturan delegasi tidak dapat dilakukan.
Sekarang ini dilakukan melalui layer, lihat metode setupMap () poin 3.
Kami akan melihat contoh di demo (
unduh dari Yandex github ), karena ada di sana. Ngomong-ngomong, Anda harus memperhatikan setAnchorWith. Nanti saya akan bilang kenapa, itu terkait dengan zoom. Ok lokasi berhasil.
2) Apa selanjutnya, tentu saja, penjelasan. Anda tidak dapat menambahkan dengan cara lama, kami melihat dalam demo lagi. Ada kelas di sana - MapObjectsViewController. Di versi baru, untuk menambahkan pin ke peta, delegasi tidak diperlukan, untuk ini Anda perlu mengakses properti mapObjects, memanggil metode addPlacemark pada objek, dan meneruskan koordinat di sana (masih ada kelebihan lainnya) Contoh:

Kami beralih pada koleksi anotasi (misalnya, setelah menerima dari server) dan menambahkan satu ke peta. Metode, omong-omong, mengembalikan "placeMark" (label tempat), yang dapat digunakan untuk membuat pengaturan tambahan, misalnya, mengubah urutan tampilan melalui properti zIndex.
Namun, di sini, saya kehilangan poin bahwa sebelum itu saya naik ke pencarian untuk delegasi dan tidak menemukannya dengan aman, dan tidak ada satu pun delegasi sama sekali (pada kenyataannya, mereka hanya mulai dipanggil secara berbeda, sekarang mereka adalah pendengar). Saya tahu dari pengalaman sebelumnya dengan paus Apple dan paus Yandex lama bahwa anotasi digunakan kembali, seperti halnya dengan sel, tetapi hanya ada addPlacemark di demo. Untuk pertanyaan tentang kartu Yandex-cards (seorang kenalan pribadi kecil membantu di sini) "- Bagaimana mengoptimalkan penggunaan memori, menggunakan kembali benda-benda?" Jawab: "Ya, jadi itu bekerja dengan baik" ... yah, semacam ya, itu bekerja.
Catatan: 1) Penting untuk dicatat bahwa Yandex.Maps menggunakan mapkit, dan jangan mengembangkannya. Ini dilakukan oleh tim mapkit (nama panggilan Nikolai di hub - likhogrud @).
2) Penjelasan mengapa objek tidak digunakan kembali:
Di paus lama, annotationViews adalah view, mereka dibuat oleh pengguna, dan tentu saja view perlu digunakan kembali, karena membuatnya tidak murah. Pada paus baru, tanda letak dibuat oleh mapkit langsung di GL terbuka. Dan mungkin mereka digunakan kembali di sana, tetapi ini tidak akurat. Bagaimanapun, ini jauh lebih efisien daripada menciptakan tampilan.
3) Dari yang baru, ngomong-ngomong, ada kemungkinan memodifikasi ikon anotasi untuk pengguna. Diimplementasikan sebagai berikut: Anda perlu menambahkan pendengar (analog dari delegasi), menerapkan protokol yang sesuai - 1 dari 3 metode, 2 biarkan kosong.
Pada saat yang sama, muat ulang tanda letak dengan ikon kami.

Juga, saya menarik perhatian Anda ke properti jangkar. Setelah menekan tombol lokasi pengguna di peta, kamera memindahkan fokus ke pusat lokasi. Tetapi masalahnya adalah, menekan tindakan lagi tidak menghasilkan. Apa? Kami mengomentari metode jangkar dan semuanya berfungsi.
4) Sekarang Anda harus menampilkan info, masing-masing, untuk menentukan klik. Ada beberapa metode di antarmuka, yang benar adalah YMKMapObjectTapListener. Ada 1 metode menarik yang penting yang harus saya siksa sendiri nanti, itu mengembalikan true agar tidak berintegrasi lebih lanjut jika pelanggan ditemukan. Saya menarik perhatian Anda, Anda harus berlangganan terlebih dahulu, mapObjects akan berlangganan (baris 149).


Jadi klik memenuhi.
Hore . Namun, ada upaya untuk menampilkan pin hanya di zona yang terlihat, ini berlebihan, tampilkan semuanya sekaligus, jadi mari kita tinggalkan (hanya karena tidak memperlambat)
5) Lalu saya ingin membuat tombol zoom in / out untuk kenyamanan. Sedikit salin-tempel dan edit dengan analogi dengan tombol lokasi, dan Anda selesai.
Lebih lanjut, karena kita tahu tentang kamera, menggunakan metode bergerak dan, karenanya, zoom saat ini + - 1 atau 0,5, sesuai kebutuhan. Semuanya baik-baik saja di sini.

6) Kami beralih ke fungsi - panggilan utama (ini adalah persegi panjang dengan info tambahan, dengan segitiga di bagian bawah). Ternyata tidak ada API ("memabukkan di musim panas" - Yandex mengenali pidato saya ketika saya membaca catatan dari selebaran agar tidak mengetik secara manual artikel ini).

Bagaimana kabar kalian 100 500 aplikasi menggunakan info.
Kami menulis dengan baik di "dukungan teknis" (Kolya) bagaimana melakukan ini secara manual, saya mengetahuinya. Apa saja pilihanmu?
Ubah tampilan menjadi gambar, karena Anda tidak dapat langsung menambahkan tampilan (menambahkan file dalam 3.1), ubah ikon ...

Kruk ini didapat di sebuah flat, sepertinya tempatnya.
Bahkan, bukan kruk, tentu saja, tetapi hanya ketidakhadiran saya mempertimbangkan fungsi dasar
7) Oke, mari kita tambahkan testout terlebih dahulu, karena itu kita menggunakan kotak merah. Jadi, dengan mengklik pin kami, metode delegate / listener dipanggil, di mana titik klik dan objek ditransfer. Tanpa mengharapkan trik, kami menganggap "titik" sebagai titik di mana Anda ingin menambahkan info. (Perhatian, apakah semuanya dilakukan dengan benar: "Mereka mengklik, mengambil poin, mengikatnya?" Sekitar 80% menjawab dengan benar, 20% - tidak)

Dan panggil metode bantuan showCallout di tubuh metode:

baris 544
Di dalam, buat tampilan uji warna merah empat puluh kali empat puluh, ubah menjadi gambar, nyatakan konstanta x dengan nilai 0,5, itu akan digunakan untuk posisi segitiga info di tengah titik. Dia menolak ide untuk mengubah posisinya, kemudian lebih suka memindahkan kamera sehingga info yang dipilih ditampilkan di tengah layar ponsel.
Selanjutnya, kita mendeklarasikan area "push" dari tappableArea, ada properti seperti itu dalam gaya ikon untuk pin. Oh well, Anda dapat membatasi zona klik, dan kami akan melakukannya. Zona tersebut berkisar dari 0,0 hingga 1,1. kita perlu bagian bawah, di mana seharusnya ada tombol yang diubah menjadi gambar sebelumnya (ingat). Oke, ini artinya zona (0,0.5 - 1.1) karena tombolnya di bawah.
Pembatasan zona berfungsi, tetapi ada nuansa, sehingga meniadakan segalanya. Jika ada pin lain di bawah area yang tidak ditekan, maka menekan akan berhasil. Arti dari daerah ini? Apakah mereka akan membuat bendera atau sesuatu sehingga klik tidak lulus. Oke ...
550 baris
mari kita buat gaya untuk ikon, Anda dapat segera menentukan posisi jangkar di parameter pertama, misalnya, saya lakukan di bawah pada baris 557. Posisi y adalah 1,05 untuk menaikkan segitiga di atas pin lagi secara vertikal
559 baris
buat info khusus kami dengan ukuran tertentu,
kami mengonfigurasi bidang yang kami perlukan menggunakan informasi dari anotasi yang dipilih terpilih Anotasi, khususnya judul dan sub-judul, tulisan pada tombol untuk info ini. Maka Anda sendiri dapat melakukan apa yang Anda inginkan. Anotasi yang dipilih ditentukan sebelumnya dalam delegasi. Tetapi untuk sekarang, tambahkan kotak merah yang dibuat sebelumnya
Selanjutnya, tambahkan pin ke koleksi mapObjects, metode ini akan mengembalikan tanda letak yang ditambahkan kepada kami, simpan dalam variabel,
Dengan mengklik pada callout itu sendiri, controller yang terperinci terbuka, dan begitu nuansanya, jika di bawah popup pin lain juga masuk ke dalamnya, delegasi akan bekerja lagi, jadi di sini Anda perlu mengubah urutan dalam hierarki melalui zIndex. Atur visibilitas dan pindahkan info kami ke pusat di saluran 564
Nuansa : Tanda letak variabel adalah pointer ke info.
Pada awalnya kami tidak memilikinya, setelah mengklik pin, tampaknya, setelah mengklik pada pin berikutnya, kami perlu menghapus info pertama kami dan menambahkan yang baru. Karenanya, jika tanda letak variabel! = Nihil, Anda harus menghapus info lama dari koleksi mapObjects)

Juga, dalam kasus tapas pada kartu, Anda perlu menyembunyikan info, jadi dalam metode delegasi kami menetapkan tanda letak, pengamat berfungsi, info tersebut dihapus, ditambah kami menghapus anotasi yang dipilih
Untuk ini, kami mendaftar untuk YMKMapInputListener sebelumnya

Pada gilirannya, metode untuk mengonversi tampilan adalah sebagai berikut. (Dalam versi 3.1, menambahkan kemampuan untuk menambahkan tampilan ke peta)
Saya tidak menjelaskan cara melakukan tampilan), tetapi jika akan ada banyak masalah (dimungkinkan dengan segitiga) dengan ini, maka tulis, saya akan menambahkan tahap ini

Magic 20 yang ditambahkan pada ketinggian diperlukan untuk tempat di bawah segitiga di bawah ini, yang harus Anda gambar
Kami juga ingin popup muncul (dilampirkan) ke pin di tempat tertentu (kiri, kanan, di tengah), untuk ini ada properti jangkar. Didefinisikan sebagai berikut:
Kami membagi area yang terlihat dari peta menjadi 3 zona vertikal dan menentukan di mana kita berada, tergantung pada ini, mengubah posisi penjilidan. Dalam contoh kode, kita memeriksa apakah kita berada di sisi kiri, dengan analogi yang kita lakukan untuk tengah, jika tidak kiri dan tidak di tengah, masing-masing, titik di kanan adalah

Fungsi pembantu untuk memeriksa apakah suatu titik jatuh ke suatu wilayah:

Mulai. Itu bekerja. Tapi ada nuansa, sepertinya kita mencoba untuk memperbesar, satu, dua, tiga, dan info terbang menjauh dari pin. Apa? Bagaimana?

7) Kami mulai men-debug, koordinatnya sama

Kemudian ada upaya untuk memahami apa yang terjadi dan bagaimana cara kerjanya, kembali lagi ke demo, pencarian perbedaan yang lebih penuh perhatian ...

Saya perhatikan bahwa koordinatnya ditransmisikan secara langsung, dan bukan yang disadap! Tapi saya debazed, jelas bahwa koordinatnya sama, yaitu lingkaran dan bujur sangkar memiliki koordinat yang sama.
Itu sebabnya dalam metode ini saya tidak langsung mengakses objek, tetapi melewati titik, yang tidak benar.

Tetapi apakah Anda perlu melemparkan objek, mengambil properti (di mana semuanya disebut berbeda, lalu berkoordinasi, lalu menunjuk, di sini sekarang geometri) apakah ini kreatif atau apa? 493 baris

Karena kita perlu memproses dua opsi pengepresan: yang pertama untuk pin, yang kedua untuk callout, dan tidak untuk memproses klik jika kita mengklik pada pin yang sama lagi, hal
pertama yang kita lakukan adalah menemukan pin yang kita klik pada koleksi pin, membandingkan mengkoordinasikan 495 baris, jika tidak mengembalikan true, dengan demikian mengatakan bahwa kami memproses klik dan tidak perlu melangkah lebih jauh dalam hierarki
Kedua : kami menentukannya dengan mengeklik pin atau pada info, kami juga akan membandingkan koordinat 499 label garis. Tes Kesetaraan:
Selanjutnya, jika ini adalah info dan kami ingin menanggapi klik tombol (atau mensimulasikan, karena sekarang ini adalah gambar), dan bukan ke seluruh area, maka kami perlu membuat beberapa perhitungan dengan pena :)
- Konversi koordinat dunia ke layar 501 baris
Kami menganggap diri kami: kami akan mengonversi koordinat peta ke layar, kami tahu di mana kami berada, kemudian dengan menambahkan lebar dan tinggi tampilan, kami mendapatkan titik sudut, tetapi karena alasan tertentu mereka tidak cocok dan saya secara manual dikalikan tiga, dalam kasus saya untuk iPhone ke 10)). Ternyata kemudian, saya lupa dan tidak memperhitungkan jumlah piksel per titik. Yang kita dapat memiliki 1x, (satu titik 1 piksel), 2x, 3x satu titik adalah tiga piksel. - Mari kita menghitung ketinggian tombol - tinggi info + ketinggian segitiga dikalikan skala, informasi tentang skala (baris 498). Selanjutnya, kami membagi semua ini menjadi dua, karena ketinggian tombol adalah setengah tinggi dari info
- Kemudian kita menghitung koordinat sudut, berdasarkan fakta bahwa jangkar (x: 0,5, y: 1), mengingat skala dan luas segitiga))
- Kemudian konversi koordinat layar ini ke dunia
- Buat area yang terlihat berdasarkan pada mereka, adalah zona tombol
- Dan kami memeriksa apakah kami menekan tombol zona atau tidak. Jika Anda menekan, maka periksa jenis anotasi, tergantung pada jenis yang kami sebut beberapa metode kami: pergi ke layar terperinci atau pilih toko ini untuk pengiriman dalam kasus dengan StorePoint
Kalau tidak, itu adalah klik pada pin dan kita perlu menambahkan info, yang sebenarnya kita lakukan di atas.
Itu saja, pada perkenalan awal dengan paus baru ini sudah berakhir.
Apa lagi yang ingin saya katakan, dalam implementasi peta mapkit saat ini mengandung banyak fungsi yang tidak digunakan, ini juga mempengaruhi ukuran biner yang dihasilkan. Apakah Anda siap untuk pengorbanan seperti itu, di masa depan, orang-orang harus dibongkar menjadi modul . Saya juga mendengar dari rekan kerja di android dari bengkel bahwa ada masalah kompatibilitas dengan Kotlin.
P.S. Sementara saya memutuskan dan mulai menulis artikel, pembaruan 3.1 keluar, di mana dari masalah di atas diselesaikan dan diimplementasikan:
Ditambahkan
Untuk Android, arm64 dan x86 build muncul.
Anda dapat menambahkan objek View apa saja ke peta.
Perutean sepeda telah muncul.
Menambahkan anotasi yang dapat dibatalkan untuk Android.
Berubah
MapKit dipecah menjadi beberapa bagian:
MapKit - hanya peta;
Arah MapKit - perutean mobil;
Transportasi MapKit - rute pejalan kaki, rute angkutan umum, dan rute sepeda;
Pencarian MapKit - pencarian dan geocoding;
MapKit Places - panorama.
Untuk iOS, anotasi yang dapat dibatalkan menjadi lebih ketat.
Diperbaiki
Sejumlah bug telah diperbaiki.
Peningkatan kinerja.
tech.yandex.ru/maps/doc/mapkit/3.x/concepts/versions-docpageTulis komentar, pertanyaan Anda.