Halo, Habr! Saya mempersembahkan kepada Anda terjemahan artikel
Menciptakan Batasan UIViews Secara Programatis Menggunakan PureLayout oleh Aly Yaka.

Hari ini saya akan memandu Anda membuat antarmuka pengguna aplikasi seluler sederhana dengan kode, tanpa menggunakan storyboard atau NIB. Saya tidak akan membahas mana yang lebih baik, karena semuanya memiliki pro dan kontra, jadi saya hanya
akan meninggalkan tautan yang membahas masalah ini .
Di bagian kedua panduan ini, kami akan membuat beberapa elemen antarmuka pengguna aplikasi seluler yang paling umum digunakan dengan kode, termasuk bilah navigasi, tampilan tabel, dan sel berukuran dinamis.
Ulasan
Tutorial ini ditulis menggunakan Xcode 9 dan Swift 4. Saya juga berasumsi bahwa Anda terbiasa dengan Xcode, Swift, dan CocoaPods.
Tanpa penundaan lebih lanjut, mari mulai membuat proyek kami: aplikasi Kartu Kontak sederhana. Tujuan artikel ini adalah untuk mengajarkan Anda cara membuat antarmuka pengguna aplikasi Anda dalam kode, dan karena itu tidak akan berisi logika apa pun mengenai fungsionalitas aplikasi, kecuali ini diperlukan untuk keperluan panduan ini.
Membuat batasan secara pemrograman dengan PureLayout
Penyiapan proyek
Mulailah dengan meluncurkan Xcode -> "Buat Proyek Xcode Baru". Pilih "Aplikasi Tampilan Tunggal" dan klik "Selanjutnya".

Beri nama proyek yang Anda suka, saya memutuskan untuk menyebutnya ContactCard. Hapus ketiga opsi di bawah ini dan pilih Swift sebagai bahasa pemrograman Anda, lalu klik Next.

Pilih lokasi di komputer Anda untuk menyimpan proyek. Hapus centang "Buat Gudang Git di Mac saya."
Karena kami tidak akan menggunakan Storyboards atau NIB dalam proyek ini, hapus "Main.storyboard", yang dapat ditemukan di Project Navigator:

Setelah itu, klik pada proyek di navigator proyek dan pada tab "Umum", cari bagian dengan informasi penyebaran dan hapus semua yang tertulis di "Antarmuka Utama". Inilah yang memberitahu Xcode mana file Storyboard untuk memuat ketika aplikasi dimulai, tetapi karena kita baru saja menghapus "Main.storyboard", Xcode tidak akan menemukan file ini, yang akan menyebabkan aplikasi crash.

Membuat ViewController
Jika Anda menjalankan aplikasi sekarang, layar hitam akan muncul, karena aplikasi tidak lagi memiliki sumber antarmuka pengguna, jadi di bagian selanjutnya kita akan membuatnya. Buka "AppDelegate.swift" dan di dalam
application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?)
, Tempel fragmen kode ini:
self.window = UIWindow(frame: UIScreen.main.bounds) let viewController = ViewController() self.window?.rootViewController = viewController self.window?.makeKeyAndVisible()
Kode ini menyediakan jendela untuk interaksi pengguna dengan aplikasi, yang biasanya dapat ditemukan di "ViewController.swift". Untuk memverifikasi dengan cepat bahwa semuanya berfungsi, buka "ViewController.swift" dan dalam metode
viewDidLoad()
, masukkan baris berikut:
self.view.backgroundColor = .blue
Sekarang jalankan aplikasi.
Untuk menavigasi antara file dalam Xcode, gunakan tombol pintas "⇧⌘O", dan kemudian masukkan nama file atau bahkan fragmen kode yang Anda cari, dan daftar file yang dapat Anda pilih akan muncul di layar.
Setelah memulai aplikasi, ini akan menjadi hasil di layar simulator Anda:

Tentu saja, kami tidak akan menggunakan biru yang menjijikkan ini, jadi ubah saja latar belakang menjadi putih dengan mengganti
.blue
dengan
.white
inside
viewDidLoad ()
.
Pengembangan UI
Untuk membuat antarmuka pengguna, kami akan menggunakan
perpustakaan yang akan membuat hidup kami jauh lebih mudah. Untuk menginstal PureLayout, Anda harus terlebih dahulu membuka terminal dan mengetik cd, lalu spasi, seret folder proyek Anda ke terminal dan tekan "Enter". Sekarang jalankan perintah berikut di dalam terminal:
Ini harus menjadi output dari terminal Anda setelah perintah kedua:

Setelah itu, tutup Xcode, buka folder di Finder, dan Anda akan menemukan "<nama proyek Anda> .xcworkspace". Inilah yang akan kami buka untuk mengakses aplikasi kami jika kami perlu menggunakan CocoaPods. Sekarang temukan file bernama "PodFile" dan tulis baris berikut di bawah frase
use_frameworks!
pod “PureLayout”
Jalankan
pod install
lagi di terminal Anda, dan kemudian bangun proyek Anda dengan menekan "Command + B".
Rehat kopi
Sekarang semuanya sudah diatur, mari kita mulai dengan pekerjaan nyata. Pergi ke "ViewController.swift" dan ambil secangkir kopi, karena seperti inilah hasil akhirnya:

