เลย์เอาต์อัตโนมัติด้วย UIViews ที่ซ่อนอยู่หรือไม่


164

ฉันรู้สึกว่ามันเป็นกระบวนทัศน์ที่ใช้กันทั่วไปในการแสดง / ซ่อนUIViewsบ่อยที่สุดUILabelsขึ้นอยู่กับตรรกะทางธุรกิจ คำถามของฉันคือวิธีที่ดีที่สุดในการใช้ AutoLayout เพื่อตอบสนองต่อมุมมองที่ซ่อนอยู่ราวกับว่าเฟรมเป็น 0x0 นี่คือตัวอย่างของรายการแบบไดนามิกของคุณสมบัติ 1-3

รายการคุณสมบัติแบบไดนามิก

ตอนนี้ฉันมีพื้นที่บน 10px จากปุ่มไปยังป้ายกำกับสุดท้ายซึ่งแน่นอนจะไม่เลื่อนขึ้นเมื่อมีการซ่อนป้ายกำกับ ณ ตอนนี้ฉันได้สร้างทางออกให้กับข้อ จำกัด นี้และแก้ไขค่าคงที่ตามจำนวนป้ายที่ฉันกำลังแสดง เห็นได้ชัดว่านี่เป็นเรื่องเล็กน้อยเนื่องจากฉันใช้ค่าคงที่ติดลบเพื่อกดปุ่มขึ้นไปบนเฟรมที่ซ่อนอยู่ มันก็ไม่ดีเช่นกันเพราะมันไม่ได้ถูก จำกัด ด้วยองค์ประกอบเลย์เอาต์ที่แท้จริงเพียงแค่การคำนวณแบบคงที่ซึ่งไม่น่าเชื่อตามความสูง / การซ้อนขององค์ประกอบอื่น ๆ และการต่อสู้กับสิ่งที่ AutoLayout สร้างขึ้น

เห็นได้ชัดว่าฉันสามารถสร้างข้อ จำกัด ใหม่ ๆ ได้ขึ้นอยู่กับป้ายกำกับแบบไดนามิกของฉัน แต่นั่นเป็นเรื่องเล็กมากและการใช้คำฟุ่มเฟือยมากสำหรับการพยายามที่จะยุบช่องว่างบางส่วน มีแนวทางที่ดีกว่านี้ไหม? การเปลี่ยนขนาดเฟรม 0,0 และให้ AutoLayout ทำสิ่งนั้นโดยไม่มีการควบคุมข้อ จำกัด ? กำลังลบมุมมองออกทั้งหมดหรือไม่

แม้ว่าโดยสุจริตเพียงแค่ปรับเปลี่ยนค่าคงที่จากบริบทของมุมมองที่ซ่อนอยู่ต้องใช้รหัสบรรทัดเดียวพร้อมการคำนวณอย่างง่าย สร้างข้อ จำกัด ใหม่ด้วย constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:ดูเหมือนจะหนักมาก

แก้ไขกุมภาพันธ์ 2018 : คำตอบดูเบนกับUIStackViews


ขอบคุณ Ryan สำหรับคำถามนี้ ฉันจะถั่วจะทำอย่างไรสำหรับกรณีที่คุณถาม ทุกครั้งที่ฉันตรวจสอบการกวดวิชาสำหรับ autolayout ส่วนใหญ่พูดถึงเว็บไซต์กวดวิชา raywenderlich ซึ่งฉันพบว่ามันยากที่จะทำให้มันออกมา
Nassif

คำตอบ:


82

UIStackViewน่าจะเป็นวิธีที่จะใช้กับ iOS 9+ ไม่เพียงจัดการกับมุมมองที่ซ่อนอยู่ แต่ยังจะลบระยะห่างและระยะขอบเพิ่มเติมหากตั้งค่าอย่างถูกต้อง


