Jika Anda mengembangkan produk untuk pasar massal, maka kemungkinan besar orang dengan penglihatan rendah menggunakannya. Jika Anda berusaha membuat antarmuka yang ramah pengguna, maka Anda perlu melakukannya dengan nyaman untuk semua klien, termasuk orang-orang dengan penglihatan rendah. Saya pikir kita sering melupakannya. Dan sudah waktunya untuk memperbaikinya.

Saya memasukkan permintaan "pengiriman pizza" dalam pencarian di App Store, mengunduh 24 aplikasi pertama dan memeriksa aplikasi mana yang menyediakan antarmuka untuk orang-orang dengan penglihatan rendah.
2 dari 24 . Dan salah satu dari keduanya, tampaknya, melakukannya secara tidak sengaja: ketika ukuran font meningkat, seluruh antarmuka "mengambang" dan itu menjadi lebih sulit untuk digunakan. Menyedihkan.
550.000 orang menggunakan aplikasi Dodo Pizza iOS setiap bulan. Bahkan jika 1% dari pengguna kami memiliki font yang diperbesar, itu adalah 5500 orang yang tidak nyaman menggunakan aplikasi kami. Kami akan memperbaikinya.
Tambahkan Dukungan Tipe Dinamis
- Kami menggunakan gaya teks sistem dinamis alih-alih yang statis.
- Secara opsional, aktifkan tanda centang Font Sesuaikan Otomatis pada label di storyboard. Atau, jika label pada tombol atau dibuat melalui kode, kita ketuk parameternya
adjustsFontForContentSizeCategory
. - Kami mengajarkan antarmuka untuk meregangkan ke berbagai ukuran font:
- Kami menggunakan perhitungan otomatis ukuran sel di mana kami bisa.
- Di mana kami tidak bisa - kami mendapatkan pengaturan ukuran font saat ini dan menanggapi perubahan dalam metode traitCollectionDidChange
. - Kami mendapatkan antarmuka yang tidak mungkin digunakan.

Kami mengubah antarmuka sehingga dapat digunakan
Kami mundur dan mulai berpikir bagaimana melakukan semuanya dengan baik.
Gunakan tempat dalam menu dengan benar
Sekarang ada banyak ruang kosong di bawah gambar pizza. Mari kita coba letakkan gambar di atas namanya: dengan cara ini akan menjadi lebih besar, dan ruang kosong akan hilang. Untuk melakukan ini, kami membungkus gambar dan
UIStackView
wadah dengan yang lainnya di
UIStackView
, dan kemudian kami akan mengalihkan arah tampilan tumpukan jika perlu.

Kami tidak memiliki pemisah antara item menu, itulah sebabnya ketika ukurannya besar, sel-sel mulai "bersatu" dan label harga pizza terlalu dekat dengan gambar pizza berikutnya. Mari kita coba tambahkan pemisah.

Bukan itu. Pertama, terlihat begitu-begitu saja. Kedua, akan sulit untuk melihat orang dengan penglihatan rendah. Bahkan jika dicat ulang dari abu-abu menjadi hitam.
Kami menghapusnya kembali dan hanya mencoba meningkatkan Internet antar sel.

Nah sekarang.
Subtotal: gunakan lebih banyak ruang, mata melompat lebih sedikit dari garis ke garis, membaca menjadi lebih mudah.
Kami meningkatkan peregangan dan melepas
Sekarang Anda dapat menambah lebar tombol tambah ke keranjang, jika tidak melayang ke kiri dan tidak di bawah jari Anda, meskipun ada banyak ruang kosong di sebelah kanan. Anda tentu saja bisa, hanya memindahkannya ke sisi kanan, tetapi kemudian akan merepotkan bagi orang-orang kidal dan, secara umum, lebih baik daripada gerakan yang tidak terkompresi. Dan kami akan membuat stroke lebih gemuk, dan sekarang tidak konsisten dengan font.

Saya melihat semua ini dan mengerti bahwa foto pizza, tentu saja, sangat besar. Mari kita coba sembunyikan, mungkin tanpa gambar Anda bisa hidup.

Secara umum, menu tanpa foto tidak kehilangan banyak informasi, tetapi sekarang satu item menu hampir selalu mengganggu layar iPhone 6S. Tapi itu menjadi kurang menarik, Air liur tidak mengalir saat menggulir. Seperti itu Untuk saat ini, biarkan seperti ini, pikirkan dengan hati-hati dan mungkin nanti kembalikan fotonya.
Jangan lupa centang "langsung"
Sekarang kategori. Secara umum, bahkan dengan pendekatan pertama ternyata lumayan. Nyalakan yang baru.

Saya mencoba menelusuri menu dan beralih antar kategori. Namun demikian, ternyata buruk: semuanya berantakan dalam tindakan. Saat menggulir menu, kategori secara otomatis beralih, dan pada pin besar seperti itu menarik terlalu banyak perhatian.
Mari kita ganti
UICollectionView
dengan tombol yang akan memanggil
UIActionSheet
.

