Saya memiliki tampilan yang memiliki baris dan kolom tampilan gambar di dalamnya.
Jika tampilan ini diubah ukurannya, saya perlu mengatur ulang posisi tampilan gambar.
Tampilan ini adalah subview dari tampilan lain yang ukurannya diubah.
Adakah cara untuk mendeteksi kapan tampilan ini diubah ukurannya?
Jawaban:
Seperti komentar Uli di bawah ini, cara yang tepat untuk melakukannya adalah menimpa
layoutSubviews
dan mengatur tata letak imageView di sana.Jika, karena alasan tertentu, Anda tidak dapat membuat subkelas dan menimpa
layoutSubviews
, observasibounds
seharusnya berhasil, bahkan saat menjadi agak kotor. Lebih buruk lagi, ada risiko dengan mengamati - Apple tidak menjamin KVO berfungsi pada kelas UIKit. Baca diskusi dengan teknisi Apple di sini: Kapan objek terkait dirilis?jawaban asli:
Anda dapat menggunakan pengamatan nilai kunci:
dan terapkan:
sumber
viewWillTransition
dll dll.layoutSubviews
masih menggunakan metode yang disarankan jika, bergantung pada ukuran tampilan saat ini, sub-tampilan yang berbeda perlu ditambahkan / dihapus dan batasan yang berbeda perlu ditambahkan / dihilangkan?Dalam
UIView
subclass, pengamat properti dapat digunakan:Tanpa subclassing, kunci-nilai observasi dengan kunci-jalur pintar akan melakukan:
sumber
frame
adalah properti hitung turunan dan runtime. jangan menimpa ini, kecuali Anda memiliki alasan yang sangat cerdas dan mengetahui untuk melakukannya. sebaliknya: gunakanbounds
atau (bahkan lebih baik)layoutSubviews
.override var bounds: CGRect { didSet { layer.cornerRadius = bounds.size.width / 2 }}
bounds
atauframe
mengubah tidak dijamin akan berhasil, bergantung pada tempat Anda meletakkan tampilan dalam hierarki tampilan. Saya akan menggantinyalayoutSubviews
. Lihat ini dan ini jawaban.Buat subclass UIView, dan timpa layoutSubviews
sumber
Swift 4 keypath KVO - Ini adalah cara saya mendeteksi rotasi otomatis dan berpindah ke panel samping iPad. Harus bekerja bekerja tampilan apa pun. Harus mengamati lapisan UIView.
sumber
.layer
berhasil! Tahukah Anda mengapa penggunaanview.observe
tidak berhasil?Anda dapat membuat subclass UIView dan mengganti
setFrame: (CGRect) bingkai
metode. Ini adalah metode yang dipanggil saat bingkai (yaitu ukuran) tampilan diubah. Lakukan sesuatu seperti ini:
sumber
setFrame:
tidak dipanggil padaUITextView
subkelas saya selama pengubahan ukuran yang disebabkan oleh rotasi otomatislayoutSubviews:
. Catatan: Saya menggunakan tata letak otomatis & iOS 7.0.setFrame:
.frame
adalah properti turunan. Lihat jawaban sayaCukup tua tapi masih pertanyaan yang bagus. Dalam kode sampel Apple, dan di beberapa subkelas UIView pribadi mereka, mereka mengganti setBounds secara kasar seperti:
Mengganti
setFrame:
bukanlah ide yang bagus.frame
diturunkan daricenter
,,bounds
dantransform
, jadi iOS tidak akan selalu memanggilsetFrame:
.sumber
setBounds:
tidak dipanggil baik saat menyetel properti frame (setidaknya di iOS 7.1). Ini bisa menjadi optimasi yang ditambahkan Apple untuk menghindari pesan tambahan.frame
danbounds
berasal dari tampilan yang mendasariCALayer
; mereka hanya memanggil melalui pengambil lapisan. DansetFrame:
mengatur bingkai lapisan, sementarasetBounds:
mengatur batas lapisan. Jadi, Anda tidak bisa begitu saja menimpa salah satunya. Juga,layoutSubviews
dipanggil secara berlebihan (tidak hanya pada perubahan geometri), jadi ini mungkin juga tidak selalu menjadi pilihan yang baik. Masih mencari ...Jika Anda berada dalam instance UIViewController, menimpa
viewDidLayoutSubviews
akan berhasil.sumber
UIView
instance danUIViewController
instance. Jadi jika Anda memilikiUIView
instance tanpa VC yang terpasang, jawaban lainnya bagus, tetapi jika Anda kebetulan terhubung ke VC, ini laki-laki Anda. Maaf itu tidak berlaku untuk kasus Anda.