8
ระวังเมื่อใช้ UIStackView ใน UITableViewCell สำหรับฉันเมื่อมุมมองมีความซับซ้อนมากการเลื่อนเริ่มจะเปลี่ยนแปลงเร็วซึ่งมันจะพูดติดอ่างทุกครั้งที่เซลล์ถูกเลื่อนเข้า / ออก ภายใต้ฝาครอบ StackView กำลังเพิ่ม / ลบข้อ จำกัด และสิ่งนี้จะไม่จำเป็นต้องมีประสิทธิภาพเพียงพอสำหรับการเลื่อนอย่างราบรื่น
Kento

7
ยินดีที่จะให้ตัวอย่างเล็ก ๆ น้อย ๆ เกี่ยวกับวิธีที่มุมมองสแต็กจัดการกับสิ่งนี้
แปลที่หายไป

@Kento นี้ยังคงเป็นปัญหาสำหรับ iOS 10 หรือไม่?
Crashalot

3
ห้าปีต่อมา ... ฉันควรอัปเดตและตั้งให้เป็นคำตอบที่ยอมรับหรือไม่ ตอนนี้มีให้บริการสามรอบแล้ว
Ryan Romanchuk

1
@RyanRomanchuk คุณควรนี่เป็นคำตอบที่ดีที่สุดตอนนี้ ขอบคุณเบ็น!
Duncan Luk

234

ความชอบส่วนตัวของฉันสำหรับการแสดง / ซ่อนมุมมองคือการสร้าง IBOutlet ด้วยข้อ จำกัด ความกว้างหรือความสูงที่เหมาะสม

ฉันแล้วอัปเดต constantค่าเป็น0ซ่อนหรืออะไรก็ตามที่ควรแสดงค่า

ข้อได้เปรียบที่ยิ่งใหญ่ของเทคนิคนี้คือข้อ จำกัด สัมพัทธ์จะถูกเก็บรักษาไว้ ตัวอย่างเช่นสมมติว่าคุณมีมุมมอง A และดู B พร้อมช่องว่างแนวนอนของx xเมื่อดูความกว้างconstantถูกตั้งค่าเป็น0.fมุมมอง B จะเลื่อนไปทางซ้ายเพื่อเติมเต็มพื้นที่นั้น

ไม่จำเป็นต้องเพิ่มหรือลบข้อ จำกัด ซึ่งเป็นการปฏิบัติการแบบหนา เพียงแค่อัปเดตข้อ จำกัด ก็constantจะทำการหลอกลวง


1
อย่างแน่นอน ตราบใดที่ - ในตัวอย่างนี้คุณวางตำแหน่งมุมมอง B ทางด้านขวาของมุมมอง A โดยใช้ช่องว่างแนวนอน ฉันใช้เทคนิคนี้ตลอดเวลาและทำงานได้ดีมาก
Max MacLeod

9
@ MaxMacLeod เพียงเพื่อให้แน่ใจว่า: หากช่องว่างระหว่างสองมุมมองเป็น x เพื่อให้มุมมอง B เริ่มจากมุมมองตำแหน่ง A เราต้องเปลี่ยนค่าคงที่ของช่องว่างเป็น 0 ด้วยใช่ไหม
kernix

1
@ kernix ใช่ถ้าจะต้องมีการ จำกัด ช่องว่างในแนวนอนระหว่างสองมุมมอง ค่าคงที่ 0 แน่นอนหมายความว่าไม่มีช่องว่าง ดังนั้นการซ่อนมุมมอง A โดยการตั้งค่าความกว้างเป็น 0 จะเลื่อนมุมมอง B ไปทางซ้ายเพื่อล้างข้อมูลด้วยคอนเทนเนอร์ ขอบคุณมากสำหรับการลงคะแนน!
Max MacLeod

2
@ MaxMacLeod ขอบคุณสำหรับคำตอบของคุณ ฉันพยายามทำสิ่งนี้ด้วย UIView ที่มีมุมมองอื่น แต่การดูย่อยของมุมมองนั้นไม่ถูกซ่อนเมื่อฉันตั้งข้อจำกัดความสูงของมันเป็น 0 การแก้ปัญหานี้ควรจะทำงานกับมุมมองที่มีการสัมภาษณ์ย่อยหรือไม่? ขอบคุณ!
Shaunlim