Buat ImageView
Masukkan baris
import PureLayout
bawah
import UIKit
sehingga Anda dapat menggunakan perpustakaan di file ini. Kemudian, di bawah deklarasi kelas dan di luar fungsi apa pun, kita mulai dengan membuat variabel
Avatar ImageView
malas (malas) sebagai berikut:
lazy var avatar: UIImageView = { let imageView = UIImageView(image: UIImage(named: "avatar.jpg")) imageView.autoSetDimensions(to: CGSize(width: 128.0, height: 128.0)) imageView.layer.borderWidth = 3.0 imageView.layer.borderColor = UIColor.lightGray.cgColor imageView.layer.cornerRadius = 64.0 imageView.clipsToBounds = true return imageView }()
Sedangkan untuk gambar, simpan gambar apa saja di desktop yang akan Anda gunakan sebagai avatar, dan seret ke Xcode di folder <Your Project Name>, yang dalam kasus saya disebut "ContactCard", dan centang kotak "Salin item jika perlu" .

Setelah itu, tulis nama file ini bersama dengan ekstensi dalam deklarasi UIImage alih-alih “avatar.jpg”.
Bagi Anda yang tidak tahu, variabel malas mirip dengan variabel biasa, kecuali bahwa mereka tidak diinisialisasi (atau beberapa ruang memori dialokasikan) sampai mereka diperlukan atau dipanggil untuk pertama kalinya . Ini berarti bahwa variabel malas tidak diinisialisasi ketika pengontrol tampilan diinisialisasi, melainkan mengharapkan titik nanti ketika mereka benar-benar diperlukan, yang menghemat daya pemrosesan dan ruang memori untuk proses lainnya. Ini sangat berguna saat menginisialisasi komponen antarmuka pengguna.
PureLayout beraksi
Seperti yang Anda lihat di dalam inisialisasi, baris
imageView.autoSetDimensions (to: CGSize (width: 128.0, height: 128.0))
adalah PureLayout yang sedang beraksi. Dalam satu baris, kami menetapkan batas untuk ketinggian dan lebar UIImageView, dan semua NSLayoutConstraints yang diperlukan dibuat tanpa perlu pemanggilan fungsi yang sangat besar. Jika Anda berhadapan dengan membuat batasan secara terprogram, maka kemungkinan besar Anda sudah jatuh cinta dengan perpustakaan yang luar biasa ini.
Untuk membuat gambar ini bulat, kita mengatur radius sudutnya menjadi setengah lebar atau tingginya, yaitu 64,0 poin. Selain itu, atur properti
clipsToBounds
menjadi
true
, yang memberitahu gambar bahwa itu harus klip semua yang ada di luar radius yang baru saja kita atur.
Kemudian kita beralih ke membuat UIView yang akan berfungsi sebagai bagian atas tampilan di belakang avatar dicat abu-abu. Nyatakan variabel malas berikut untuk tampilan ini:
lazy var upperView: UIView = { let view = UIView() view.autoSetDimension(.height, toSize: 128) view.backgroundColor = .gray return view }()
Menambahkan subview
Sebelum melanjutkan, mari buat
func addSubviews ()
yang menambahkan tampilan yang baru saja kita buat (dan semua yang akan kita buat) sebagai subviews ke pengontrol tampilan:
func addSubviews() { self.view.addSubview(avatar) self.view.addSubview(upperView) }
Sekarang tambahkan baris berikut ke
viewDidLoad (): self.addSubviews ()
Batasan pengaturan
Untuk mendapatkan gambaran seberapa jauh kita telah melangkah, mari kita tentukan batasan pada kedua jenis ini. Buat fungsi lain yang disebut
func setupConstraints()
dan masukkan batasan berikut:
func setupConstraints() { avatar.autoAlignAxis(toSuperviewAxis: .vertical) avatar.autoPinEdge(toSuperviewEdge: .top, withInset: 64.0) upperView.autoPinEdge(toSuperviewEdge: .left) upperView.autoPinEdge(toSuperviewEdge: .right) upperView.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .bottom) }
Sekarang di dalam
viewDidLoad()
panggil
setupConstraints()
, sebagai berikut:
self.setupConstraints()
. Tambahkan ini SETELAH panggilan
addSubviews()
. Ini harus menjadi kesimpulan akhir:

Bawa avatar ke garis depan
Sayangnya, ini bukan yang ingin saya terima. Seperti yang Anda lihat,
upperView
atas kami terletak di atas avatar. Ini karena fakta bahwa kami menambahkan avatar sebagai
subviews
sebelum tampilan
upperView
, dan karena subview ini terletak dalam beberapa bentuk di stack, kami mendapatkan hasil ini. Untuk mengatasinya, kita cukup mengganti dua baris ini satu sama lain, tetapi ada trik lain yang ingin saya tunjukkan kepada Anda, yaitu:
self.view.bringSubview (toFront: avatar)
.
Metode ini akan mentransfer avatar dari bagian bawah tumpukan ke atas, jadi pilih metode yang paling Anda sukai. Tentu saja, untuk keterbacaan, lebih baik menambahkan subview dalam urutan di mana mereka harus ditampilkan jika berpotongan, sambil mengingat bahwa subview yang ditambahkan pertama akan berada di bagian bawah tumpukan, dan oleh karena itu pandangan berpotongan lainnya akan muncul di atasnya.
Dan beginilah seharusnya tampilannya:

Buat Kontrol Tersegmentasi
Selanjutnya, kita akan membuat kontrol tersegmentasi, yang merupakan bilah abu-abu yang berisi tiga bagian. Sebenarnya, kontrol tersegmentasi mudah dibuat. Lakukan hal berikut:
lazy var segmentedControl: UISegmentedControl = { let control = UISegmentedControl(items: ["Personal", "Social", "Resumè"]) control.autoSetDimension(.height, toSize: 32.0) control.selectedSegmentIndex = 0 control.layer.borderColor = UIColor.gray.cgColor control.tintColor = .gray return control }()
Saya percaya bahwa semuanya jelas, satu-satunya perbedaan adalah bahwa setelah inisialisasi kami menyediakannya dengan serangkaian string, setiap baris mewakili judul dari salah satu bagian yang kami inginkan. Kami juga mengatur
selectedSegmentIndex
ke 0, yang memberi tahu kontrol tersegmentasi untuk memilih / memilih segmen pertama selama inisialisasi. Sisanya hanyalah gaya bermain.
Sekarang mari kita lanjutkan dan tambahkan sebagai subview dengan menyisipkan baris berikut di akhir fungsi
addCubviews(): self.view.addSubview(segmentedControl)
dan batasannya akan seperti ini:
segmentedControl.autoPinEdge(toSuperviewEdge: .left, withInset: 8.0) segmentedControl.autoPinEdge(toSuperviewEdge: .right, withInset: 8.0) segmentedControl.autoPinEdge(.top, to: .bottom, of: avatar, withOffset: 16.0)
Kami memberi tahu kontrol tersegmentasi bahwa kami ingin melampirkannya di sisi kiri superview-nya, namun kami ingin sedikit meningkatkan intervalnya, dan tidak melampirkannya langsung ke tepi layar. Jika Anda perhatikan, saya menggunakan apa yang disebut grid delapan titik, di mana semua jarak dan ukuran adalah kelipatan delapan. Saya melakukan hal yang sama di sisi kanan kontrol tersegmentasi. Sedangkan untuk batasan terakhir, ia mengatakan melampirkan titik pada pangkal avatar dengan interval 16 poin.
Setelah menambahkan batasan di atas ke
func setupConstraints()
jalankan kodenya dan pastikan tampilannya seperti ini:

Menambahkan Tombol
Sekarang kita akan beralih ke bagian terakhir dari antarmuka pengguna buku teks, yang merupakan tombol "Edit". Tambahkan variabel malas berikut:
lazy var editButton: UIButton = { let button = UIButton() button.setTitle("Edit", for: .normal) button.setTitleColor(.gray, for: .normal) button.layer.cornerRadius = 4.0 button.layer.borderColor = UIColor.gray.cgColor button.layer.borderWidth = 1.0 button.tintColor = .gray button.backgroundColor = .clear button.autoSetDimension(.width, toSize: 96.0) button.autoSetDimension(.height, toSize: 32.0) return button }()
Jangan khawatir tentang seberapa besar inisialisasi ini, tetapi perhatikan bagaimana saya mengatur judul dan warnanya dengan memanggil fungsi
button.setTitle
dan
button.setTitleColor
. Untuk alasan tertentu, kami tidak dapat menetapkan judul tombol dengan langsung mengakses
titleLabel
-
titleLabel
, dan ini karena ada status berbeda untuk tombol tersebut, dan banyak yang akan merasa nyaman memiliki tajuk / warna berbeda untuk status berbeda.
Sekarang tambahkan tombol sebagai subview, seperti komponen lainnya, dan tambahkan batasan berikut ini sehingga muncul di tempat yang seharusnya:
editButton.autoPinEdge(.top, to: .bottom, of: upperView, withOffset: 16.0) editButton.autoPinEdge(toSuperviewEdge: .right, withInset: 8.0)
Di sini kami hanya menetapkan batas kanan dan atas untuk tombol, karena kami memberikan ukuran, itu tidak akan berkembang dan tidak ada lagi yang diperlukan. Sekarang jalankan proyek untuk melihat hasil akhir:

Beberapa catatan terbaru
Berlatih, tambahkan elemen antarmuka sebanyak yang Anda inginkan. Buat tampilan aplikasi apa pun yang Anda rasa sulit. Mulai yang sederhana dan secara bertahap tingkatkan kesulitannya. Coba gambarkan komponen UI pada selembar kertas untuk membayangkan bagaimana mereka saling menempel.
Di bagian kedua, saya memperluas panduan ini untuk membuat bilah navigasi, tampilan tabel, dan sel berukuran dinamis dalam kode.