ฉันเพิ่งเริ่มเรียนรู้ AutoLayout สำหรับ iOS และดูภาษารูปแบบภาพ
ทุกอย่างทำงานได้ดียกเว้นสิ่งหนึ่ง: ฉันไม่สามารถรับมุมมองไปยังศูนย์ภายในกำกับ
เป็นไปได้ด้วย VFL หรือฉันจำเป็นต้องสร้างข้อ จำกัด ด้วยตนเอง?
ฉันเพิ่งเริ่มเรียนรู้ AutoLayout สำหรับ iOS และดูภาษารูปแบบภาพ
ทุกอย่างทำงานได้ดียกเว้นสิ่งหนึ่ง: ฉันไม่สามารถรับมุมมองไปยังศูนย์ภายในกำกับ
เป็นไปได้ด้วย VFL หรือฉันจำเป็นต้องสร้างข้อ จำกัด ด้วยตนเอง?
คำตอบ:
ขณะนี้ไม่ดูเหมือนว่าจะเป็นไปได้ที่จะจัดมุมมองให้อยู่กึ่งกลางใน superview โดยใช้VFL เท่านั้น อย่างไรก็ตามเป็นเรื่องยากที่จะใช้สาย VFL เดี่ยวและข้อ จำกัด พิเศษเดียว (ต่อแกน):
VFL: "|-(>=20)-[view]-(>=20)-|"
[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:view.superview
attribute:NSLayoutAttributeCenterX
multiplier:1.f constant:0.f];
มีใครคิดว่าคุณสามารถทำได้ (ซึ่งเป็นสิ่งที่ฉันคิดตอนแรกและลองเมื่อฉันเห็นคำถามนี้):
[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>=20)-[view(==200)]-(>=20)-|"
options: NSLayoutFormatAlignAllCenterX | NSLayoutFormatAlignAllCenterY
metrics:nil
views:@{@"view" : view}];
ฉันลองใช้รูปแบบที่แตกต่างกันของหลายข้อที่พยายามดัดโค้งตามความประสงค์ของฉัน แต่สิ่งนี้ดูเหมือนจะไม่ใช้กับผู้ดูแลแม้ว่าจะมีสาย VFL สองสายแยกกันสำหรับทั้งสองแกน ( H:|V:
) จากนั้นผมก็เริ่มที่จะลองและแยกว่าเมื่อตัวเลือกไม่ได้นำไปใช้กับ VFL ดูเหมือนว่าจะไม่ใช้กับผู้ดูแลใน VFL และจะใช้กับมุมมองที่ชัดเจนใด ๆ ที่กล่าวถึงในสตริง VFL (ซึ่งน่าผิดหวังในบางกรณี)
ฉันหวังว่าในอนาคต Apple จะเพิ่มตัวเลือกใหม่บางประเภทเพื่อให้ตัวเลือก VFL คำนึงถึงผู้ดูแลแม้ว่าจะทำเฉพาะเมื่อมีเพียงมุมมองที่ชัดเจนเพียงอย่างเดียวนอกเหนือจากการกำกับดูแลใน VFL ทางออกก็อาจจะเป็นอีกทางเลือกหนึ่งผ่านเข้าสู่ VFL NSLayoutFormatOptionIncludeSuperview
ที่บอกว่าสิ่งที่ชอบ:
จำเป็นต้องพูดฉันเรียนรู้มากมายเกี่ยวกับ VFL พยายามตอบคำถามนี้
|
และ[superview]
แยกเอนทิตีภายในแม้ว่ามันจะเป็นตัวแทนของความหมายเดียวกัน โดยการใช้การหาค่าอัตโนมัติ[superview]
จะรวมถึงวัตถุ superview ในการวัดการจัดตำแหน่งของมัน (ในกรณีที่คำตอบของเขาที่ลิงก์ github คือNSLayoutFormatAlignAllCenterY
/ the X
metric)
ใช่เป็นไปได้ที่จะจัดมุมมองให้อยู่กึ่งกลางในมุมมองของมันด้วยภาษาของรูปแบบภาพ ทั้งในแนวตั้งและแนวนอน นี่คือตัวอย่าง:
ฉันคิดว่าการสร้างข้อ จำกัด ด้วยตนเองจะดีกว่า
[superview addConstraint:
[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
[superview addConstraint:
[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:superview
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0]];
ตอนนี้เราสามารถใช้NSLayoutAnchorเพื่อกำหนด AutoLayout โดยทางโปรแกรม:
(มีให้ใน iOS 9.0 และใหม่กว่า)
view.centerXAnchor.constraint(equalTo: superview.centerXAnchor).isActive = true
view.centerYAnchor.constraint(equalTo: superview.centerYAnchor).isActive = true
ฉันแนะนำให้ใช้SnapKitซึ่งเป็น DSL เพื่อให้การจัดวางอัตโนมัติทำได้ง่ายทั้งใน iOS และ macOS
view.snp.makeConstraints({ $0.center.equalToSuperview() })
Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.
เป็นไปได้อย่างที่สุดก็สามารถทำได้เช่นนี้:
[NSLayoutConstraint constraintsWithVisualFormat:@"H:[view]-(<=1)-[subview]"
options:NSLayoutFormatAlignAllCenterY
metrics:nil
views:NSDictionaryOfVariableBindings(view, subview)];
เรียนรู้สิ่งนี้จากที่นี่ โค้ดด้านบนกึ่งกลาง subview ในมุมมองโดย Y แน่นอน
Swift3:
NSLayoutConstraint.constraints(withVisualFormat: "H:[view]-(<=1)-[subview]",
options: .alignAllCenterY,
metrics: nil,
views: ["view":self, "subview":_spinnerView])
เพิ่มรหัสด้านล่างและให้ปุ่มของคุณอยู่ตรงกลางของหน้าจอ เป็นไปได้อย่างแน่นอน
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-[button]-|"
options:NSLayoutFormatAlignAllCenterY
metrics:0
views:views]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-[button]-|"
options:NSLayoutFormatAlignAllCenterX
metrics:0
views:views]];
ฉันรู้ว่ามันไม่ต้องการที่คุณต้องการ แต่แน่นอนคุณสามารถคำนวณระยะขอบและใช้พวกเขาเพื่อสร้างสตริงรูปแบบภาพ;)
อย่างไรก็ตามไม่มี น่าเสียดายที่มันเป็นไปไม่ได้ที่จะทำอย่างนั้น 'อัตโนมัติ' กับ VFL - อย่างน้อยยังไม่ได้
ขอบคุณคำตอบจาก @Evgenii ฉันสร้างตัวอย่างเต็มรูปแบบในส่วนสำคัญ:
จัดกึ่งกลางสี่เหลี่ยมสีแดงตามแนวตั้งด้วยความสูงที่กำหนดเอง
https://gist.github.com/yallenh/9fc2104b719742ae51384ed95dcaf626
คุณสามารถจัดมุมมองในแนวตั้งให้อยู่กึ่งกลางได้โดยใช้ VFL (ซึ่งไม่ง่ายนัก) หรือใช้ข้อ จำกัด ด้วยตนเอง อย่างไรก็ตามฉันไม่สามารถรวมทั้ง centerY และ height เข้าด้วยกันใน VFL เช่น:
"H:[subView]-(<=1)-[followIcon(==customHeight)]"
ในข้อ จำกัด VFL ของโซลูชันปัจจุบันถูกเพิ่มแยกต่างหาก
สิ่งที่ต้องทำคือควรประกาศผู้ควบคุมดูแลในพจนานุกรม แทนการใช้ที่คุณใช้|
@{@"super": view.superview};
และNSLayoutFormatAlignAllCenterX
สำหรับแนวตั้งและNSLayoutFormatAlignAllCenterY
แนวนอนเป็นตัวเลือก
คุณสามารถใช้มุมมองพิเศษ
NSDictionary *formats =
@{
@"H:|[centerXView]|": @0,
@"V:|[centerYView]|": @0,
@"H:[centerYView(0)]-(>=0)-[yourView]": @(NSLayoutFormatAlignAllCenterY),
@"V:[centerXView(0)]-(>=0)-[yourView]": @(NSLayoutFormatAlignAllCenterX),
};
NSDictionary *views = @{
@"centerXView": centerXView,
@"centerYView": centerYView,
@"yourView": yourView,
};
^(NSString *format, NSNumber *options, BOOL *stop) {
[superview addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:format
options:options.integerValue
metrics:nil
views:views]];
}];
centerXView.hidden = centerYView.hidden = YES;
ถ้าคุณอยากให้มันเรียบร้อยแล้ว
PS: ฉันไม่แน่ใจว่าฉันสามารถเรียกมุมมองเพิ่มเติม "ตัวยึด" เพราะภาษาอังกฤษเป็นภาษาที่สองของฉัน มันจะได้รับการชื่นชมถ้าใครบางคนสามารถบอกฉันว่า
สำหรับผู้ที่มาที่นี่เพื่อInterface Builder
แก้ปัญหาตาม (Google ทำให้ฉันที่นี่) เพียงเพิ่มข้อ จำกัด ความกว้าง / ความสูง const และเลือกมุมมองย่อย -> ควบคุมการลากไปที่ superview -> เลือก "กึ่งกลางแนวนอน / แนวนอนใน superview"
//create a 100*100 rect in the center of superView
var consts = NSLayoutConstraint.constraints(withVisualFormat: "H:|-space-[myView]-space-|", options: [], metrics:["space":view.bounds.width/2-50], views:["myView":myView])
consts += NSLayoutConstraint.constraints(withVisualFormat: "V:|-space-[myView]-space-|", options: [], metrics: ["space":view.bounds.height/2-50], views: ["myView":myView])
เพียงแค่ต้องบอกว่าคุณสามารถใช้สิ่งนี้แทนข้อ จำกัด :
child.center = [parent convertPoint:parent.center fromView:parent.superview];
@ igor-muzykaตอบในSwift 2 :
NSLayoutConstraint.constraintsWithVisualFormat("H:[view]-(<=1)-[subview]",
options: .AlignAllCenterY,
metrics: nil,
views: ["view":view, "subview":subview])
แทนที่จะใช้ VFL คุณสามารถทำได้ในส่วนต่อประสานผู้สร้าง ในกระดานเรื่องราวหลัก ctrl + คลิกที่มุมมองที่คุณต้องการจัดกึ่งกลาง ลากไปที่ superview (ในขณะที่กดปุ่ม ctrl) แล้วเลือก "Center X" หรือ "Center Y" ไม่จำเป็นต้องใช้รหัส