6
นอกจากนี้ยังจะชื่นชมวิธีการแก้ปัญหาที่ทำงานสำหรับ UIView ที่มีมุมมองอื่น ๆ ...
มาร์ค Gibaud

96

วิธีแก้ปัญหาของการใช้ค่าคงที่0เมื่อถูกซ่อนและค่าคงที่อื่นถ้าคุณแสดงอีกครั้งนั้นใช้งานได้ แต่ก็ไม่พอใจหากเนื้อหาของคุณมีขนาดที่ยืดหยุ่น คุณจะต้องวัดเนื้อหาที่มีความยืดหยุ่นและตั้งค่าคงที่ สิ่งนี้ผิดปกติและมีปัญหาหากขนาดเนื้อหาเปลี่ยนแปลงเนื่องจากเซิร์ฟเวอร์หรือกิจกรรม UI

ฉันมีทางออกที่ดีกว่า

แนวคิดคือการตั้งค่ากฎความสูง 0 ให้มีลำดับความสำคัญสูงเมื่อเราซ่อนองค์ประกอบเพื่อไม่ให้มีพื้นที่ว่างอัตโนมัติ

นี่คือวิธีที่คุณทำ:

1. ตั้งค่าความกว้าง (หรือความสูง) เป็น 0 ในตัวสร้างส่วนต่อประสานที่มีลำดับความสำคัญต่ำ

การตั้งค่าความกว้าง 0 กฎ

เครื่องมือสร้างส่วนต่อประสานจะไม่ตะโกนเกี่ยวกับความขัดแย้งเพราะลำดับความสำคัญต่ำ ทดสอบพฤติกรรมความสูงโดยตั้งค่าลำดับความสำคัญเป็น 999 ชั่วคราว (ห้าม 1,000 คนที่จะกลายพันธุ์โดยทางโปรแกรมดังนั้นเราจะไม่ใช้มัน) เครื่องมือสร้างส่วนติดต่ออาจจะตะโกนเกี่ยวกับข้อ จำกัด ที่ขัดแย้งกัน คุณสามารถแก้ไขสิ่งเหล่านี้ได้โดยกำหนดลำดับความสำคัญของวัตถุที่เกี่ยวข้องเป็น 900 หรือมากกว่านั้น

2. เพิ่มทางออกเพื่อให้คุณสามารถแก้ไขลำดับความสำคัญของข้อ จำกัด ความกว้างในรหัส:

การเชื่อมต่อเต้าเสียบ

3. ปรับลำดับความสำคัญเมื่อคุณซ่อนองค์ประกอบของคุณ:

cell.alertTimingView.hidden    = place.closingSoon != true
cell.alertTimingWidth.priority = place.closingSoon == true ? 250 : 999

@SimplGy คุณช่วยบอกหน่อยได้ไหมว่าสถานที่นี้ปิดให้บริการอะไร?
Niharika

มันไม่ได้เป็นส่วนหนึ่งของโซลูชันทั่วไป @Niharika มันเป็นเพียงแค่กฎทางธุรกิจในกรณีของฉัน (แสดงมุมมองว่าร้านอาหาร / ไม่ได้ปิดเร็ว ๆ นี้)
SimplGy

11

ในกรณีนี้ฉันแมปความสูงของป้ายชื่อผู้แต่งกับ IBOutlet ที่เหมาะสม:

@property (retain, nonatomic) IBOutlet NSLayoutConstraint* authorLabelHeight;

และเมื่อฉันตั้งความสูงของข้อ จำกัด เป็น 0.0f เราจะรักษา "ช่องว่างภายใน" เนื่องจากความสูงของปุ่ม Play อนุญาตให้ทำได้

cell.authorLabelHeight.constant = 0; //Hide 
cell.authorLabelHeight.constant = 44; //Show

