UIStackView“ ไม่สามารถตอบสนองข้อ จำกัด ได้พร้อมกัน” ในมุมมองที่ซ่อนอยู่“ squished”


97

เมื่อ "แถว" UIStackView ของฉันขาดตอนพวกเขาจะส่งAutoLayoutคำเตือน อย่างไรก็ตามพวกเขาแสดงผลได้ดีและไม่มีอะไรผิดปกตินอกเหนือจากการบันทึกประเภทนี้:

ไม่สามารถปฏิบัติตามข้อ จำกัด พร้อมกันได้ อาจมีข้อ จำกัด อย่างน้อยหนึ่งข้อในรายการต่อไปนี้คือข้อ จำกัด ที่คุณไม่ต้องการ ลองทำสิ่งนี้: (1) ดูข้อ จำกัด แต่ละข้อแล้วลองหาสิ่งที่คุณไม่คาดคิด (2) ค้นหารหัสที่เพิ่มข้อ จำกัด หรือข้อ จำกัด ที่ไม่ต้องการและแก้ไข (หมายเหตุ: หากคุณเห็นNSAutoresizingMaskLayoutConstraintsว่าคุณไม่เข้าใจโปรดดูเอกสารสำหรับUIViewคุณสมบัติtranslatesAutoresizingMaskIntoConstraints) (

ตอนนี้ยังไม่แน่ใจว่าจะแก้ไขอย่างไร แต่ดูเหมือนจะไม่ผิดอะไรนอกจากสร้างความรำคาญ

มีใครรู้วิธีแก้ไหม ที่น่าสนใจคือข้อ จำกัด ของการจัดวางมักจะถูกแท็กด้วย"การซ่อน UISV"ซึ่งบ่งชี้ว่าอาจจะละเลยความสูงต่ำสุดสำหรับมุมมองย่อยหรือบางสิ่งในอินสแตนซ์นี้?


1
ดูเหมือนว่าจะได้รับการแก้ไขใน iOS11 โดยไม่ได้รับคำเตือนใด ๆ ที่นี่
trapper

คำตอบ:


206

คุณได้รับปัญหานี้เนื่องจากเมื่อตั้งค่ามุมมองย่อยจากภายในUIStackViewเป็นแบบซ่อนมุมมองย่อยจะ จำกัด ความสูงไว้ที่ศูนย์ก่อนเพื่อให้มีการเคลื่อนไหว

ฉันได้รับข้อผิดพลาดต่อไปนี้:

2015-10-01 11:45:13.732 <redacted>[64455:6368084] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7f7f5be18c80 V:[UISegmentedControl:0x7f7f5bec4180]-(8)-|   (Names: '|':UIView:0x7f7f5be69d30 )>",
    "<NSLayoutConstraint:0x7f7f5be508d0 V:|-(8)-[UISegmentedControl:0x7f7f5bec4180]   (Names: '|':UIView:0x7f7f5be69d30 )>",
    "<NSLayoutConstraint:0x7f7f5bdfbda0 'UISV-hiding' V:[UIView:0x7f7f5be69d30(0)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7f7f5be18c80 V:[UISegmentedControl:0x7f7f5bec4180]-(8)-|   (Names: '|':UIView:0x7f7f5be69d30 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

สิ่งที่ฉันพยายามทำคือวางUIViewภายในของฉันUIStackViewที่มีสิ่งที่UISegmentedControlใส่เข้าไปในแต่ละขอบ

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

เพื่อแก้ไขปัญหานี้ฉันเปลี่ยนลำดับความสำคัญ 8pt บนสุดของข้อ จำกัด ด้านล่างจาก 1,000 เป็น 999 เพื่อให้UISV-hidingข้อ จำกัด มีลำดับความสำคัญหากจำเป็น


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

4
การเปลี่ยนลำดับความสำคัญก็ใช้ได้ผลกับฉันเช่นกัน นอกจากนี้การลบข้อ จำกัด ส่วนเกิน (สีจาง) ที่คัดลอกโดยไม่ได้ตั้งใจจากคลาสขนาดที่ไม่ได้ใช้ เคล็ดลับที่สำคัญ: เพื่อแก้ไขปัญหาเหล่านี้ได้ง่ายขึ้นให้ตั้งค่าสตริง IDENTIFER ในแต่ละข้อ จำกัด จากนั้นคุณจะเห็นว่าข้อ จำกัด ใดที่ซุกซนในข้อความแก้ไขข้อบกพร่อง
Womble

3
ในกรณีของฉันฉันต้องลดลำดับความสำคัญของความสูงลงเท่านั้นจึงจะได้ผล
pixelfreak

เคล็ดลับ IDENTIFIER นั้นยอดเยี่ยมมาก! ฉันสงสัยเสมอว่าจะให้ข้อ จำกัด ในชื่อข้อความดีบักได้อย่างไรฉันมักจะมองหาที่จะเพิ่มบางสิ่งบางอย่างในมุมมองแทนที่จะเป็นข้อ จำกัด ขอบคุณ @Womble!
Ryan

ขอบคุณ! ลำดับความสำคัญจาก 1,000 ถึง 999 ทำให้เคล็ดลับ Xcode: เวอร์ชัน 8.3.3 (8E3004b)
Michael Garito

54

ฉันประสบปัญหาคล้าย ๆ กันซึ่งแก้ไขได้ไม่ยาก ในกรณีของฉันฉันมีมุมมองสแต็กที่ฝังอยู่ในมุมมองสแต็ก UIStackView ภายในมีป้ายกำกับสองป้ายและระบุระยะห่างที่ไม่ใช่ศูนย์

เมื่อคุณเรียก addArrangedSubview () ระบบจะสร้างข้อ จำกัด ที่คล้ายกับสิ่งต่อไปนี้โดยอัตโนมัติ:

V:|[innerStackView]|              | = outerStackView

  V:|[label1]-(2)-[label2]|       | = innerStackView

ตอนนี้เมื่อคุณพยายามซ่อน innerStackView คุณจะได้รับคำเตือนข้อ จำกัด ที่ไม่ชัดเจน

จะเข้าใจว่าทำไมให้แรกดูว่าทำไมนี้ไม่ได้เกิดขึ้นเมื่อมีค่าเท่ากับinnerStackView.spacing 0เมื่อคุณโทรinnerStackView.hidden = trueไปที่ @niumnichols ถูกต้อง ... outerStackViewจะสกัดกั้นการโทรนี้อย่างน่าอัศจรรย์และสร้างข้อ จำกัด การซ่อน UISV0ความสูงด้วยลำดับความสำคัญ 1,000 (จำเป็น) สันนิษฐานว่านี่เป็นการอนุญาตให้องค์ประกอบในมุมมองสแต็กสามารถเคลื่อนไหวได้เมื่อมองไม่เห็นในกรณีที่รหัสซ่อนของคุณถูกเรียกภายในบล็อก น่าเสียดายที่ดูเหมือนจะไม่มีวิธีป้องกันไม่ให้เพิ่มข้อ จำกัด นี้ อย่างไรก็ตามคุณจะไม่ได้รับคำเตือน "ไม่สามารถปฏิบัติตามข้อ จำกัด พร้อมกัน" (USSC) ได้เนื่องจากสิ่งต่อไปนี้เกิดขึ้น:UIView.animationWithDuration()

  1. ความสูงของ label1 ถูกตั้งค่าเป็น 0
  2. ระยะห่างระหว่างป้ายกำกับทั้งสองถูกกำหนดเป็น 0 แล้ว
  3. ความสูงของ label2 ถูกตั้งค่าเป็น 0
  4. ความสูงของ innerStackView ถูกตั้งค่าเป็น 0

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

ตอนนี้จะกลับไปตัวอย่างเช่นรถถ้าเราตั้งspacingไป2ตอนนี้เรามีข้อ จำกัด เหล่านี้:

  1. ความสูงของ label1 ถูกตั้งค่าเป็น 0
  2. ระยะห่างระหว่างป้ายกำกับทั้งสองถูกสร้างขึ้นโดยอัตโนมัติโดยมุมมองสแต็กสูง 2 พิกเซลที่ลำดับความสำคัญ 1,000
  3. ความสูงของ label2 ถูกตั้งค่าเป็น 0
  4. ความสูงของ innerStackView ถูกตั้งค่าเป็น 0

มุมมองสแต็กไม่สามารถสูงได้ทั้ง 0 พิกเซลและมีเนื้อหาสูง 2 พิกเซล ไม่สามารถตอบสนองข้อ จำกัด ได้

หมายเหตุ: คุณสามารถดูพฤติกรรมนี้ได้จากตัวอย่างที่ง่ายกว่า เพียงแค่เพิ่ม UIView ในมุมมองแบบสแต็กเป็นมุมมองย่อยที่จัดเรียง จากนั้นกำหนดข้อ จำกัด ด้านความสูงให้กับ UIView นั้นด้วยลำดับความสำคัญ 1,000 ตอนนี้ลองโทรซ่อนที่

หมายเหตุ: ไม่ว่าด้วยเหตุผลใดสิ่งนี้จะเกิดขึ้นก็ต่อเมื่อมุมมองสแต็กของฉันเป็นมุมมองย่อยของ UICollectionViewCell หรือ UITableViewCell อย่างไรก็ตามคุณยังคงสามารถสร้างพฤติกรรมนี้ซ้ำนอกเซลล์ได้โดยการโทรinnerStackView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)ใช้ลูปรันถัดไปหลังจากซ่อนมุมมองสแต็กด้านใน

