74

Tôi có một lớp con UIView tùy chỉnh đang được khởi tạo qua một ngòi.Định tâm X của chế độ xem con trong tự động trả lời "không được chuẩn bị cho ràng buộc"

Trong -awakeFromNib, tôi đang tạo một chế độ xem phụ và cố gắng căn giữa nó trong phần giám sát của nó.

[self setInteralView: [[UIView alloc] init]]; 
[[self internalView] addConstraint: [NSLayoutConstraint constraintWithItem: [self internalView] 
                   attribute: NSLayoutAttributeCenterX 
                   relatedBy: NSLayoutRelationEqual 
                    toItem: self 
                   attribute: NSLayoutAttributeCenterX 
                   multiplier: 1 
                    constant: 0]]; 

này phá vỡ, và làm cho đầu ra sau đây:

2013-08-11 17:58:29.628 MyApp[32414:a0b] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0xc1dcc80 UIView:0xc132a40.centerX == MyView:0xc1315a0.centerX> 
    When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView _viewHierarchyUnpreparedForConstraint:] to debug. 
2013-08-11 17:58:29.630 MyApp[32414:a0b] View hierarchy unprepared for constraint. 
    Constraint: <NSLayoutConstraint:0xc1dcc80 UIView:0xc132a40.centerX == MyView:0xc1315a0.centerX> 
    Container hierarchy: 
<UIView: 0xc132a40; frame = (0 0; 0 0); clipsToBounds = YES; layer = <CALayer: 0xc132bc0>> 
    View not found in container hierarchy: <MyView: 0xc1315a0; frame = (-128 -118; 576 804); layer = <CALayer: 0xc131710>> 
    That view's superview: <UIView: 0xc131a70; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0xc131b50>> 

Trả lời

87

Theo các tiểu bang lỗi, bạn phải thêm các hạn chế đối với một cái nhìn như vậy mà các quan điểm liên quan đến việc hạn chế là quan điểm bạn thêm vào hoặc một chế độ xem phụ của chế độ xem đó. Trong trường hợp mã của bạn ở trên, bạn nên thêm ràng buộc đó vào self, thay vì [self internalView]. Lý do nó không hoạt động như văn bản là một trong các khung nhìn liên quan đến ràng buộc (self) không có trong hệ thống phân cấp khung nhìn nếu bạn chỉ xem xét [self internalView] và bên dưới).

Để biết thêm chi tiết, hãy xem discussion section of the documentation trên phương thức addConstraint:.

Đây là dòng code của bạn, cố định như tôi đề nghị:

UIView* internalView = [[UIView alloc] initWithFrame:CGRectZero]; 
internalView.translatesAutoresizingMaskIntoConstraints = NO; 
[self setInternalView:internalView]; 

[self addConstraint: [NSLayoutConstraint constraintWithItem: [self internalMapView] 
             attribute: NSLayoutAttributeCenterX 
             relatedBy: NSLayoutRelationEqual 
             toItem: self 
             attribute: NSLayoutAttributeCenterX 
             multiplier: 1 
             constant: 0]]; 
+0

Điều đó mang lại cho tôi một lỗi tuyên bố 'Không thể thỏa mãn đồng thời hạn chế. Có lẽ ít nhất một trong những ràng buộc trong danh sách sau đây là một trong những bạn không muốn.' Và sau đó nó phá vỡ '' –

+1

Rất có thể vì bạn didn ' t tắt tính năng tự động thay đổi kích thước mặt nạ thành các ràng buộc. Tôi sẽ cập nhật mã của tôi ở trên để làm như vậy. Bạn cũng có thể cần thêm các ràng buộc chiều rộng/chiều cao để nó có thể nhìn thấy được và tôi khuyên bạn nên thêm một ràng buộc vào trung tâm Y hoặc một số ràng buộc trên/dưới để tự tạo bố cục được xác định rõ. –

+0

để bạn không thể có bố cục như: '@" V: | [v] | "'? vì điều này sẽ ám chỉ đến người giám sát? – Sam