ป้อนคำอธิบายรูปภาพที่นี่


9

มีวิธีแก้ไขมากมายที่นี่ แต่วิธีการปกติของฉันแตกต่างกันอีกครั้ง :)

ตั้งค่าข้อ จำกัด สองชุดคล้ายกับคำตอบของ Jorge Arimany และ TMin:

ป้อนคำอธิบายรูปภาพที่นี่

ทั้งสามข้อ จำกัด ที่ทำเครื่องหมายมีค่าเดียวกันสำหรับค่าคงที่ ข้อ จำกัด ที่ทำเครื่องหมาย A1 และ A2 ตั้งค่าระดับความสำคัญเป็น 500 ในขณะที่ข้อ จำกัด ที่ทำเครื่องหมาย B นั้นตั้งค่าระดับความสำคัญเป็น 250 (หรือเป็นUILayoutProperty.defaultLowรหัส)

เชื่อมต่อข้อ จำกัด B กับ IBOutlet จากนั้นเมื่อคุณซ่อนองค์ประกอบคุณเพียงแค่ต้องตั้งค่าลำดับความสำคัญของข้อ จำกัด เป็นสูง (750):

constraintB.priority = .defaultHigh

แต่เมื่อองค์ประกอบมองเห็นได้ให้ตั้งค่าลำดับความสำคัญเป็นต่ำ (250):

constraintB.priority = .defaultLow

ข้อได้เปรียบ (เล็กน้อยที่ยอมรับได้) ของวิธีการนี้มากกว่าเพียงแค่เปลี่ยนisActiveข้อ จำกัด B คือคุณยังคงมีข้อ จำกัด ในการทำงานหากองค์ประกอบชั่วคราวถูกลบออกจากมุมมองโดยวิธีการอื่น


นี่คือข้อดีของการไม่มีค่าซ้ำกันใน Storyboard และรหัสเช่นความสูง / ความกว้างขององค์ประกอบ สง่างามมาก.
Robin Daugherty

ขอบคุณ !! มันช่วยฉัน
Parth Barot

วิธีการที่ยอดเยี่ยมขอบคุณ
โหระพา

5

func intrinsicContentSize() -> CGSizeระดับชั้นย่อยมุมมองและแทนที่ เพียงแค่กลับไปCGSizeZeroหากมุมมองถูกซ่อนอยู่


2
มันเยี่ยมมาก บางองค์ประกอบ UI ต้องเรียกไปinvalidateIntrinsicContentSizeแม้ว่า setHiddenคุณสามารถทำได้ในแทนที่
DrMickeyLauer

5

ฉันเพิ่งค้นพบว่าเพื่อให้ UILabel ไม่ใช้พื้นที่คุณต้องซ่อนมันและตั้งค่าข้อความเป็นสตริงว่าง (iOS 9)

การรู้ข้อเท็จจริง / ข้อผิดพลาดนี้จะช่วยให้บางคนทำให้เค้าโครงของพวกเขาง่ายขึ้นอาจเป็นไปได้ว่าเป็นคำถามดั้งเดิมดังนั้นฉันจึงคิดว่าฉันโพสต์ไว้


1
ฉันไม่คิดว่าคุณต้องซ่อนมัน การตั้งค่าข้อความเป็นสตริงว่างควรเพียงพอ
Rob VS

4

ฉันประหลาดใจที่ไม่มีวิธีการที่หรูหรากว่าUIKitนี้สำหรับพฤติกรรมที่ต้องการนี้ ดูเหมือนว่าเป็นเรื่องธรรมดามากที่ต้องการจะทำ

เนื่องจากการเชื่อมโยงข้อ จำกัด กับIBOutletsและการตั้งค่าคงที่ให้0รู้สึกแย่ (และทำให้เกิดNSLayoutConstraintคำเตือนเมื่อมุมมองของคุณมีหัวข้อย่อย) ฉันตัดสินใจที่จะสร้างส่วนขยายที่ให้วิธีการที่เรียบง่ายและเป็นรัฐในการซ่อน / แสดงภาพUIViewที่มีข้อ จำกัด