Voooot. Sekarang Anda dapat mengambil panel atas, di mana kota, stok, alamat dan kode promosi.
Jangan lupa tentang garis yang sangat panjang
Pertama, mari kita pilih kota. Tidak ada yang rumit dengan font di tombol, tetapi menarik untuk mengajarkan "segitiga" untuk tumbuh dengan font. Dalam kasus kami, segitiga dibuat ikon di tombol, yang dipindahkan ke sisi kanan melalui
CGAffineTransform
. Pilihan lain adalah mengumpulkan
NSAttributedString
dari teks dan ikon segitiga, dan kemudian mengumpankan semuanya ke tombol. Untuk menormalkan ikon, Anda dapat menggunakan gambar vektor, yang harus dalam aset dengan tanda centang Preserve Vector Data.

Ikon segitiga berwarna hitam, dan dicat putih melalui kode. Dan untuk beberapa alasan, dengan ukuran teks standar, keluar artefak dalam bentuk batas hitam. Itu lucu Tidak juga. Dia disembuhkan dengan meletakkan ikon yang awalnya putih di aset.
Sekarang kita meregangkan dodo-rubel, semuanya sederhana:

Dan sekarang pertanyaannya adalah: apa yang akan terjadi jika nama kota ternyata panjang dan kami memiliki banyak rubel dodo? Secara teori, Anda perlu mempersingkat nama kota. Ingat apa yang saya katakan tentang opsi kedua untuk menambahkan ikon seperti itu ke tombol, melalui
NSAttributedString
? Saya mencoba dan sekarang ada masalah bahwa ketika kita mengurangi judul, ikon segitiga juga menghilang, karena sekarang itu adalah bagian dari judul. Stosh. Kita harus mengembalikan logika memindahkan ikon melalui transformasi.
Jika Anda tahu cara mudah untuk memindahkan ikon di tombol ke sisi kanan dan skala bersama-sama dengan font di header - tolong buang di komentar.
Masuk
Akhirnya stok. Di sini Anda perlu duduk dan berpikir. Judulnya bisa panjang dan bahkan sekarang terkadang tidak muat pada satu baris. Pada ukuran besar, dia tidak akan cocok sama sekali. Jika Anda membuat karet panel oranye atas dan memungkinkan judul aksi dalam ukuran besar untuk menempati beberapa baris, maka blok atas akan memakan setengah layar bahkan pada iPhone besar, dan Anda tidak harus mengingat tentang 4S. Ini bukan masalahnya. Anda bisa bermain dengan tata letak di dalam kotak tindakan: buat kotak gambar, dan ambil tempat yang kosong sebagai tajuk. Tetapi gambar untuk stok disesuaikan dengan format tertentu dan tidak akan ditampilkan dengan benar di format lain. Ini tidak mungkin.
Rumit
Jadi, tetapi Anda dapat kembali menghapus gambar sepenuhnya dan mengambil seluruh tempat dengan judul.

Ya itu. Tangan gatal untuk mewarnai latar belakang di bawah judul tindakan, tetapi ini akan mempengaruhi keterbacaan. Dan kami, seperti, berusaha memperbaikinya. Jadi kami tidak melukis apa pun dan beralih ke dua tombol yang tersisa tentang alamat dan kode promosi.
Kami bekerja dengan batasan ketat
Judul pada tombol-tombol ini tidak dapat direduksi. Tetapi jika tidak dikurangi, maka tombol akan saling merayap. Dan ya, Anda tidak dapat menyembunyikan tombol-tombol ini.
Ketika saya redid stock, saya tidak ingin menambah ketinggian panel oranye atas. Sepertinya harus. Bagus bahwa mereka tidak menambahnya pada waktu itu, kalau tidak sekarang akan ada aduha. Secara umum, saya akan memilih satu baris untuk setiap tombol.

Ufff, itu dia. Adapun foto yang dimatikan dalam menu, saya masih tidak yakin. Atau, Anda hanya dapat menampilkan setengah gambar pizza daripada lingkaran keseluruhan, tetapi kami memiliki setengah pizza langsung pada menu, sehingga tidak akan berhasil, kami dapat membingungkan pengguna.
Mari kita bandingkan pendekatan pertama dengan hasil akhir:

Sekarang bandingkan "sebelum" dan "setelah" dengan simulasi penglihatan yang buruk:

Jangan takut untuk mengubah antarmuka dan kontrol. Tidak ada yang salah dengan seseorang melihat tombol lain atau, misalnya, slider. Dan tidak fatal jika seseorang tidak melihat sesuatu atau jika judulnya berbeda.
Dan kami tidak menyentuh UITabBarController
, karena dengan ukuran teks yang besar, itu keluar dari kotak pada keran panjang dapat menunjukkan ikon dan judul tab dengan cara yang sama seperti iOS menunjukkan perubahan volume.
Kami menunjukkan bagaimana semuanya bekerja di dalam
Setiap komponen UI logis dalam aplikasi iOS Dodo Pizza dialokasikan ke
UIViewController
terpisah. Setiap pengontrol tersebut memiliki
UIView
dialokasikan untuk file terpisah. Anda dapat membaca lebih lanjut tentang ini di artikel kami:
Kontroler, tenang saja! Kami mengeluarkan kode dalam UIViewPengontrol bawang. Kami memecah layar menjadi beberapa bagianMenghapus komponen UI logis ke dalam
UIViewController
terpisah
UIViewController
sangat menyederhanakan tugas memodifikasi antarmuka ke berbagai negara. Kami menyarankan Anda mencoba pendekatan ini, bahkan jika Anda tidak berencana untuk menambahkan dukungan untuk Jenis Dinamis - lebih mudah untuk mengontrol status layar: menanggapi perubahan otorisasi, hak, peran, dan sebagainya.
Jadi disini. Kami menambahkan lapisan tambahan antara komponen UI dan wadah induknya. Kami menyebutnya
StateViewController
.