หมายเหตุ: แม้ว่าคุณจะพยายามเรียกใช้โค้ดใน UIView.performWithoutWithoutAnimations มุมมองสแต็กจะยังคงเพิ่มข้อ จำกัด ความสูง 0 ซึ่งจะทำให้เกิดคำเตือน USSC


มีอย่างน้อย 3 วิธีสำหรับปัญหานี้:

  1. ก่อนซ่อนองค์ประกอบใด ๆ ในมุมมองสแต็กให้ตรวจสอบว่าเป็นมุมมองแบบสแต็กหรือไม่และถ้าเป็นเช่นนั้นให้เปลี่ยนเป็นspacing0สิ่งนี้น่ารำคาญเพราะคุณต้องย้อนกระบวนการ (และจำระยะห่างเดิม) เมื่อใดก็ตามที่คุณแสดงเนื้อหาอีกครั้ง
  2. removeFromSuperviewแทนที่จะหลบซ่อนตัวอยู่องค์ประกอบในมุมมองสแต็คโทร สิ่งนี้น่ารำคาญยิ่งขึ้นเนื่องจากเมื่อคุณย้อนกระบวนการคุณต้องจำไว้ว่าที่ไหนจะแทรกรายการที่ถูกลบออกไป คุณสามารถเพิ่มประสิทธิภาพได้โดยเรียกใช้ removeArrangedSubview แล้วจึงซ่อน แต่ยังมีการทำบัญชีจำนวนมากที่ยังต้องทำ
  3. ตัดมุมมองสแต็กที่ซ้อนกัน (ซึ่งไม่มีศูนย์spacing) ใน UIView ระบุข้อ จำกัด อย่างน้อยหนึ่งข้อเป็นลำดับความสำคัญที่ไม่จำเป็น (999 หรือต่ำกว่า) นี่เป็นทางออกที่ดีที่สุดเนื่องจากคุณไม่ต้องทำบัญชีใด ๆ ในตัวอย่างของฉันฉันสร้างข้อ จำกัด ด้านบนนำหน้าและต่อท้ายที่ 1000 ระหว่างมุมมองสแต็กและมุมมองกระดาษห่อหุ้มจากนั้นสร้างข้อ จำกัด 999 จากด้านล่างของมุมมองสแต็กไปยังมุมมองกระดาษห่อหุ้ม ด้วยวิธีนี้เมื่อมุมมองสแต็กภายนอกสร้างข้อ จำกัด ด้านความสูงเป็นศูนย์ข้อ จำกัด 999 จะเสียและคุณไม่เห็นคำเตือนของ USSC (หมายเหตุ: สิ่งนี้คล้ายกับการแก้ปัญหาควรตั้งค่าคลาสย่อย contentView.translatesAutoResizingMaskToConstraints ของ UICollectionViewCell เป็นfalse )