มันซ่อนมุมมองและลบข้อ จำกัด ภายนอกเท่านั้น เมื่อคุณแสดงมุมมองอีกครั้งมันจะเพิ่มข้อ จำกัด กลับมา ข้อแม้เดียวคือคุณจะต้องระบุข้อ จำกัด การเฟลโอเวอร์ที่ยืดหยุ่นกับมุมมองโดยรอบ

แก้ไข คำตอบนี้มีเป้าหมายที่ iOS 8.4 และต่ำกว่า ใน iOS 9 เพียงใช้UIStackViewวิธีนี้


1
นี่เป็นวิธีที่ฉันชอบเช่นกัน เป็นการปรับปรุงที่สำคัญสำหรับคำตอบอื่น ๆ ที่นี่เนื่องจากไม่เพียงแค่ทำให้สควอชมีขนาดเท่ากับศูนย์ วิธีการสควอชจะทำให้เกิดปัญหาสำหรับทุกสิ่งยกเว้นการจ่ายเงินเล็กน้อย ตัวอย่างนี้เป็นช่องว่างขนาดใหญ่ที่รายการที่ซ่อนอยู่ในคำตอบอื่น ๆนี้ และคุณสามารถท้ายด้วยการละเมิดข้อ จำกัด ดังกล่าว
Benjohn

@DanielSchlaug ขอบคุณที่ชี้ให้เห็น ฉันได้อัพเดทใบอนุญาตเป็น MIT แล้ว อย่างไรก็ตามฉันจำเป็นต้องมีจิตใจที่สูงห้าทุกครั้งที่มีคนใช้วิธีนี้
อัลเบิร์ต Bori

4

แนวปฏิบัติที่ดีที่สุดคือเมื่อทุกอย่างมีข้อ จำกัด เลย์เอาต์ที่ถูกต้องเพิ่มความสูงหรือมีข้อ จำกัด ขึ้นอยู่กับว่าคุณต้องการให้มุมมองโดยรอบย้ายและเชื่อมต่อข้อ จำกัด เข้ากับIBOutletคุณสมบัติอย่างไร

ตรวจสอบให้แน่ใจว่าคุณสมบัติของคุณคือ strong

ในรหัส yo เพียงแค่ต้องตั้งค่าคงที่เป็น 0 และเปิดใช้งานมัน, tho ซ่อนเนื้อหา, หรือปิดการใช้งานเพื่อแสดงเนื้อหา นี่คือดีกว่า messing up กับค่าคงที่การบันทึก - คืนค่า อย่าลืมโทรlayoutIfNeededหลังจากนั้น

หากเนื้อหาที่จะซ่อนถูกจัดกลุ่มแนวปฏิบัติที่เหมาะสมที่สุดคือการใส่มุมมองทั้งหมดและเพิ่มข้อ จำกัด ในมุมมองนั้น

@property (strong, nonatomic) IBOutlet UIView *myContainer;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *myContainerHeight; //should be strong!!

-(void) showContainer
{
    self.myContainerHeight.active = NO;
    self.myContainer.hidden = NO;
    [self.view layoutIfNeeded];
}
-(void) hideContainer
{
    self.myContainerHeight.active = YES;
    self.myContainerHeight.constant = 0.0f;
    self.myContainer.hidden = YES;
    [self.view layoutIfNeeded];
}

เมื่อคุณตั้งค่าแล้วคุณสามารถทดสอบใน IntefaceBuilder โดยการตั้งค่าข้อ จำกัด ของคุณเป็น 0 จากนั้นกลับสู่ค่าดั้งเดิม อย่าลืมที่จะตรวจสอบลำดับความสำคัญของข้อ จำกัด อื่น ๆ ดังนั้นเมื่อซ่อนอยู่จะไม่มีความขัดแย้งเลย วิธีอื่นในการทดสอบคือการใส่ค่าเป็น 0 และตั้งค่าระดับความสำคัญเป็น 0 แต่คุณไม่ควรลืมคืนค่าระดับความสำคัญสูงสุดอีกครั้ง


