2013-04-28 26 views
6

My UIViewController tạo ra quan điểm của mình bằng cách ghi đè phương pháp loadView:chế AutoLayout cho một cái nhìn autoresizing tạo ra trong loadView ViewController của

- (void)loadView { 
    UIView *view = [[UIView alloc] init]; 
    view.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth; 
    self.view = view; 
} 

Bây giờ tôi muốn chuyển sang AutoLayout và do đó thêm một

view.translatesAutoresizingMaskIntoConstraints = NO; 

đến phương thức loadView. Bây giờ tôi phải chỉ định các ràng buộc giống nhau được tự động phát trước đó. Cách tiếp cận của tôi là ghi đè lên updateViewConstraints với

- (void)updateViewConstraints { 
    if (0 == [[self.view constraints] count]) { 
     NSDictionary* views = @{@"view" : self.view}; 

     [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:0 views:views]]; 
     [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view]|" options:0 metrics:0 views:views]]; 
    } 

    [super updateViewConstraints]; 
} 

Nhưng tôi nhận được một ngoại lệ vì tôi nghĩ rằng loại này hạn chế nên đi với quan điểm siêu:

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to install constraint on view. Does the constraint reference something from outside the subtree of the view? That's illegal. 

Vì vậy, làm thế nào để các contraints đúng phải tìm như?

Trả lời

8

Bạn cần đặt các ràng buộc trên giám sát. Ngoại lệ là do tham chiếu đến superview bằng cách chuyển "|" ở định dạng trực quan. Nếu bạn cập nhật mã của mình như sau, mã sẽ hoạt động:

- (void)updateViewConstraints { 
    if (self.view.superview != nil && [[self.view.superview constraints] count] == 0) { 
     NSDictionary* views = @{@"view" : self.view}; 

     [self.view.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:0 views:views]]; 
     [self.view.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view]|" options:0 metrics:0 views:views]]; 
    } 
    [super updateViewConstraints]; 
} 

Thực tế bạn có thể muốn kiểm tra điều gì đó khác với 0 ràng buộc trên superview nhưng điều này sẽ hữu ích.

1

Tôi không chắc chắn bạn cần đặt các ràng buộc cho chế độ xem gốc của cửa sổ.

Điều đó nói rằng, những hạn chế của bạn trông đúng, tôi nghĩ rằng ngoại trừ bạn nhận được là bởi vì đây:

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:0 views:views]]; 

sử dụng | ký hiệu đại diện cho giám sát của chế độ xem. Theo chế độ xem cấp cơ sở, chế độ xem không có giám sát. Một cái gì đó như thế này có thể hoạt động tốt hơn:

- (void)loadView { 
    UIView *customView = [[UIView alloc] init]; 
    [self.view addSubview:customView]; 
    NSDictionary* views = @{@"customView" : customView}; 

    [customView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[customView]|" options:0 metrics:0 views:views]]; 
    [customView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[customView]|" options:0 metrics:0 views:views]]; 
} 
+0

Nhưng tôi rõ ràng không muốn thêm chế độ xem dưới dạng chế độ xem phụ, vì sau đó tôi sẽ có chế độ xem không sử dụng ở giữa mà tôi không cần. –

+0

Chi phí xem thêm, không sử dụng là bao nhiêu? Tôi chỉ hỏi ở đây, đó là một câu hỏi dành cho bạn. Bạn đã thử bỏ các ràng buộc? Những hạn chế nào đi kèm với bộ điều khiển xem mặc định thông qua Bảng phân cảnh? – James

+0

Các chế độ xem được tạo theo chương trình, do đó không có gì từ Bảng phân cảnh. Xem thêm lãng phí thời gian và bộ nhớ cpu. –

5

Bạn không cần phải thiết lập các hạn chế về quan điểm gốc của bạn như Matt Neuburg giải thích Chapter 19 of his Programming iOS 6 book, in section Manual Layout:

Chúng tôi không bận tâm để cung cấp cho chúng tôi xem (self.view) một khung hợp lý. Điều này là do chúng tôi đang dựa vào người khác để định khung chế độ xem phù hợp. Trong trường hợp này, “ai đó khác” là cửa sổ, phản hồi việc có thuộc tính rootViewController được đặt thành bộ điều khiển chế độ xem bằng cách gắn khung nhìn của trình điều khiển chế độ xem một cách thích hợp làm chế độ xem gốc trước khi đặt nó vào cửa sổ dưới dạng chế độ xem phụ.

5

Vấn đề với cách tiếp cận của CEarwood là đây là ViewController và chế độ xem của nó không phải là chế độ xem phụ của bất kỳ chế độ xem nào khác, vì vậy gọi self.view.subview chỉ dẫn đến kết quả là không. Hãy nhớ rằng tài liệu hướng dẫn của Apple và hướng dẫn mạnh mẽ cho thấy rằng một UIViewController chiếm nhiều hơn hoặc ít hơn toàn bộ màn hình (bên cạnh thanh điều hướng hoặc thanh tab, vv). Câu trả lời của Palimondo về cơ bản là đúng: UIViewController của bạn cần phải bắt đầu xem trong loadView, nhưng nó không cần phải xác định khung hoặc ràng buộc của Palimondo vì chúng tự động được đặt thành khung và ràng buộc của cửa sổ. Đây là chính xác những gì được thực hiện theo mặc định nếu bạn không thực hiện loadView mình.

+4

Có một lỗi nhỏ: Bạn đang nói về self.view.superview thay vì self.view.subview – Klaas

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