โดยสรุปสาเหตุที่คุณได้รับพฤติกรรมนี้คือ:

  1. Apple สร้างข้อ จำกัด ลำดับความสำคัญ 1,000 รายการให้คุณโดยอัตโนมัติเมื่อคุณเพิ่มมุมมองย่อยที่มีการจัดการลงในมุมมองสแต็ก
  2. Apple จะสร้างข้อ จำกัด ความสูง 0 ให้คุณโดยอัตโนมัติเมื่อคุณซ่อนมุมมองย่อยของมุมมองสแต็ก

หาก Apple (1) อนุญาตให้คุณระบุลำดับความสำคัญของข้อ จำกัด (โดยเฉพาะตัวเว้นวรรค ) หรือ (2) อนุญาตให้คุณเลือกไม่ใช้ข้อ จำกัด การซ่อน UISVอัตโนมัติปัญหานี้จะได้รับการแก้ไขอย่างง่ายดาย


6
ขอบคุณสำหรับคำอธิบายที่ละเอียดถี่ถ้วนและเป็นประโยชน์ อย่างไรก็ตามสิ่งนี้ดูเหมือนจะเป็นข้อบกพร่องของ Apple ที่มีมุมมองแบบซ้อน โดยพื้นฐานแล้วคุณลักษณะ "การซ่อน" ของพวกเขาไม่สามารถใช้ร่วมกับคุณลักษณะ "ระยะห่าง" ได้ ความคิดใด ๆ ของพวกเขาได้แก้ไขปัญหานี้แล้วหรือได้เพิ่มคุณสมบัติบางอย่างเพื่อป้องกันการแฮ็กด้วยมุมมองที่มีข้อมูลเพิ่มเติม (อีกครั้งรายละเอียดที่ดีของการแก้ปัญหาที่อาจเกิดขึ้นและไม่เห็นด้วยกับความสง่างามของ # 3)
Marchy

1
UIStackViewเด็กทุกคนที่มีUIStackViewความจำเป็นต้องถูกห่อหุ้มด้วยUIViewหรือเป็นเพียงเด็กที่คุณต้องการซ่อน / เลิกซ่อน?
Adrian

1
สิ่งนี้ให้ความรู้สึกเหมือนการกำกับดูแลที่แย่มากในส่วนของ Apple โดยเฉพาะอย่างยิ่งเนื่องจากคำเตือนและข้อผิดพลาดเกี่ยวกับการใช้UIStackViewมักจะคลุมเครือและเข้าใจยาก
bompf

นี่คือเครื่องช่วยชีวิต ฉันประสบปัญหาที่ UIStackViews เพิ่มลงใน UITableViewCell ทำให้เกิดการสแปมบันทึกข้อผิดพลาด AutoLayout ทุกครั้งที่เซลล์ถูกนำกลับมาใช้ การฝัง stackView ใน UIView โดยตั้งค่าลำดับความสำคัญข้อ จำกัด จุดยึดด้านล่างเป็นต่ำช่วยแก้ปัญหาได้ มันทำให้ตัวแก้ไขจุดบกพร่องของมุมมองแสดงองค์ประกอบของ stackView ว่ามีความสูงไม่ชัดเจน แต่จะแสดงอย่างถูกต้องในแอปโดยไม่มีสแปมบันทึกข้อผิดพลาด ขอบคุณ.
Womble

6

โดยส่วนใหญ่ข้อผิดพลาดนี้สามารถแก้ไขได้โดยการลดลำดับความสำคัญของข้อ จำกัด เพื่อขจัดความขัดแย้ง


คุณหมายถึงอะไร? ข้อ จำกัด ทั้งหมดสัมพันธ์กันภายในมุมมองที่ซ้อนกัน ....
Ben Guild

ฉันขอโทษฉันไม่เข้าใจคำถามของคุณถูกต้องภาษาอังกฤษของฉันก็เป็นเช่นนั้น แต่สิ่งที่ฉันคิดก็คือข้อ จำกัด นั้นสัมพันธ์กับแม่มดมุมมองที่เกี่ยวข้องหากมุมมองถูกซ่อนไว้ข้อ จำกัด ก็จะไม่ทำงาน ฉันไม่แน่ใจว่านั่นเป็นข้อสงสัยของคุณหรือเปล่า แต่ฉันหวังว่าฉันจะช่วยได้
Luciano Almeida

ดูเหมือนว่าจะมาจากตอนที่ของถูกทำลายหรืออยู่ระหว่างการแสดง / ซ่อน ในกรณีนี้จะมองเห็นได้บางส่วน - บางทีอาจจำเป็นต้องผ่านและกำจัดค่าคงที่ในแนวตั้งขั้นต่ำเพราะสามารถยกกำลังเป็น 0 ได้?
Ben Guild

2

เมื่อคุณตั้งค่ามุมมองเป็นซ่อนUIStackviewจะพยายามทำให้มุมมองเคลื่อนไหวออกไป หากคุณต้องการเอฟเฟกต์นั้นคุณจะต้องกำหนดลำดับความสำคัญที่ถูกต้องสำหรับข้อ จำกัด เพื่อไม่ให้ขัดแย้งกัน (ตามที่หลาย ๆ คนแนะนำไว้ข้างต้น)

อย่างไรก็ตามหากคุณไม่สนใจภาพเคลื่อนไหว (บางทีคุณอาจซ่อนมันไว้ใน ViewDidLoad) คุณก็สามารถทำได้ง่ายๆremoveFromSuperviewซึ่งจะมีผลเหมือนกัน แต่ไม่มีปัญหาใด ๆ กับข้อ จำกัด เนื่องจากสิ่งเหล่านั้นจะถูกลบออกพร้อมกับมุมมอง


1

จากคำตอบของ @ Senseful นี่คือส่วนขยาย UIStackView เพื่อรวมมุมมองสแต็กในมุมมองและใช้ข้อ จำกัด ที่เขาแนะนำ:

/// wraps in a `UIView` to prevent autolayout warnings when a stack view with spacing is placed inside another stack view whose height might be zero (usually due to `hidden` being `true`).
/// See http://stackoverflow.com/questions/32428210
func wrapped() -> UIView {
    let wrapper = UIView()
    translatesAutoresizingMaskIntoConstraints = false
    wrapper.addSubview(self)

    for attribute in [NSLayoutAttribute.Top, .Left, .Right, .Bottom] {
        let constraint = NSLayoutConstraint(item: self,
                                            attribute: attribute,
                                            relatedBy: .Equal,
                                            toItem: wrapper,
                                            attribute: attribute,
                                            multiplier: 1,
                                            constant: 0)
        if attribute == .Bottom { constraint.priority = 999 }
        wrapper.addConstraint(constraint)
    }
    return wrapper
}

แทนการเพิ่มของการใช้งานstackViewstackView.wrapped()


1

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

หากคุณยังคงประสบปัญหาแสดงว่าปัญหาน่าจะเกิดจากระยะห่างใน StackViews ที่ซ่อนอยู่ วิธีแก้ปัญหาของฉันคือเพิ่ม UIView เป็นตัวเว้นระยะและตั้งค่าระยะห่าง UIStackView เป็นศูนย์ จากนั้นตั้งค่าข้อ จำกัด View.height หรือ View.width (ขึ้นอยู่กับสแต็กแนวตั้งหรือแนวนอน) กับระยะห่างของ StackView

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

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


1

ฉันเพิ่งต่อสู้กับข้อผิดพลาดการจัดวางอัตโนมัติเมื่อซ่อนไฟล์UIStackView. แทนที่จะเก็บหนังสือและห่อสแต็คจำนวนUIViewsมากฉันเลือกที่จะสร้างทางออกสำหรับparentStackViewร้านค้าของฉันและร้านค้าสำหรับเด็กที่ฉันต้องการซ่อน / เลิกซ่อน

@IBOutlet weak var parentStackView: UIStackView!
@IBOutlet var stackViewNumber1: UIStackView!
@IBOutlet var stackViewNumber2: UIStackView!

ในสตอรีบอร์ดนี่คือลักษณะของ parentStack ของฉัน:

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

มีลูก 4 คนและเด็ก ๆ แต่ละคนมีมุมมองซ้อนกันอยู่ข้างใน เมื่อคุณซ่อนมุมมองแบบสแต็กหากมีองค์ประกอบ UI ที่เป็นมุมมองแบบสแต็กเช่นกันคุณจะเห็นข้อผิดพลาดของการจัดวางอัตโนมัติ แทนที่จะซ่อนฉันเลือกที่จะลบออก

ในตัวอย่างของฉันparentStackViewsมีอาร์เรย์ของ 4 องค์ประกอบ ได้แก่ Top Stack View, StackViewNumber1, Stack View Number 2 และ Stop Button ดัชนีของพวกเขาarrangedSubviewsคือ 0, 1, 2 และ 3 ตามลำดับ เมื่อฉันต้องการซ่อนหนึ่งฉันเพียงแค่ลบออกจากparentStackView's arrangedSubviewsอาร์เรย์ เนื่องจากมันไม่ได้อ่อนแอมันจึงยังคงอยู่ในหน่วยความจำและคุณสามารถใส่กลับไปที่ดัชนีที่คุณต้องการได้ในภายหลัง ฉันไม่ได้เริ่มต้นใหม่ดังนั้นมันจึงแฮงค์เอาท์จนกว่าจะจำเป็น แต่ไม่ได้ขยายหน่วยความจำ

โดยพื้นฐานแล้วคุณสามารถ ...

1) ลาก IBOutlets สำหรับสแต็กหลักของคุณและเด็ก ๆ ที่คุณต้องการซ่อน / เลิกซ่อนไปที่กระดานเรื่องราว

