Karena pertanyaan yang saya ajukan telah dilihat berulang kali, saya akan memberikan jawaban terperinci. Jangan ragu untuk memodifikasinya jika Anda ingin menambahkan lebih banyak konten yang benar.
Pertama rekap pada pertanyaan: bingkai, batas dan pusat dan hubungan mereka.
Frame A view's frame
( CGRect
) adalah posisi persegi panjangnya di superview
sistem koordinat. Secara default dimulai di kiri atas.
Bounds A view's bounds
( CGRect
) mengekspresikan persegi panjang view dalam sistem koordinatnya sendiri.
Pusat A center
adalah CGPoint
dinyatakan dalam superview
sistem koordinat dan menentukan posisi titik tengah tampilan yang tepat.
Diambil dari posisi UIView + ini adalah hubungan (mereka tidak bekerja dalam kode karena mereka adalah persamaan informal) di antara properti sebelumnya:
CATATAN: Hubungan ini tidak berlaku jika tampilan diputar. Untuk info lebih lanjut, saya sarankan Anda melihat gambar berikut yang diambil dari The Kitchen Drawer berdasarkan kursus Stanford CS193p . Kredit diberikan ke @Rhubarb .
Dengan menggunakan, frame
Anda dapat mengubah posisi dan / atau mengubah ukuran tampilan di dalamnya superview
. Biasanya dapat digunakan dari superview
, misalnya, saat Anda membuat subview tertentu. Sebagai contoh:
// view1 will be positioned at x = 30, y = 20 starting the top left corner of [self view]
// [self view] could be the view managed by a UIViewController
UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 400.0f, 400.0f)];
view1.backgroundColor = [UIColor redColor];
[[self view] addSubview:view1];
Ketika Anda membutuhkan koordinat untuk menggambar di dalam, view
Anda biasanya merujuk bounds
. Contoh tipikalnya adalah menggambar dalam view
subview sebagai inset yang pertama. Menggambar subview perlu mengetahui bounds
superview. Sebagai contoh:
UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(50.0f, 50.0f, 400.0f, 400.0f)];
view1.backgroundColor = [UIColor redColor];
UIView* view2 = [[UIView alloc] initWithFrame:CGRectInset(view1.bounds, 20.0f, 20.0f)];
view2.backgroundColor = [UIColor yellowColor];
[view1 addSubview:view2];
Perilaku yang berbeda terjadi ketika Anda mengubah bounds
tampilan. Misalnya, jika Anda mengubah bounds
size
, frame
perubahan (dan sebaliknya). Perubahan terjadi di sekitar center
tampilan. Gunakan kode di bawah ini dan lihat apa yang terjadi:
NSLog(@"Old Frame %@", NSStringFromCGRect(view2.frame));
NSLog(@"Old Center %@", NSStringFromCGPoint(view2.center));
CGRect frame = view2.bounds;
frame.size.height += 20.0f;
frame.size.width += 20.0f;
view2.bounds = frame;
NSLog(@"New Frame %@", NSStringFromCGRect(view2.frame));
NSLog(@"New Center %@", NSStringFromCGPoint(view2.center));
Selanjutnya, jika Anda mengubah bounds
origin
Anda mengubah origin
sistem koordinat internal. Secara default origin
berada di (0.0, 0.0)
(sudut kiri atas). Misalnya, jika Anda mengubah origin
untuk view1
Anda dapat melihat (komentar kode sebelumnya jika Anda mau) yang sekarang sudut kiri atas untuk view2
menyentuh yang view1
. Motivasinya cukup sederhana. Anda mengatakan kepada view1
bahwa sudut kiri atas kini berada pada posisi (20.0, 20.0)
tapi karena view2
's frame
origin
mulai dari (20.0, 20.0)
, mereka akan bertepatan.
CGRect frame = view1.bounds;
frame.origin.x += 20.0f;
frame.origin.y += 20.0f;
view1.bounds = frame;
Ini origin
mewakili view
posisi dalam superview
tetapi menggambarkan posisi bounds
pusat.
Akhirnya, bounds
dan origin
tidak terkait konsep. Keduanya memungkinkan untuk memperoleh frame
tampilan (Lihat persamaan sebelumnya).
Studi kasus View1
Inilah yang terjadi ketika menggunakan cuplikan berikut.
UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 400.0f, 400.0f)];
view1.backgroundColor = [UIColor redColor];
[[self view] addSubview:view1];
NSLog(@"view1's frame is: %@", NSStringFromCGRect([view1 frame]));
NSLog(@"view1's bounds is: %@", NSStringFromCGRect([view1 bounds]));
NSLog(@"view1's center is: %@", NSStringFromCGPoint([view1 center]));
Gambar relatif.
Ini yang terjadi jika saya mengubah [self view]
batasan seperti berikut.
// previous code here...
CGRect rect = [[self view] bounds];
rect.origin.x += 30.0f;
rect.origin.y += 20.0f;
[[self view] setBounds:rect];
Gambar relatif.
Di sini Anda mengatakan [self view]
bahwa sudut kiri atas sekarang berada di posisi (30.0, 20.0) tetapi karena view1
asal bingkai dimulai dari (30.0, 20.0), mereka akan bertepatan.
Referensi tambahan (untuk memperbarui dengan referensi lain jika Anda mau)
Tentang clipsToBounds
(sumber Apple doc)
Menetapkan nilai ini ke YA menyebabkan subview terpotong pada batas-batas penerima. Jika diatur ke TIDAK, subview yang bingkainya melampaui batas yang terlihat dari receiver tidak terpotong. Nilai standarnya adalah TIDAK.
Dengan kata lain, jika tampilan frame
adalah (0, 0, 100, 100)
dan subview-nya (90, 90, 30, 30)
, Anda hanya akan melihat sebagian dari subview itu. Yang terakhir tidak akan melebihi batas tampilan induk.
masksToBounds
setara dengan clipsToBounds
. Alih-alih ke UIView
, properti ini diterapkan ke CALayer
. Di bawah tenda, clipsToBounds
panggilan masksToBounds
. Untuk referensi lebih lanjut, lihat Bagaimana hubungan antara clipsToBounds UIView dan maskALToBounds CALayer? .