1
นั่นเป็นเพราะข้อ จำกัด และมุมมองไม่สามารถถูกเก็บไว้ในลำดับชั้นการดูได้เสมอดังนั้นหากคุณปิดการใช้งานข้อ จำกัด และซ่อนมุมมองคุณยังคงเก็บมุมมองไว้เพื่อให้ปรากฏขึ้นอีกครั้งโดยไม่คำนึงถึงลำดับชั้นการดู
Jorge Arimany

3

ฉันสร้างหมวดหมู่เพื่อปรับปรุงข้อ จำกัด ได้อย่างง่ายดาย:

[myView1 hideByHeight:YES];

คำตอบที่นี่: ซ่อน autolayout UIView: วิธีรับ NSLayoutConstraint ที่มีอยู่เพื่ออัปเดตอันนี้

ป้อนคำอธิบายรูปภาพที่นี่


8
น่าเสียดายที่คุณมีระยะห่างสองเท่าตรงที่ลูกศรสีเหลืองชี้ไป
Zoltán

ฉันคิดว่าเช่นเดียวกับโซลูชันอื่น ๆ ข้างต้น ไม่เหมาะเลย
Benjohn

2

วิธีที่ฉันชอบนั้นคล้ายกับวิธีที่ Jorge Arimany แนะนำ

ฉันชอบที่จะสร้างข้อ จำกัด หลายอย่าง สร้างข้อ จำกัด ของคุณก่อนเมื่อมองเห็นป้ายกำกับที่สอง สร้างเต้าเสียบสำหรับข้อ จำกัด ระหว่างปุ่มและป้ายกำกับที่ 2 (ถ้าคุณใช้ objc ต้องแน่ใจว่ามันแข็งแรง) ข้อ จำกัด นี้กำหนดความสูงระหว่างปุ่มและป้ายกำกับที่สองเมื่อมองเห็นได้

จากนั้นสร้างข้อ จำกัด อื่นที่ระบุความสูงระหว่างปุ่มและป้ายกำกับด้านบนเมื่อซ่อนปุ่มที่สอง สร้างเต้าเสียบเพื่อข้อ จำกัด ที่สองและตรวจสอบให้แน่ใจว่าเต้าเสียบนี้มีตัวชี้ที่แข็งแกร่ง จากนั้นยกเลิกการinstalledเลือกช่องทำเครื่องหมายในเครื่องมือสร้างส่วนต่อประสานและตรวจสอบให้แน่ใจว่าลำดับความสำคัญข้อ จำกัด แรกนั้นต่ำกว่าลำดับความสำคัญข้อ จำกัด ที่สองนี้

ในที่สุดเมื่อคุณซ่อนป้ายกำกับที่สองสลับ.isActiveคุณสมบัติของข้อ จำกัด และการโทรเหล่านี้setNeedsDisplay()

และนั่นคือไม่มีหมายเลข Magic ไม่มีคณิตศาสตร์หากคุณมีข้อ จำกัด หลายอย่างในการเปิดและปิดคุณสามารถใช้คอลเล็กชันทางออกเพื่อให้พวกเขาจัดการโดยรัฐ (AKA เก็บข้อ จำกัด ที่ซ่อนไว้ทั้งหมดไว้ใน OutletCollection อันหนึ่งและอันที่ไม่ถูกซ่อนอยู่ในอีกอันหนึ่งและทำซ้ำในแต่ละคอลเลกชันเพื่อสลับสถานะ. isActive ของพวกเขา)