2) เมื่อคุณต้องการซ่อนให้ลบสแต็กที่คุณต้องการซ่อนจากparentStackView's arrangedSubviewsอาร์เรย์

3) โทรด้วยself.view.layoutIfNeeded()UIView.animateWithDuration

หมายเหตุสอง stackViews weakที่ผ่านมาไม่ได้ คุณต้องเก็บไว้รอบ ๆ เมื่อคุณเลิกซ่อน

สมมติว่าฉันต้องการซ่อน stackViewNumber2:

parentStackView.removeArrangedSubview(stackViewNumber2)
stackViewNumber2.removeFromSuperview()

จากนั้นทำให้เคลื่อนไหว:

UIView.animate(withDuration: 0.25,
               delay: 0,
               usingSpringWithDamping: 2.0,
               initialSpringVelocity: 10.0,
               options: [.curveEaseOut],
               animations: {
                self.view.layoutIfNeeded()
},
               completion: nil)

หากคุณต้องการ "ยกเลิกการซ่อน" ในstackViewNumber2ภายหลังคุณสามารถแทรกลงในparentStackView arrangedSubViewsดัชนีที่ต้องการและทำให้การอัปเดตเคลื่อนไหวได้

parentStackView.removeArrangedSubview(stackViewNumber1)
stackViewNumber1.removeFromSuperview()
parentStackView.insertArrangedSubview(stackViewNumber2, at: 1)

