UIView
และ subclasses ของทุกคนมีคุณสมบัติและframe
bounds
ความแตกต่างคืออะไร?
UIView
และ subclasses ของทุกคนมีคุณสมบัติและframe
bounds
ความแตกต่างคืออะไร?
คำตอบ:
ขอบเขตของUIViewเป็นรูปสี่เหลี่ยมผืนผ้าแสดงเป็นสถานที่ (x, y) และขนาด (กว้างความสูง) เมื่อเทียบกับระบบพิกัดของตัวเอง (0,0)
กรอบของUIViewเป็นรูปสี่เหลี่ยมผืนผ้าแสดงเป็นที่ตั้ง (x, y) และขนาด (กว้างความสูง) เทียบกับ SuperView มันอยู่ภายใน
ลองจินตนาการถึงมุมมองที่มีขนาด 100x100 (กว้าง x สูง) ในตำแหน่งที่ 25,25 (x, y) ของผู้ควบคุม รหัสต่อไปนี้จะพิมพ์ขอบเขตและกรอบของมุมมองนี้:
// 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);
}
และผลลัพธ์ของรหัสนี้คือ:
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
ดังนั้นเราจะเห็นได้ว่าในทั้งสองกรณีความกว้างและความสูงของมุมมองจะเหมือนกันโดยไม่คำนึงว่าเรากำลังดูขอบเขตหรือกรอบ สิ่งที่แตกต่างกันคือตำแหน่ง x, y ของมุมมอง ในกรณีของขอบเขตพิกัด x และ y อยู่ที่ 0,0 เนื่องจากพิกัดเหล่านี้สัมพันธ์กับมุมมองของตัวเอง อย่างไรก็ตามพิกัดเฟรม x และ y นั้นสัมพันธ์กับตำแหน่งของมุมมองภายในมุมมองพาเรนต์ (ซึ่งก่อนหน้านี้เราบอกว่าอยู่ที่ 25,25)
นอกจากนี้ยังมีการนำเสนอที่ยอดเยี่ยมที่ครอบคลุม UIViews ดูสไลด์ 1-20 ซึ่งไม่เพียง แต่อธิบายความแตกต่างระหว่างเฟรมและขอบเขต แต่ยังแสดงตัวอย่างด้วยภาพ
frame = ตำแหน่งและขนาดของมุมมองโดยใช้ระบบพิกัดของมุมมองพาเรนต์
bounds = ตำแหน่งและขนาดของมุมมองโดยใช้ระบบพิกัดของตัวเอง
เพื่อช่วยให้ฉันจำกรอบฉันคิดถึงกรอบรูปบนผนังกรอบรูปบนผนังกรอบรูปเหมือนขอบของมุมมอง ฉันแขวนรูปภาพได้ทุกที่ที่ต้องการบนผนัง ในทำนองเดียวกันฉันสามารถใส่มุมมองได้ทุกที่ที่ฉันต้องการภายในมุมมองหลัก (เรียกอีกอย่างหนึ่งว่า superview) มุมมองของผู้ปกครองเป็นเหมือนกำแพง ที่มาของระบบพิกัดใน iOS นั้นอยู่ที่มุมบนซ้าย เราสามารถใส่มุมมองของเราที่จุดกำเนิดของ superview โดยการตั้งค่าพิกัด xy ของกรอบการดูเป็น (0, 0) ซึ่งเหมือนกับแขวนรูปภาพของเราไว้ที่มุมซ้ายบนสุดของผนัง หากต้องการเลื่อนไปทางขวาให้เพิ่ม x เพื่อเลื่อนลงเพิ่มขึ้น y
เพื่อช่วยให้ฉันจำขอบเขตได้ฉันนึกถึงสนามบาสเก็ตบอลซึ่งบางครั้งบาสเก็ตก็ล้มลงบาสเก็ตที่ได้รับการเคาะออกจากขอบเขตคุณกำลังเลี้ยงลูกฟุตบอลอยู่ทั่วสนามบาสเก็ตบอล แต่คุณไม่สนใจว่าตัวเองอยู่ที่ไหนในสนาม อาจเป็นในโรงยิมหรือนอกโรงเรียนมัธยมหรือหน้าบ้านของคุณ มันไม่สำคัญ คุณแค่ต้องการเล่นบาสเก็ตบอล ในทำนองเดียวกันระบบพิกัดสำหรับขอบเขตของมุมมองจะสนใจเฉพาะมุมมองเท่านั้น ไม่ทราบว่ามีมุมมองใดอยู่ในมุมมองพาเรนต์ จุดเริ่มต้นขอบเขต (จุด (0, 0) ตามค่าเริ่มต้น) คือมุมซ้ายบนของมุมมอง มุมมองย่อยใด ๆ ที่มุมมองนี้ถูกจัดวางไว้สัมพันธ์กับประเด็นนี้ มันเหมือนกับการพาบาสเก็ตบอลไปที่มุมซ้ายด้านหน้าของศาล
ตอนนี้ความสับสนเกิดขึ้นเมื่อคุณพยายามเปรียบเทียบเฟรมและขอบเขต แม้ว่ามันจะไม่เลวร้ายอย่างที่คิดในตอนแรก ลองใช้รูปภาพเพื่อช่วยให้เราเข้าใจ
ในภาพแรกทางซ้ายเรามีมุมมองที่อยู่ด้านซ้ายบนของมุมมองหลัก สี่เหลี่ยมสีเหลืองแสดงถึงเฟรมของมุมมอง ทางด้านขวาเราจะเห็นมุมมองอีกครั้ง แต่คราวนี้มุมมองหลักจะไม่ปรากฏ นั่นเป็นเพราะขอบเขตไม่รู้เกี่ยวกับมุมมองหลัก สี่เหลี่ยมสีเขียวแสดงถึงขอบเขตของมุมมอง จุดสีแดงในภาพทั้งสองหมายถึงแหล่งที่มาของกรอบหรือขอบเขต
Frame
origin = (0, 0)
width = 80
height = 130
Bounds
origin = (0, 0)
width = 80
height = 130
ดังนั้นกรอบและขอบเขตจึงเหมือนกันในภาพนั้น ลองดูตัวอย่างที่พวกเขาแตกต่างกัน
Frame
origin = (40, 60) // That is, x=40 and y=60
width = 80
height = 130
Bounds
origin = (0, 0)
width = 80
height = 130
ดังนั้นคุณจะเห็นได้ว่าการเปลี่ยนพิกัด xy ของเฟรมเลื่อนไปในมุมมองพาเรนต์ แต่เนื้อหาของมุมมองนั้นยังคงเหมือนเดิม ขอบเขตไม่มีความคิดว่าสิ่งใดที่แตกต่าง
ถึงตอนนี้ความกว้างและความสูงของทั้งเฟรมและขอบเขตเท่ากันทุกประการ นั่นไม่จริงเสมอไป ดูว่าเกิดอะไรขึ้นถ้าเราหมุนมุมมอง 20 องศาตามเข็มนาฬิกา (การหมุนทำได้โดยใช้การแปลงดูเอกสารประกอบและตัวอย่างมุมมองและเลเยอร์เหล่านี้สำหรับข้อมูลเพิ่มเติม)
Frame
origin = (20, 52) // These are just rough estimates.
width = 118
height = 187
Bounds
origin = (0, 0)
width = 80
height = 130
คุณจะเห็นว่าขอบเขตยังคงเหมือนเดิม พวกเขายังไม่รู้ว่าเกิดอะไรขึ้น! แม้ว่าค่าเฟรมจะเปลี่ยนไปทั้งหมด
ทีนี้มันง่ายกว่าที่จะเห็นความแตกต่างระหว่างเฟรมกับขอบเขตใช่ไหม? บทความที่คุณอาจไม่เข้าใจเฟรมและขอบเขตกำหนดกรอบมุมมองเป็น
... กล่องขอบเขตที่เล็กที่สุดของมุมมองนั้นเกี่ยวกับระบบการปกครองของผู้ประสานงานรวมถึงการแปลงใด ๆ ที่ใช้กับมุมมองนั้น
เป็นสิ่งสำคัญที่จะต้องทราบว่าหากคุณเปลี่ยนมุมมองกรอบจะไม่ได้กำหนด ดังนั้นจริง ๆ แล้วกรอบสีเหลืองที่ฉันวาดรอบขอบเขตสีเขียวที่หมุนในภาพด้านบนไม่เคยมีอยู่จริง นั่นหมายความว่าถ้าคุณหมุนปรับขนาดหรือทำการแปลงอื่น ๆ คุณไม่ควรใช้ค่าเฟรมอีกต่อไป คุณยังสามารถใช้ค่าขอบเขตได้ เอกสารของ Apple เตือนว่า:
สำคัญ:ถ้า
transform
คุณสมบัติของมุมมองไม่มีการแปลงข้อมูลเฉพาะตัวเฟรมของมุมมองนั้นจะไม่ได้ถูกกำหนดและผลลัพธ์ของพฤติกรรมการเปลี่ยนขนาดอัตโนมัติจะเป็นเช่นนั้น
ค่อนข้างโชคร้ายเกี่ยวกับการปรับขนาดอัตโนมัติ .... มีบางอย่างที่คุณสามารถทำได้
เมื่อแก้ไข
transform
คุณสมบัติของมุมมองของคุณการแปลงทั้งหมดจะดำเนินการสัมพันธ์กับจุดกึ่งกลางของมุมมอง
ดังนั้นหากคุณต้องการย้ายมุมมองไปรอบ ๆ ในพาเรนต์หลังจากการแปลงเสร็จสิ้นคุณสามารถทำได้โดยเปลี่ยนview.center
พิกัด ชอบframe
, center
ใช้ระบบการประสานงานในมุมมองของผู้ปกครอง
ตกลงมากำจัดการหมุนของเราและมุ่งไปที่ขอบเขต จนถึงจุดเริ่มต้นขอบเขตยังคงอยู่ที่ (0, 0) ไม่จำเป็นต้องทำ เกิดอะไรขึ้นถ้ามุมมองของเรามีมุมมองย่อยขนาดใหญ่ที่ใหญ่เกินกว่าจะแสดงพร้อมกันทั้งหมด เราจะทำให้มันเป็นUIImageView
ภาพขนาดใหญ่ นี่คือภาพที่สองของเราจากด้านบนอีกครั้ง แต่คราวนี้เราสามารถเห็นเนื้อหาทั้งหมดของมุมมองย่อยของมุมมองของเราจะเป็นอย่างไร
Frame
origin = (40, 60)
width = 80
height = 130
Bounds
origin = (0, 0)
width = 80
height = 130
เฉพาะมุมซ้ายบนของรูปภาพเท่านั้นที่สามารถใส่ในขอบเขตของมุมมองได้ ทีนี้ลองดูว่าเกิดอะไรขึ้นถ้าเราเปลี่ยนพิกัดจุดกำเนิดของขอบเขต
Frame
origin = (40, 60)
width = 80
height = 130
Bounds
origin = (280, 70)
width = 80
height = 130
เฟรมไม่ได้ย้ายไปอยู่ใน superview แต่เนื้อหาภายในเฟรมเปลี่ยนไปเนื่องจากจุดเริ่มต้นของขอบเขตสี่เหลี่ยมผืนผ้าเริ่มต้นที่ส่วนอื่นของมุมมอง นี่เป็นแนวคิดทั้งหมดที่อยู่เบื้องหลังUIScrollView
และเป็นคลาสย่อย (ตัวอย่างเช่น a UITableView
) ดูการทำความเข้าใจกับ UIScrollViewสำหรับคำอธิบายเพิ่มเติม
เนื่องจากframe
เกี่ยวข้องกับตำแหน่งของมุมมองในมุมมองพาเรนต์คุณจึงใช้มุมมองนั้นเมื่อคุณทำการเปลี่ยนแปลงภายนอกเช่นเปลี่ยนความกว้างหรือค้นหาระยะห่างระหว่างมุมมองและด้านบนของมุมมองพาเรนต์
ใช้bounds
เวลาที่คุณทำการเปลี่ยนแปลงภายในเช่นวาดสิ่งหรือจัดเรียงหัวข้อย่อยภายในมุมมอง ใช้ขอบเขตเพื่อให้ได้ขนาดของมุมมองถ้าคุณทำ transfomation กับมัน
เอกสารของ Apple
คำถาม StackOverflow ที่เกี่ยวข้อง
แหล่งข้อมูลอื่น ๆ
นอกจากการอ่านบทความข้างต้นมันช่วยฉันได้มากในการสร้างแอปทดสอบ คุณอาจต้องการลองทำสิ่งที่คล้ายกัน (ฉันได้ความคิดจากหลักสูตรวิดีโอนี้แต่น่าเสียดายที่มันไม่ฟรี)
นี่คือรหัสสำหรับการอ้างอิงของคุณ:
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
พยายามเรียกใช้รหัสด้านล่าง
- (void)viewDidLoad {
[super viewDidLoad];
UIWindow *w = [[UIApplication sharedApplication] keyWindow];
UIView *v = [w.subviews objectAtIndex:0];
NSLog(@"%@", NSStringFromCGRect(v.frame));
NSLog(@"%@", NSStringFromCGRect(v.bounds));
}
ผลลัพธ์ของรหัสนี้คือ:
การวางแนวของอุปกรณ์เคสคือแนวตั้ง
{{0, 0}, {768, 1024}}
{{0, 0}, {768, 1024}}
การวางแนวของอุปกรณ์เคสคือแนวนอน
{{0, 0}, {768, 1024}}
{{0, 0}, {1024, 768}}
เห็นได้ชัดว่าคุณสามารถเห็นความแตกต่างระหว่างกรอบและขอบเขต
กรอบเป็นรูปสี่เหลี่ยมผืนผ้าที่กำหนด UIView ด้วยความเคารพต่อ SuperView
ขอบเขตดูแลรักษาเป็นช่วงของค่าที่กำหนดว่าNSView เป็นระบบพิกัด
คือทุกอย่างในสี่เหลี่ยมนี้จะแสดงใน UIView
frameคือจุดเริ่มต้น (มุมบนซ้าย) และขนาดของมุมมองในระบบพิกัดของมุมมอง super ซึ่งหมายความว่าคุณแปลมุมมองในมุมมอง super โดยการเปลี่ยนต้นกำเนิดของเฟรมขอบเขตในทางกลับกันคือขนาดและต้นกำเนิดใน ระบบพิกัดของตัวเองดังนั้นโดยค่าเริ่มต้นขอบเขตที่มาคือ (0,0)
เวลาส่วนใหญ่ของกรอบและขอบเขตจะสอดคล้องกัน แต่ถ้าคุณมีมุมมองของเฟรม ((140,65), (200,250)) และขอบเขต ((0,0), (200,250)) และมุมมองเอียง เพื่อให้มันยืนที่มุมขวาล่างจากนั้นขอบเขตจะยังคงอยู่ ((0,0), (200,250)) แต่เฟรมไม่ได้
เฟรมจะเป็นสี่เหลี่ยมที่เล็กที่สุดที่ห่อหุ้ม / ล้อมรอบมุมมองดังนั้นเฟรม (ดังในรูปภาพ) จะเป็น (140,65), (320,320))
ข้อแตกต่างอีกอย่างคือถ้าคุณมี superView ที่มีขอบเขต ((0,0), (200,200)) และ superView นี้มี subView ที่มีเฟรมคือ ((20,20), (100,100)) และคุณเปลี่ยนขอบเขต superView ถึง ((20,20), (200,200)) จากนั้นเฟรมย่อยจะยังคง ((20,20), (100,100)) แต่ชดเชยด้วย (20,20) เพราะระบบพิกัดของผู้ประสานงานถูกชดเชยด้วย (20, 20)
ฉันหวังว่านี่จะช่วยให้ใครบางคน
subView
superView
เปลี่ยนsuperView
ขอบเขตเพื่ออะไรจะไม่ให้ตรงกับต้นกำเนิดของมันsubView
superView
จัดวางเฟรมสัมพันธ์กับ SuperView ในขณะที่ขอบเขตสัมพันธ์กับ NSView
ตัวอย่าง: X = 40, Y = 60.Also มี 3 Views.This แผนภาพแสดงความคิดที่ชัดเจน
ให้ฉันเพิ่ม 5 เซนต์ของฉัน
กรอบถูกใช้โดยมุมมองพาเรนต์ของมุมมองเพื่อวางไว้ในมุมมองพาเรนต์
ขอบเขตจะถูกใช้โดยมุมมองเพื่อวางเนื้อหาของตัวเอง (เช่นมุมมองการเลื่อนในขณะที่เลื่อน) ดูเพิ่มเติมคลิปไปที่ขอบเขต ขอบเขตยังสามารถใช้เพื่อซูมเข้า / ออกเนื้อหาของมุมมอง
ความคล้ายคลึง:
กรอบ ~ หน้าจอทีวี
ขอบเขต ~ กล้อง (ซูมย้ายหมุน)
คำตอบข้างต้นอธิบายความแตกต่างระหว่างขอบเขตและเฟรมได้ดีมาก
ขอบเขต: มุมมองขนาดและตำแหน่งตามระบบพิกัดของตัวเอง
กรอบ: ขนาดมุมมองและตำแหน่งสัมพันธ์กับ SuperView
จากนั้นมีความสับสนว่าในกรณีของขอบเขต X, Y จะเป็น "0" เสมอ นี้ไม่เป็นความจริง สิ่งนี้สามารถเข้าใจได้ใน UIScrollView และ UICollectionView เช่นกัน
เมื่อขอบเขต 'x, y ไม่ใช่ 0
ลองสมมุติว่าเรามี UIScrollView เราได้ดำเนินการให้เลขหน้า UIScrollView มี 3 หน้าและความกว้างของ ContentSize คือสามเท่าของความกว้างหน้าจอ (สมมติว่า ScreenWidth คือ 320) ความสูงนั้นคงที่ (สมมติ 200)
scrollView.contentSize = CGSize(x:320*3, y : 200)
เพิ่ม UIImageViews สามรายการเป็นมุมมองย่อยและดูค่าxของเฟรมอย่างใกล้ชิด
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)
หน้า 0: เมื่อ ScrollView เป็น 0 หน้าขอบเขตจะเป็น (x: 0, y: 0, ความกว้าง: 320, ความสูง: 200)
หน้า 1: เลื่อนและย้ายไปที่หน้า 1.
ตอนนี้ขอบเขตจะเป็น(x: 320, y: 0, ความกว้าง: 320, ความสูง: 200)
จำไว้ว่าเราพูดด้วยความเคารพต่อระบบพิกัดของมันเอง ดังนั้นตอนนี้ "ส่วนที่มองเห็นได้" ของ ScrollView ของเรามี "x" ที่ 320 ดูที่เฟรมของ imageView1
เช่นเดียวกับกรณีของ UICollectionView วิธีที่ง่ายที่สุดในการดูคอลเล็กชัน View คือการเลื่อนและพิมพ์ / บันทึกขอบเขตและคุณจะได้รับแนวคิด
คำตอบทั้งหมดข้างต้นถูกต้องและนี่คือสิ่งที่ฉันทำในสิ่งนี้:
หากต้องการแยกความแตกต่างระหว่างเฟรมและขอบเขต CONCEPTS ผู้พัฒนาควรอ่าน:
- สัมพันธ์กับ superview (มุมมองพาเรนต์หนึ่งรายการ) ซึ่งอยู่ภายใน = FRAME
- สัมพันธ์กับระบบพิกัดของตัวเองกำหนดตำแหน่งย่อย = BOUNDS
"ขอบเขต" ทำให้เกิดความสับสนเนื่องจากให้การแสดงผลว่าพิกัดเป็นตำแหน่งของมุมมองที่ตั้งค่าไว้ แต่สิ่งเหล่านี้อยู่ในความสัมพันธ์และปรับเปลี่ยนตามค่าคงที่ของเฟรม
อีกหนึ่งภาพประกอบเพื่อแสดงความแตกต่างระหว่างกรอบและขอบเขต ในตัวอย่างนี้:
View B
เป็นมุมมองย่อยของ View A
View B
ถูกย้ายไปที่ x:60, y: 20
View B
ถูกหมุน 45 degrees
กรอบเทียบกับที่ถูกผูกไว้
frame = ตำแหน่งและขนาดของมุมมองโดยใช้ระบบพิกัดของมุมมองพาเรนต์
bounds = ตำแหน่งและขนาดของมุมมองโดยใช้ระบบพิกัดของตัวเอง
มุมมองจะติดตามขนาดและตำแหน่งโดยใช้สองรูปสี่เหลี่ยมผืนผ้า: กรอบรูปสี่เหลี่ยมผืนผ้าและรูปสี่เหลี่ยมผืนผ้าขอบเขต กรอบสี่เหลี่ยมกำหนดตำแหน่งและขนาดของมุมมองใน superview โดยใช้ระบบพิกัดของ superview ขอบเขตขอบเขตกำหนดระบบพิกัดภายในที่ใช้เมื่อวาดเนื้อหาของมุมมองรวมถึงที่มาและการปรับสเกล รูปที่ 2-1 แสดงให้เห็นถึงความสัมพันธ์ระหว่างกรอบสี่เหลี่ยมทางด้านซ้ายและขอบด้านขวาทางด้านขวา”
กล่าวโดยสรุปเฟรมคือแนวคิดของมุมมองของ superview และขอบเขตคือแนวคิดของมุมมอง การมีหลายระบบการประสานงานระบบหนึ่งสำหรับแต่ละมุมมองเป็นส่วนหนึ่งของลำดับชั้นมุมมอง