BoxView - pembayaran otomatis praktis untuk iOS

Saya ingin berbagi perpustakaan untuk secara efisien membangun antarmuka pengguna untuk aplikasi iOS berdasarkan autolayout.



Meskipun dengan munculnya SwiftUI, relevansi autolayout dengan cepat berkurang, sementara mekanisme ini masih digunakan secara aktif, dan perpustakaan dapat bermanfaat bagi mereka yang membuat (atau mengubah) UI langsung dalam kode.



Cara membangun antarmuka ini memiliki sejumlah kelemahan yang membatasi penggunaannya:



  • Pembuatan elemen NSLayoutConstraint sangat merepotkan.
  • Visibilitas yang buruk - melihat kode sulit untuk memahami bagaimana tampilan UI.
  • Banyak kode rutin. Untuk menempatkan setiap tampilan membutuhkan penciptaan rata-rata sekitar 3 kendala, yaitu tiga baris dari jenis kode yang sama.
  • Kesulitan menciptakan antarmuka yang berubah secara dinamis: diperlukan untuk menyimpan batasan dalam variabel yang terpisah sehingga Anda dapat mengubahnya nanti, dan juga sering membuat kendala yang berlebihan dan "mematikan" yang tidak perlu.


Masalah pertama mudah diselesaikan dengan membungkus metode standar untuk menciptakan kendala menjadi sesuatu yang lebih manusiawi. Dan itu sudah diterapkan dengan baik, misalnya, di SnapKit , TinyConstraints dan perpustakaan serupa lainnya.



Tetapi Anda masih harus menulis banyak jenis kode yang sama, dan masih ada masalah dengan visibilitas dan perubahan dinamis pada tata letak. UIStackView menyelesaikan masalah ini dengan anggun, tetapi sayangnya, UIStackView memiliki kustomisasi yang sangat terbatas pada pengaturan elemen individual. Oleh karena itu, muncul ide tentang wadah UIView yang mengontrol tata letak tumpukan subview-nya, tetapi dengan kemampuan untuk menyesuaikan secara individual lokasi setiap subview.

Pendekatan inilah yang mendasari BoxView, dan telah terbukti sangat efektif. BoxView memungkinkan Anda untuk hampir sepenuhnya menghilangkan kendala pembuatan manual, hampir seluruh antarmuka pengguna dibentuk sebagai sistem BoxViews bersarang. Akibatnya, kode menjadi lebih pendek dan lebih jelas, manfaatnya terutama terlihat untuk UI dinamis.



BoxView dalam banyak hal mirip dengan UIStackView standar, tetapi menggunakan aturan yang berbeda untuk penempatan subview: di dalamnya Anda dapat mengatur indentasi dan ukuran untuk setiap subview secara individual. Untuk membuat tata letak, BoxView menggunakan larik BoxItems, yang berisi semua tampilan yang perlu ditampilkan, dan informasi tentang cara mengaturnya. Dan ini tidak memerlukan banyak kode sama sekali - sebagian besar parameter tata letak diambil secara default, dan hanya nilai yang diperlukan yang ditentukan secara eksplisit.



Properti penting dari BoxView adalah bahwa ia hanya menciptakan batasan yang ditentukan untuk subview yang ditambahkan, dan tidak ada yang lain. Oleh karena itu, dapat digunakan tanpa batasan dalam hubungannya dengan pustaka dan metode tata letak lainnya.



Sebagai contoh, pertimbangkan membuat form login sederhana menggunakan BoxView (Kode contoh lengkap dengan deskripsi langkah-demi-langkah tersedia di proyek BoxViewExample di github ).



gambar


Untuk membuat tata letak seperti itu di BoxView, beberapa baris kode sudah cukup:



        nameBoxView.items = [nameImageView.boxed.centerY(), nameField.boxed]
        passwordBoxView.items = [passwordImageView.boxed.centerY(), passwordField.boxed]
        boxView.insets = .all(16.0)
        boxView.spacing = 20.0
        boxView.items = [
            titleLabel.boxed.centerX(padding: 30.0).bottom(20.0),
            nameBoxView.boxed,
            passwordBoxView.boxed,
            forgotButton.boxed.left(>=0.0),
            loginButton.boxed.top(30.0).left(50.0).right(50.0),
        ]


BoxItem dibuat dari UIView apa pun menggunakan variabel kotak, setelah itu dapat diatur ke padding pada 4 sisi, perataan, dan ukuran absolut atau relatif.



Setiap elemen tata letak dapat ditambahkan dan dihapus secara bebas (termasuk dengan animasi) tanpa memengaruhi penempatan sisanya. Sebagai contoh, mari tambahkan cek untuk bidang input kosong dan, jika terjadi kesalahan, kami akan menampilkan pesan langsung di bawah bidang kosong:



gambar


Dan meskipun pesan tersebut harus "mengintegrasikan" ke tata letak yang ada, Anda bahkan tidak perlu mengubah kode yang ada untuk ini!



    func showErrorForField(_ field: UITextField) {
        errorLabel.frame = field.convert(field.bounds, to: boxView)
        let item = errorLabel.boxed.top(-boxView.spacing).left(errorLabel.frame.minX - boxView.insets.left)
        boxView.insertItem(item, after: field.superview, z: .back)
        boxView.animateChangesWithDurations(0.3)
    }
    
    @objc func onClickButton(sender: UIButton) {
        for field in [nameField, passwordField] {
            if field.text?.isEmpty ?? true {
                showErrorForField(field)
                return
            }
        }
        // ok, can proceed with login
    }
    
    @objc func onChangeTextField(sender: UITextField) {
        errorLabel.removeFromSuperview()
        boxView.animateChangesWithDurations(0.3)
    }


BoxView mendukung semua toolkit autolayout: jarak antar elemen, ukuran absolut dan relatif, prioritas, dukungan bahasa RTL. Selain UIView, objek tak terlihat - UILayoutGuides juga dapat digunakan sebagai elemen tata letak. Tata letak fleksibel juga dapat digunakan. Tentu saja, skema tata letak itu sendiri, dalam bentuk sistem tumpukan UIView bersarang, tidak 100% mencakup semua opsi yang mungkin untuk pengaturan relatif elemen, tetapi ini tidak diperlukan. Tidak apa-apa untuk sebagian besar antarmuka pengguna biasa, dan untuk kasus yang lebih eksotis, Anda selalu dapat menambahkan kendala tambahan yang sesuai dengan cara lain. Beberapa metode utilitas, misalnya untuk membuat batasan rasio aspek, juga disertakan dalam perpustakaan.



Contoh kecil lainnyatersedia di github (~ 100 baris kode!) mengilustrasikan penggunaan sistem bersarang BoxView bersama dengan metode pengaturan kendala lainnya, serta perubahan animasi dalam pengaturan BoxView.



gambar


Proyek BoxView di github



All Articles