// Then animate it
UIView.animate(withDuration: 0.25,
               delay: 0,
               usingSpringWithDamping: 2.0,
               initialSpringVelocity: 10.0,
               options: [.curveEaseOut],
               animations: {
                self.view.layoutIfNeeded()
},
               completion: nil)

ฉันพบว่ามันง่ายกว่าการทำบัญชีตามข้อ จำกัด การจัดลำดับความสำคัญ ฯลฯ

หากคุณมีสิ่งที่คุณต้องการซ่อนไว้โดยค่าเริ่มต้นคุณก็สามารถวางมันออกมาบนกระดานและลบในและอัปเดตได้โดยไม่ต้องใช้การเคลื่อนไหวviewDidLoadview.layoutIfNeeded()


1

ฉันพบข้อผิดพลาดเดียวกันกับ Stack Views แบบฝังแม้ว่าทุกอย่างจะทำงานได้ดีที่รันไทม์

ฉันแก้ไขข้อผิดพลาดข้อ จำกัด โดยซ่อนมุมมองสแต็กย่อยทั้งหมดก่อน (การตั้งค่าisHidden = true) ก่อนที่จะซ่อนมุมมองสแต็กหลัก

การทำเช่นนี้ไม่มีความซับซ้อนทั้งหมดในการลบมุมมองที่จัดเรียงย่อยโดยยังคงรักษาดัชนีไว้เมื่อจำเป็นต้องเพิ่มกลับ