1

Như @CharlesA chỉ ra trong câu trả lời của ông vấn đề là quan điểm bạn đang thêm không có trong hệ thống phân cấp cái nhìn đúng đắn. Câu trả lời của anh là một câu trả lời hay, nhưng tôi sẽ trình bày một số chi tiết cho một trường hợp sử dụng cụ thể gây ra vấn đề này cho tôi:

Tôi đã xảy ra điều này khi cố thêm ràng buộc vào một khung nhìn có bộ điều khiển khung nhìn đã khởi tạo bằng cách sử dụng instantiateViewControllerWithIdentifier. Để giải quyết vấn đề, tôi đã sử dụng [childViewController didMoveToParentViewController:self]. Điều này đã thêm khung nhìn vào phân cấp khung nhìn đã được tham chiếu bởi ràng buộc của tôi.

108

Đối với những người khác đến đây: Tôi gặp lỗi này, bởi vì tôi đã thêm các ràng buộc trước khi tôi thêm các bản xem trước vào cấu trúc phân cấp.

+0

Cảm ơn, bạn đã cứu tôi rất nhiều thời gian! – Stas

+0

Đây là lý do phổ biến nhất cho sự thất bại này tôi đã nhận thấy cho đến nay. –

+0

chính xác và khi bạn làm điều đó 'constraintWithItem: youView' mục không tồn tại trong nó! – Nazir

9

Mẹo bổ sung:

Tôi có một ứng dụng mới được phát triển mà chạy tốt trên iOS7 nhưng nhận được lỗi trên iOS8 "Các hệ thống phân cấp xem không được chuẩn bị cho sự hạn chế".

Đọc một số bài đăng khác cho biết rằng (các) lượt xem cần phải được thêm trước khi tạo các ràng buộc. Tôi đã làm điều đó nhưng vẫn gặp lỗi.

Sau đó, tôi đã tìm ra rằng tôi nên tạo các ràng buộc dưới - (void) viewDidAppear thay vì viewDidLoad

+1

Khi 'viewDidAppear()' được gọi, khung nhìn đã được hiển thị cho người dùng. Nếu sửa đổi các ràng buộc, nó phải là trước đó, trong 'viewWillLayoutSubviews()'. Thêm vòng đời tại đây: https://medium.com/@SergiGracia/ios-uiviewcontroller-lifecycle-261e3e2f6133#.8q888tocb – maganap

31

ngắn câu trả lời: swap cha mẹ và con xem.
Giả sử self là quan điểm cha mẹ:

  • xấu: [subview addConstraint [NSLayoutConstraint constraintWithItem:self...

  • tốt: [self addConstraint [NSLayoutConstraint constraintWithItem:subview...


SWI ft

subview.translatesAutoresizingMaskIntoConstraints = false 
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(
    "H:|-0-[subview]-0-|", 
    options: .DirectionLeadingToTrailing, 
    metrics: nil, 
    views: ["subview":subview])) 

obj-C

[subview setTranslatesAutoresizingMaskIntoConstraints:NO]; 
[self addConstraints:[NSLayoutConstraint 
         constraintsWithVisualFormat:@"H:|-0-[subview]-0-|" 
         options:NSLayoutFormatDirectionLeadingToTrailing 
         metrics:nil 
         views:NSDictionaryOfVariableBindings(subview)]]; 
2

Đây là một câu hỏi cũ nhưng tôi muốn chỉ ra dòng này từ các tài liệu:

Khi phát triển dành cho iOS 8.0 hoặc sau đó, đặt thuộc tính isActive của ràng buộc thành true thay vì gọi trực tiếp phương thức addConstraint (_ :). Thuộc tính isActive tự động thêm và loại bỏ ràng buộc khỏi khung nhìn chính xác.

Ít nhất, điều này sẽ loại bỏ một điểm lỗi vì bạn không còn cần phải lo lắng về việc kêu gọi addConstraint trên quan điểm sai

Các vấn đề liên quan