Controller dengan menu mengintegrasikan state-controller, dan sudah menyematkan
collection
- atau
button
kontrol.
StateViewController
ini memperlihatkan komponen UI ini atau itu tergantung pada situasinya.
Untuk melakukan ini,
StateViewController
perlu tahu tentang statusnya dan mengubahnya jika perlu.
Dalam contoh ini,
StateViewController
akan mengaktifkan pemilihan kategori dalam menu dari koleksi ke tombol dan sebaliknya. Dan dalam hal tampilan "normal", dan dalam kasus tampilan untuk orang-orang tunanetra, pemilih harus dapat melakukan hal yang sama:
- Tampilkan daftar kategori.
- Sorot kategori yang dipilih.
- Perbarui daftar kategori.
- Laporkan bahwa kategori "keluar."
Rasakan aroma indah log kecil segar ini? Dan, tidak, ini adalah tim pizza api yang dikirimkan ponsel. 5 menit istirahat.
2 iris kemudian"... Yah, kita membungkus komponen kita seperti itu untuk memilih kategori dalam protokol, DAN MEREKA SEGERA!"
Petunjuk: Luncurkan Inspektur Aksesibilitas untuk dengan mudah memeriksa bagaimana antarmuka merespons perubahan dalam pengaturan ubin dinamis. Untuk melakukan ini, di Xcode terbuka, klik Xcode → Buka Alat Pengembang → Inspektur Aksesibilitas, pilih simulator di perangkat dan pergi ke tab terakhir
Petunjuk lain: keluarkan kontrol taip dinamo pada iPhone (bukan pada simulator) ke Pusat Kontrol untuk mengubah ukuran teks dengan mudah dan cepat. Untuk melakukan ini, pada iPhone, buka Pengaturan → Pusat Kontrol → Sesuaikan Kontrol dan tambahkan Ukuran Teks.
Kami memanggil selektor kategori biasa,
CategoriesCollectionViewController
, dan untuk tunanetra -
CategoriesButtonViewController
. Protokol umum mereka disebut
CategoriesPickerProtocol
. Pengontrol keadaan umum adalah
CategoriesStateViewController
.
Kami menjelaskan status yang mungkin ada di
CategoriesStateViewController
kami:
private enum State { case collection, button }
Kami mengajarnya untuk menunjukkan pengontrol yang diinginkan untuk setiap negara:
private var state: State = .collection { didSet { if state != oldValue { updateViewController(for: state) } } } private func updateViewController(for state: State) { let viewController = self.viewController(for: state) self.updateController(with: viewController) } private func viewController(for state: State) { switch state { case .collection: return CategoriesCollectionViewController.instantiateFromStoryboard() case .button: return CategoriesButtonViewController.instantiateFromStoryboard() } }
instantiateFromStoryboard()
- metode dari ekstensi yang ditulis sendiri ke view controller, membuat instance controller dari storyboard jika mereka memiliki nama yang sama. Kode tersebut ada dalam kode sumber di akhir artikel.
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) self.updateStateToCurrentContentSize() } private func updateStateToCurrentContentSize() { let contentSize = self.traitCollection.preferredContentSizeCategory self.updateState(to: contentSize) } private func updateState(to contentSize: UIContentSizeCategory) { self.state = contentSize.isAccessibilityCategory ? .button : .collection }
Kami menggambarkan protokol
CategoriesPickerProtocol
, secara bersamaan menambahkan dua protokol lagi: untuk delegasi dan untuk dataure.
protocol CategoriesPickerProtocol where Self: UIViewController { var datasource: CategoriesDatasource? { get set } var delegate: CategoriesDelegate? { get set } func select(_ category: ProductCategoryModule.ProductCategoryViewModel) func updateCategories() var selectedCategory: ProductCategoryModule.ProductCategoryViewModel? { get } } protocol CategoriesDatasource: class { var categories: [ProductCategoryModule.ProductCategoryViewModel] { get } func index(of category: Product.ProductCategory) -> Int } protocol CategoriesDelegate: class { func productCategoriesView(_ categoriesPicker: CategoriesPickerProtocol, didSelect category: ProductCategoryModule.ProductCategoryViewModel) }
Tidak ada gunanya menampilkan implementasinya, hanya saja setiap pengendara motor menampilkan kategori dan melaporkan perubahan ke atas.
Contoh terperinci menggunakan pengontrol keadaan untuk taype dinamis dapat ditemukan di
repo saya
di GitHub .
→
Omong-omong, kami berkembang