หวังว่านี่จะช่วยได้


1

Senseful ได้ให้คำตอบที่ดีเยี่ยมสำหรับต้นตอของปัญหาข้างต้นดังนั้นฉันจะตรงไปที่วิธีแก้ปัญหา

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


0

คุณอาจสร้างข้อ จำกัด ขณะทำงานกับคลาสขนาดบางอย่าง (เช่น wCompact hRegular) จากนั้นคุณสร้างรายการที่ซ้ำกันเมื่อคุณเปลี่ยนไปใช้คลาสขนาดอื่น (เช่น wAny hAny) ตรวจสอบข้อ จำกัด ของออบเจ็กต์ UI ในคลาสขนาดต่างๆและดูว่ามีความผิดปกติกับข้อ จำกัด หรือไม่ คุณควรเห็นเส้นสีแดงแสดงข้อ จำกัด ในการชนกัน ใส่รูปไม่ได้จนกว่าจะได้รับ 10 คะแนนชื่อเสียงขออภัย: /


โอวตกลง. แต่ฉันพบข้อผิดพลาดนั้นเมื่อฉันมีกรณีที่ฉันอธิบายdrive.google.com/file/d/0B-mn7bZcNqJMVkt0OXVLVVdnNTA/…
FM

ใช่ฉันไม่เห็นสีแดงใด ๆ เลยโดยการสลับคลาสขนาดในตัวสร้างอินเทอร์เฟซ ฉันใช้เฉพาะขนาด "ใดก็ได้"
Ben Guild