ฉันรู้ว่าไรอัน Romanchuk บอกว่าเขาไม่ต้องการใช้ข้อ จำกัด หลายอย่าง แต่ฉันรู้สึกว่านี่ไม่ใช่ micromanage-y และง่ายกว่าที่จะสร้างมุมมองและข้อ จำกัด แบบโปรแกรม (ซึ่งเป็นสิ่งที่ฉันคิดว่าเขาต้องการหลีกเลี่ยงถ้าฉัน กำลังอ่านคำถามถูก)

ฉันได้สร้างตัวอย่างง่ายๆฉันหวังว่าจะเป็นประโยชน์ ...

import UIKit

class ViewController: UIViewController {

    @IBOutlet var ToBeHiddenLabel: UILabel!


    @IBOutlet var hiddenConstraint: NSLayoutConstraint!
    @IBOutlet var notHiddenConstraint: NSLayoutConstraint!


    @IBAction func HideMiddleButton(_ sender: Any) {

        ToBeHiddenLabel.isHidden = !ToBeHiddenLabel.isHidden
        notHiddenConstraint.isActive = !notHiddenConstraint.isActive
        hiddenConstraint.isActive = !hiddenConstraint.isActive

        self.view.setNeedsDisplay()
    }
}

ป้อนคำอธิบายรูปภาพที่นี่


0

ฉันจะให้วิธีแก้ปัญหาของฉันเช่นกันเพื่อเสนอความหลากหลาย) ฉันคิดว่าการสร้างเต้าเสียบสำหรับความกว้าง / ความสูงของแต่ละรายการบวกกับการเว้นวรรคนั้นเป็นเรื่องไร้สาระและทำให้โค้ดระเบิดข้อผิดพลาดที่เป็นไปได้และจำนวนแทรกซ้อน

เมธอดของฉันลบมุมมองทั้งหมด (ในกรณีของฉัน UIImageView อินสแตนซ์), เลือกว่าอันไหนที่จะต้องเพิ่มกลับมาและในลูปมันเพิ่มกลับแต่ละอันและสร้างข้อ จำกัด ใหม่ จริงๆแล้วมันง่ายจริงๆโปรดติดตาม นี่คือรหัสที่รวดเร็วและสกปรกของฉันที่จะทำ:

// remove all views
[self.twitterImageView removeFromSuperview];
[self.localQuestionImageView removeFromSuperview];

// self.recipients always has to be present
NSMutableArray *items;
items = [@[self.recipients] mutableCopy];

// optionally add the twitter image
if (self.question.sharedOnTwitter.boolValue) {
    [items addObject:self.twitterImageView];
}

// optionally add the location image
if (self.question.isLocal) {
    [items addObject:self.localQuestionImageView];
}

UIView *previousItem;
UIView *currentItem;

previousItem = items[0];
[self.contentView addSubview:previousItem];

// now loop through, add the items and the constraints
for (int i = 1; i < items.count; i++) {
    previousItem = items[i - 1];
    currentItem = items[i];

    [self.contentView addSubview:currentItem];

    [currentItem mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(previousItem.mas_centerY);
        make.right.equalTo(previousItem.mas_left).offset(-5);
    }];
}


// here I just connect the left-most UILabel to the last UIView in the list, whichever that was
previousItem = items.lastObject;

[self.userName mas_remakeConstraints:^(MASConstraintMaker *make) {
    make.right.equalTo(previousItem.mas_left);
    make.leading.equalTo(self.text.mas_leading);
    make.centerY.equalTo(self.attachmentIndicator.mas_centerY);;
}];

ฉันทำความสะอาดเค้าโครงและระยะห่างที่สอดคล้องกัน รหัสของฉันใช้ Masonry ฉันขอแนะนำอย่างยิ่ง: https://github.com/SnapKit/Masonry


0

ลองBoxViewมันทำให้การจัดวางแบบไดนามิกกระชับและอ่านง่าย
ในกรณีของคุณมันคือ:

    boxView.optItems = [
        firstLabel.boxed.useIf(isFirstLabelShown),
        secondLabel.boxed.useIf(isSecondLabelShown),
        button.boxed
    ]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.