UIView
ve alt sınıfları tüm özelliklere sahiptir frame
ve bounds
. Fark ne?
UIView
ve alt sınıfları tüm özelliklere sahiptir frame
ve bounds
. Fark ne?
Yanıtlar:
Sınırları bir bölgesinin UIView olan dikdörtgen kendi koordinat sisteminin (0,0) göre bir yerde (x, y) ve boyut (genişlik, yükseklik) olarak ifade edilen,.
Çerçeve , bir bölgesinin UIView olan dikdörtgen bunun içinde yer alan Superview göre bir yerde (x, y) ve boyut (genişlik, yükseklik) olarak ifade edilen,.
Bu nedenle, denetiminin 25,25 (x, y) konumunda 100x100 (genişlik x yükseklik) boyutuna sahip bir görünüm düşünün. Aşağıdaki kod, bu görünümün sınırlarını ve çerçevesini yazdırır:
// This method is in the view controller of the superview
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"bounds.origin.x: %f", label.bounds.origin.x);
NSLog(@"bounds.origin.y: %f", label.bounds.origin.y);
NSLog(@"bounds.size.width: %f", label.bounds.size.width);
NSLog(@"bounds.size.height: %f", label.bounds.size.height);
NSLog(@"frame.origin.x: %f", label.frame.origin.x);
NSLog(@"frame.origin.y: %f", label.frame.origin.y);
NSLog(@"frame.size.width: %f", label.frame.size.width);
NSLog(@"frame.size.height: %f", label.frame.size.height);
}
Ve bu kodun çıktısı:
bounds.origin.x: 0
bounds.origin.y: 0
bounds.size.width: 100
bounds.size.height: 100
frame.origin.x: 25
frame.origin.y: 25
frame.size.width: 100
frame.size.height: 100
Dolayısıyla, her iki durumda da, sınırlara veya çerçeveye bakıp bakmadığımızdan bağımsız olarak görünümün genişliği ve yüksekliğinin aynı olduğunu görebiliriz. Farklı olan görünümün x, y konumlandırmasıdır. Sınırlar söz konusu olduğunda, bu koordinatlar görünümün kendisine göreli olduğundan, x ve y koordinatları 0,0'dır. Bununla birlikte, x ve y kareleri koordinatları, görünümün üst görünümdeki konumuyla ilişkilidir (daha önce 25,25'te olduğunu söylemiştik).
Bir de bulunmaktadır harika sunum UIViews kapsar. Sadece çerçeveler ve sınırlar arasındaki farkı açıklamakla kalmayıp aynı zamanda görsel örnekleri de gösteren 1-20 slaytlarına bakın.
frame = üst görünümün koordinat sistemini kullanarak bir görünümün konumu ve boyutu
bounds = bir görünümün kendi koordinat sistemini kullanarak konumu ve boyutu
Çerçeveyi hatırlamama yardımcı olmak için , bir duvardaki resim çerçevesini düşünüyorum . Resim çerçevesi görünümün kenarlığına benzer. Resmi duvarda istediğim her yere asabilirim. Aynı şekilde, üst görünümde (denetim adı da denir) istediğim her yere görünüm koyabilirim. Üst görünüm duvar gibidir. İOS'ta koordinat sisteminin kökeni sol üst köşedir. Görünüm çerçevemizin xy koordinatlarını (0, 0) olarak ayarlayarak görüşümüzü kaynağın kökenine koyabiliriz, bu da resmimizi duvarın sol üst köşesine asmak gibidir. Sağa taşımak için x'i artırın, aşağı taşımak için y'yi artırın.
Sınırları hatırlamama yardımcı olmak için , bazen basketbolun sınırların dışına atıldığı bir basketbol sahası düşünüyorum . Topu basketbol sahasının her tarafına sürüyorsunuz, ancak mahkemenin kendisinin nerede olduğunu gerçekten önemsemiyorsunuz. Bir spor salonunda veya dışarıda bir lisede veya evinizin önünde olabilir. Önemli değil. Sadece basketbol oynamak istiyorsun. Aynı şekilde, bir görünümün sınırları için koordinat sistemi yalnızca görünümün kendisine önem verir. Üst görünümde görünümün nerede olduğu hakkında hiçbir şey bilmiyor. Sınırların başlangıç noktası (varsayılan olarak nokta (0, 0)) görünümün sol üst köşesidir. Bu görüşün sahip olduğu tüm alt görüşler bu noktaya göre düzenlenir. Basketbolu mahkemenin sol ön köşesine götürmek gibi.
Şimdi, kareyi ve sınırları karşılaştırmaya çalıştığınızda karışıklık geliyor. Aslında ilk başta göründüğü kadar kötü değil. Anlayabilmemiz için bazı resimler kullanalım.
Soldaki ilk resimde, üst görünümünün sol üst tarafında bulunan bir görünüm var. Sarı dikdörtgen görünümün çerçevesini temsil eder. Sağda görünümü tekrar görüyoruz ancak bu kez üst görünüm gösterilmiyor. Çünkü sınırlar ebeveyn görüşünü bilmiyor. Yeşil dikdörtgen görünümün sınırlarını temsil eder. Her iki görüntüdeki kırmızı nokta , çerçevenin veya sınırların kökenini temsil eder .
Frame
origin = (0, 0)
width = 80
height = 130
Bounds
origin = (0, 0)
width = 80
height = 130
Yani çerçeve ve sınırlar bu resimde tamamen aynıydı. Farklı oldukları bir örneğe bakalım.
Frame
origin = (40, 60) // That is, x=40 and y=60
width = 80
height = 130
Bounds
origin = (0, 0)
width = 80
height = 130
Böylece çerçevenin xy koordinatlarını değiştirmenin onu üst görünümde hareket ettirdiğini görebilirsiniz. Ancak görünümün içeriği hala aynı görünüyor. Sınırların hiçbir şeyin farklı olduğuna dair hiçbir fikri yoktur.
Şimdiye kadar hem çerçevenin hem de sınırların genişliği ve yüksekliği tamamen aynı olmuştur. Yine de bu her zaman doğru değildir. Görünümü saat yönünde 20 derece döndürürsek ne olduğuna bakın. (Döndürme dönüştürmeler kullanılarak yapılır. Daha fazla bilgi için belgelere , bu görünüm ve katman örneklerine bakın.)
Frame
origin = (20, 52) // These are just rough estimates.
width = 118
height = 187
Bounds
origin = (0, 0)
width = 80
height = 130
Sınırların hala aynı olduğunu görebilirsiniz. Hala bir şey olduğunu bilmiyorlar! Yine de kare değerlerinin hepsi değişti.
Çerçeve ve sınırlar arasındaki farkı görmek biraz daha kolay, değil mi? Muhtemelen kareleri ve sınırları anlamadığınız makalede bir görünüm çerçevesi
... söz konusu görünüme uygulanan dönüşümler de dahil olmak üzere, bu görünümün ana koordinat sistemine göre en küçük sınırlayıcı kutusu.
Bir görünümü dönüştürürseniz, çerçevenin tanımsız hale geldiğine dikkat etmek önemlidir. Yani aslında, yukarıdaki resimde döndürülen yeşil sınırların etrafında çizdiğim sarı çerçeve asla gerçekte mevcut değil. Bu, döndürür, ölçeklendirir veya başka bir dönüşüm yaparsanız, çerçeve değerlerini artık kullanmamanız gerektiği anlamına gelir. Yine de sınır değerlerini kullanabilirsiniz. Apple belgeleri uyarıyor:
Önemli: Bir görünümün
transform
özelliği kimlik dönüşümü içermiyorsa, o görünümün çerçevesi tanımsızdır ve otomatikleştirme davranışlarının sonuçları da öyle olur.
Autoresizing hakkında oldukça talihsiz .... Ama yapabileceğiniz bir şey var.
transform
Görünümünüzün özelliğini değiştirirken , tüm dönüşümler görünümün merkez noktasına göre gerçekleştirilir.
Dolayısıyla, bir dönüştürme yapıldıktan sonra üst görünümde bir görünüm taşımanız gerekiyorsa, view.center
koordinatları değiştirerek bunu yapabilirsiniz . Mesela frame
, center
üst görünümün koordinat sistemini kullanır.
Tamam, rotasyonumuzdan kurtulalım ve sınırlara odaklanalım. Şimdiye kadar sınırların kökeni her zaman (0, 0) kaldı. Olmasına gerek yok. Görüşümüz, bir kerede görüntülenemeyecek kadar büyük büyük bir alt görünüme sahipse ne olur? UIImageView
Büyük bir resimle bunu yapacağız . İşte yukarıdaki ikinci resmimiz yine, ancak bu sefer görüşümüzün alt görünümünün tüm içeriğinin nasıl görüneceğini görebiliriz.
Frame
origin = (40, 60)
width = 80
height = 130
Bounds
origin = (0, 0)
width = 80
height = 130
Görüntünün yalnızca sol üst köşesi görünümün sınırlarına sığabilir. Şimdi sınırların başlangıç koordinatlarını değiştirirsek ne olur bakalım.
Frame
origin = (40, 60)
width = 80
height = 130
Bounds
origin = (280, 70)
width = 80
height = 130
Çerçeve denetimde hareket etmedi, ancak sınır dikdörtgeninin kaynağı görünümün farklı bir bölümünde başladığı için çerçevenin içindeki içerik değişti. Bu, a UIScrollView
ve onun alt sınıflarının arkasındaki tüm fikirdir (örneğin, a UITableView
). Daha fazla açıklama için UIScrollView'ı Anlama konusuna bakın .
Yana frame
üst görünümünde bir görünümün konumu ile ilgilidir yapıyoruz zaman, bunu kullanmak dışa değişiklikleri genişliğini değiştirmek veya görünüm ve üst görünümü üst kısmı arasındaki mesafeyi bulmak gibi.
Görünüm çizme veya görünüm içinde alt görünümler düzenleme gibi içe doğru değişiklikbounds
yaparken kullanın . Ayrıca, üzerinde biraz transfeksiyon gerçekleştirdiyseniz, görünümün boyutunu almak için sınırları kullanın.
Apple belgeleri
İlgili StackOverflow soruları
Diğer kaynaklar
Yukarıdaki makaleleri okumaya ek olarak, bir test uygulaması yapmak bana çok yardımcı olur. Benzer bir şey yapmaya çalışmak isteyebilirsiniz. ( Bu video kursundan fikrim var ama maalesef ücretsiz değil.)
İşte referans için kod:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var myView: UIView!
// Labels
@IBOutlet weak var frameX: UILabel!
@IBOutlet weak var frameY: UILabel!
@IBOutlet weak var frameWidth: UILabel!
@IBOutlet weak var frameHeight: UILabel!
@IBOutlet weak var boundsX: UILabel!
@IBOutlet weak var boundsY: UILabel!
@IBOutlet weak var boundsWidth: UILabel!
@IBOutlet weak var boundsHeight: UILabel!
@IBOutlet weak var centerX: UILabel!
@IBOutlet weak var centerY: UILabel!
@IBOutlet weak var rotation: UILabel!
// Sliders
@IBOutlet weak var frameXSlider: UISlider!
@IBOutlet weak var frameYSlider: UISlider!
@IBOutlet weak var frameWidthSlider: UISlider!
@IBOutlet weak var frameHeightSlider: UISlider!
@IBOutlet weak var boundsXSlider: UISlider!
@IBOutlet weak var boundsYSlider: UISlider!
@IBOutlet weak var boundsWidthSlider: UISlider!
@IBOutlet weak var boundsHeightSlider: UISlider!
@IBOutlet weak var centerXSlider: UISlider!
@IBOutlet weak var centerYSlider: UISlider!
@IBOutlet weak var rotationSlider: UISlider!
// Slider actions
@IBAction func frameXSliderChanged(sender: AnyObject) {
myView.frame.origin.x = CGFloat(frameXSlider.value)
updateLabels()
}
@IBAction func frameYSliderChanged(sender: AnyObject) {
myView.frame.origin.y = CGFloat(frameYSlider.value)
updateLabels()
}
@IBAction func frameWidthSliderChanged(sender: AnyObject) {
myView.frame.size.width = CGFloat(frameWidthSlider.value)
updateLabels()
}
@IBAction func frameHeightSliderChanged(sender: AnyObject) {
myView.frame.size.height = CGFloat(frameHeightSlider.value)
updateLabels()
}
@IBAction func boundsXSliderChanged(sender: AnyObject) {
myView.bounds.origin.x = CGFloat(boundsXSlider.value)
updateLabels()
}
@IBAction func boundsYSliderChanged(sender: AnyObject) {
myView.bounds.origin.y = CGFloat(boundsYSlider.value)
updateLabels()
}
@IBAction func boundsWidthSliderChanged(sender: AnyObject) {
myView.bounds.size.width = CGFloat(boundsWidthSlider.value)
updateLabels()
}
@IBAction func boundsHeightSliderChanged(sender: AnyObject) {
myView.bounds.size.height = CGFloat(boundsHeightSlider.value)
updateLabels()
}
@IBAction func centerXSliderChanged(sender: AnyObject) {
myView.center.x = CGFloat(centerXSlider.value)
updateLabels()
}
@IBAction func centerYSliderChanged(sender: AnyObject) {
myView.center.y = CGFloat(centerYSlider.value)
updateLabels()
}
@IBAction func rotationSliderChanged(sender: AnyObject) {
let rotation = CGAffineTransform(rotationAngle: CGFloat(rotationSlider.value))
myView.transform = rotation
updateLabels()
}
private func updateLabels() {
frameX.text = "frame x = \(Int(myView.frame.origin.x))"
frameY.text = "frame y = \(Int(myView.frame.origin.y))"
frameWidth.text = "frame width = \(Int(myView.frame.width))"
frameHeight.text = "frame height = \(Int(myView.frame.height))"
boundsX.text = "bounds x = \(Int(myView.bounds.origin.x))"
boundsY.text = "bounds y = \(Int(myView.bounds.origin.y))"
boundsWidth.text = "bounds width = \(Int(myView.bounds.width))"
boundsHeight.text = "bounds height = \(Int(myView.bounds.height))"
centerX.text = "center x = \(Int(myView.center.x))"
centerY.text = "center y = \(Int(myView.center.y))"
rotation.text = "rotation = \((rotationSlider.value))"
}
}
bounds
vs frame
bir bakış.
aşağıdaki kodu çalıştırmayı dene
- (void)viewDidLoad {
[super viewDidLoad];
UIWindow *w = [[UIApplication sharedApplication] keyWindow];
UIView *v = [w.subviews objectAtIndex:0];
NSLog(@"%@", NSStringFromCGRect(v.frame));
NSLog(@"%@", NSStringFromCGRect(v.bounds));
}
bu kodun çıktısı:
büyük / küçük harf aygıt yönü Dikey
{{0, 0}, {768, 1024}}
{{0, 0}, {768, 1024}}
büyük / küçük harf duyarlı cihazın yatay yönü
{{0, 0}, {768, 1024}}
{{0, 0}, {1024, 768}}
açıkçası, çerçeve ve sınırlar arasındaki farkı görebilirsiniz
çerçeve , süper görünümün koordinat sistemindeki görünümün başlangıç noktası (sol üst köşe) ve boyutudur, bu da çerçevenin başlangıç noktasını değiştirerek görünümü süper görünümde çevirdiğiniz anlamına gelir , diğer yandan sınırlar kendi koordinat sistemi, bu nedenle varsayılan olarak sınırların kaynağı (0,0) 'dır.
çoğu zaman çerçeve ve sınırlar uyumludur, ancak örneğin çerçeve ((140,65), (200,250)) ve sınırlar ((0,0), (200,250)) görünümünüz varsa ve görünüm eğildiyse sağ alt köşesinde durur, sonra sınırlar yine de ((0,0), (200,250)) olur, ancak çerçeve değildir.
çerçeve görünümü çevreleyen / çevreleyen en küçük dikdörtgen olacaktır, böylece çerçeve (fotoğraftaki gibi) ((140,65), (320,320)) olacaktır.
başka bir fark, örneğin sınırları ((0,0), (200,200)) olan bir superView'ınız varsa ve bu superView'in çerçevesi ((20,20), (100,100)) olan bir subView varsa ve superView sınırlarını değiştirdiyseniz ile ((20,20), (200,200)) arasındaysa, subView çerçevesi hala ((20,20), (100,100)) olur, ancak denetim koordinat sistemi (20, 20).
umarım bu birisine yardım eder.
subView
çerçeve buna göredir superView
. superView
sınırların herhangi bir şeye dönüştürülmesi, menşein subView
onunla çakışmasını sağlamaz superView
.
SuperView ile göreceli olarak çerçevelendirirken NSView ile göreceli olarak sınırlar.
Örnek: X = 40, Y = 60.Ayrıca 3 Görünüm içerir. Bu Diyagram size net bir fikir gösterir.
5 sentimi ekleyeyim.
Çerçeve , görünümün üst görünümü tarafından üst görünümün içine yerleştirmek için kullanılır.
Sınırlar , görünümün kendisi tarafından kendi içeriğini yerleştirmek için kullanılır (kaydırma görünümünde kaydırma görünümü gibi). Ayrıca bkz. Klipleri . . Sınırlar, görünümün içeriğini yakınlaştırmak / uzaklaştırmak için de kullanılabilir.
Analoji:
Çerçeve ~ TV ekranı
Sınırları ~ Kamera (yakınlaştırma, taşıma, döndürme)
Yukarıdaki cevaplar, Sınırlar ve Çerçeveler arasındaki farkı çok iyi açıkladı.
Sınırlar: Kendi koordinat sistemine göre görünüm Boyutu ve Konum.
Çerçeve: SuperView'e göre bir görünüm boyutu ve Konum.
Daha sonra, X'in Sınırı durumunda Y'nin her zaman "0" olacağı karışıklığı var. Bu doğru değil . Bu UIScrollView ve UICollectionView'da da anlaşılabilir.
'X, y sınırları 0 olmadığında
Diyelim ki bir UIScrollView var. Sayfalandırmayı uyguladık. UIScrollView 3 sayfadan oluşur ve ContentSize'ın genişliği Ekran Genişliğinin üç katıdır (ScreenWidth'in 320 olduğunu varsayalım). Yükseklik sabittir (200 varsayalım).
scrollView.contentSize = CGSize(x:320*3, y : 200)
Üç UIImageView'i subView olarak ekleyin ve çerçevenin x değerine yakından bakın
let imageView0 = UIImageView.init(frame: CGRect(x:0, y: 0 , width : scrollView.frame.size.width, height : scrollView.frame.size.height))
let imageView1 : UIImageView.init( frame: CGRect(x:320, y: 0 , width : scrollView.frame.size.width, height : scrollView.frame.size.height))
let imageView2 : UIImageView.init(frame: CGRect(x:640, y: 0 , width : scrollView.frame.size.width, height : scrollView.frame.size.height))
scrollView.addSubview(imageView0)
scrollView.addSubview(imageView0)
scrollView.addSubview(imageView0)
Sayfa 0: ScrollView 0 sayfasındayken, sınırları olacak (x: 0, y: 0, genişlik: 320, yükseklik: 200)
Sayfa 1: Kaydırma yapın ve Sayfa 1'e gidin.
Şimdi sınırlar (x: 320, y: 0, genişlik: 320, yükseklik: 200) olacak
olacaktır. Kendi koordinat Sistemi ile ilgili dediğimizi hatırlayın. Şimdi ScrollView'ımızın "Görünür Kısmı", 320'de "x" değerine sahiptir. İmageView1'in çerçevesine bakın.
UICollectionView için de aynı şey geçerli. CollectionView'a bakmanın en kolay yolu, onu kaydırmak ve sınırlarını yazdırmak / kaydetmek.
Yukarıdaki tüm cevaplar doğrudur ve bu benim bunu kabul etmemdir:
Çerçeve ve sınırlar arasında ayrım yapmak için CONCEPTS geliştiricisi şunları okumalıdır:
- denetime göre (bir ana görünüm) = FRAME içinde bulunur
- kendi koordinat sistemine göre alt görüntüleme konumunu belirler = BOUNDS
"sınırlar" kafa karıştırıcıdır çünkü koordinatların ayarlandığı görünümün konumu olduğu izlenimini verir. Ancak bunlar ilişkiler içindedir ve çerçeve sabitlerine göre ayarlanır.
Çerçeve ve bağlı
frame = üst görünümün koordinat sistemini kullanarak bir görünümün konumu ve boyutu
bounds = bir görünümün kendi koordinat sistemini kullanarak konumu ve boyutu
Görünüm, iki dikdörtgen kullanarak boyutunu ve konumunu izler: bir kare dikdörtgen ve bir sınır dikdörtgen. Çerçeve dikdörtgeni, denetimin koordinat sistemini kullanarak denetimdeki görünümün konumunu ve boyutunu tanımlar. Sınırlar dikdörtgeni, başlangıç ve ölçekleme de dahil olmak üzere görünümün içeriğini çizerken kullanılan iç koordinat sistemini tanımlar. Şekil 2-1, soldaki kare dikdörtgen ile sağdaki sınır dikdörtgen arasındaki ilişkiyi göstermektedir. ”
Kısacası, çerçeve denetimin bir görüş fikridir ve sınırlar görüşün kendi fikridir. Her görünüm için bir tane olmak üzere birden fazla koordinat sistemine sahip olmak, görünüm hiyerarşisinin bir parçasıdır.