0

ฉันต้องการซ่อน UIStackView ทั้งหมดในแต่ละครั้ง แต่ฉันได้รับข้อผิดพลาดเดียวกันกับ OP ซึ่งได้รับการแก้ไขให้ฉัน:

for(UIView *currentView in self.arrangedSubviews){
    for(NSLayoutConstraint *currentConstraint in currentView.constraints){
        [currentConstraint setPriority:999];
    }
}

สิ่งนี้ไม่ได้ผลสำหรับฉันเพราะโปรแกรมจัดวางอัตโนมัติบ่นเมื่อคุณเปลี่ยนข้อ จำกัด ที่จำเป็น ( priority = 1000) เป็นไม่จำเป็น ( priority <= 999)
Senseful

0

ฉันมีปุ่มแถวหนึ่งที่มีข้อจำกัดความสูง สิ่งนี้เกิดขึ้นเมื่อซ่อนปุ่มเดียว การตั้งค่าลำดับความสำคัญของข้อจำกัดความสูงของปุ่มนั้นเป็น 999 ช่วยแก้ปัญหาได้


-2

ข้อผิดพลาดนี้ไม่เกี่ยวข้องกับ UIStackView เกิดขึ้นเมื่อคุณมีข้อ จำกัด ของความขัดแย้งที่มีลำดับความสำคัญเดียวกัน ตัวอย่างเช่นหากคุณมีข้อ จำกัด ระบุว่าความกว้างของมุมมองของคุณคือ 100 และคุณมีข้อ จำกัด อื่นในเวลาเดียวกันระบุว่าความกว้างของมุมมองคือ 25% ของคอนเทนเนอร์ เห็นได้ชัดว่ามีสองข้อ จำกัด ที่ขัดแย้งกัน วิธีแก้ปัญหาคือการลบออก


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.