2015-05-07 14 views
5

Tôi đang sử dụng systemLayoutSizeFittingSize để có kích thước nhỏ nhất cho lớp con chế độ xem tùy chỉnh đáp ứng các ràng buộc nội bộ của nó.Ràng buộc "UITemporaryLayoutHeight" của iOS

let someView = SomeView()   
someView.setNeedsUpdateConstraints() 
someView.setNeedsLayout() 
someView.layoutIfNeeded() 

let viewSize = someView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize) 

println(viewSize) // PRINTS (0.0, 96.0) WHICH IS RIGHT! 

tôi nhận được giá trị chính xác nhưng tôi cũng nhận được một cảnh báo Unable to simultaneously satisfy constraints:

"<NSLayoutConstraint:0x7ff16b753190 '_UITemporaryLayoutHeight' V:[ProjectName.SomeView:0x7ff16b772210(0)]>", 
"<NSLayoutConstraint:0x7ff16b75de50 UIImageView:0x7ff16b76eff0.top == ProjectName.SomeView:0x7ff16b772210.topMargin>", 
"<NSLayoutConstraint:0x7ff16b7653f0 UIImageView:0x7ff16b76eff0.bottom <= ProjectName.SomeView:0x7ff16b772210.bottomMargin>" 

Dưới đây là SomeView UIView lớp con tôi.

Nó chỉ chứa một hình ảnh 80x80 được gắn vào lề trên cùng, bên trái và dưới cùng. (Tôi đang sử dụng PureLayout để viết các ràng buộc).

Bây giờ rõ ràng chế độ xem này sẽ có chiều cao cố định là 96 (80 + 8x2 đối với lề) nhưng về mặt lý thuyết nó có thể kéo dài nếu các thay đổi của nó thay đổi kích thước.

Bất kỳ ý tưởng nào? Tìm kiếm google cho UITemporaryLayoutHeight (hoặc Width) mang đến cho 0 kết quả ...

class SomeView: UIView { 

    let imageView = UIImageView() 

    var constraintsSet = false 

    override init(frame: CGRect) { 

     super.init(frame: frame) 

     backgroundColor = UIColor.lightGrayColor() 

     imageView.backgroundColor = UIColor.darkGrayColor() 
     addSubview(imageView) 
    } 

    override func updateConstraints() { 

     if(!constraintsSet) { 

      imageView.autoPinEdgeToSuperviewMargin(.Top) 
      imageView.autoPinEdgeToSuperviewMargin(.Left) 
      imageView.autoPinEdgeToSuperviewMargin(.Bottom, relation: NSLayoutRelation.GreaterThanOrEqual) 
      imageView.autoSetDimension(.Width, toSize: 80.0) 
      imageView.autoSetDimension(.Height, toSize: 80.0) 

      constraintsSet = true 
     } 
     super.updateConstraints() 
    } 
} 

Trả lời

14

này:

Nó chỉ chứa một IMAGExem 80x80 pinned để phía trên, bên trái và lề dưới

NSLayoutConstraint này: 0x7ff16b753190 '_UITemporaryLayoutHeight' V: [ ProjectName.SomeView: 0x7ff16b772210 (0)]

là nguồn gốc của sự cố. UIKit là lúc nào đó trong quá trình tải/bố trí/hiển thị bằng cách sử dụng độ cao 0. Vì bạn có các ràng buộc cho cả hai hình ảnh trên cùng và dưới cùng là imageview có kích thước nội tại của nó, bạn đang yêu cầu nó phù hợp với hình ảnh không gian.

Cách thông thường để giải quyết vấn đề này là đặt mức độ ưu tiên của giới hạn trên hoặc dưới lên bất kỳ giá trị nào nhỏ hơn 1000.

+1

Như một lưu ý: Tôi thực sự muốn nghe lời giải thích từ Apple về những _UITemporaryLayoutHeight và những thứ tương tự bật lên trong giao diện điều khiển. –

+0

Cảm ơn điều này dường như giải quyết vấn đề! – LorTush

+0

Ai đó hãy hỏi tại các phòng thí nghiệm của WWDC và báo cáo lại. Đoán của tôi: họ đặt các ràng buộc ở đó để làm cho hệ điều hành rõ ràng gọi ra quan điểm của bạn vì không hài lòng về việc bị thu nhỏ về 0 kích thước. –

0

Nơi bạn đang thêm những hạn chế dường như là nguồn gốc của vấn đề của bạn.

Ngoài ra, bạn cần phải thiết lập setTranslatesAutoresizingMaskIntoConstraints(false) đến imageView

Hãy thử thêm những hạn chế khi bạn thêm các hình ảnh như subview.

Something như thế này nên làm việc:

class SomeView: UIView { 

    let imageView = UIImageView() 

    var constraintsSet = false 

    override init(frame: CGRect) { 

     super.init(frame: frame) 

     backgroundColor = UIColor.lightGrayColor() 

     imageView.backgroundColor = UIColor.darkGrayColor() 
     addSubview(imageView) 

     // Don't forget this 
     imageView.setTranslatesAutoresizingMaskIntoConstraints(false) 

     imageView.autoPinEdgeToSuperviewMargin(.Top) 
     imageView.autoPinEdgeToSuperviewMargin(.Left) 
     imageView.autoPinEdgeToSuperviewMargin(.Bottom, relation: NSLayoutRelation.GreaterThanOrEqual) 
     imageView.autoSetDimension(.Width, toSize: 80.0) 
     imageView.autoSetDimension(.Height, toSize: 80.0) 
    } 
} 

Hope công việc này. Hãy cho tôi biết nếu bạn cần thêm trợ giúp!

+0

Cảm ơn bạn đã trả lời! Tôi khá chắc chắn rằng PureLayout tự động thiết lập setTranslatesAutoresizingMaskIntoConstraints thành false, vì vậy đó là lý do tại sao tôi bỏ nó ra .. Về nơi mà tôi thêm ràng buộc, tôi đã đọc ở nhiều nơi (bao gồm cả tài liệu của Apple) mà ràng buộc nên được thêm vào updateConstraints () phương pháp. Tôi đã thử di chuyển chúng trong phương thức init() và tôi nhận được cảnh báo khác: '" "' Chiều cao vẫn được đặt thành 0 nhưng không có tên 'UITemporaryLayoutHeight' – LorTush

13

Tôi đã nhận thấy điều này xảy ra với tôi nếu tôi gọi số layoutIfNeeded trên chế độ xem trước khi bố mẹ của nó được đặt. Tôi sẽ đặt cược nếu bạn đã xóa someView.layoutIfNeeded() bạn sẽ không thấy lỗi đó nữa. Bạn có thể cũng có thể loại bỏ someView.setNeedsLayout() và thay thế bằng someView.updateConstraintsIfNeeded(). systemLayoutSizeFittingSize không yêu cầu lượt xem thực sự được đặt ra, nó chỉ cần các ràng buộc được cấu hình đúng cách.

+0

tuyệt vời! nó hoạt động. –

2

Tôi có cảnh báo này khi chế độ xem không có số gọi là superviewlayoutIfNeeded. Giải pháp của tôi là gọi layoutIfNeeded sau khi xem được thêm vào một superview. Tôi hy vọng điều này sẽ giúp:

- (void)didMoveToSuperview { 
    [super didMoveToSuperview]; 
    [self layoutIfNeeded]; 
} 
+0

Tại sao ai đó lại bỏ phiếu này? Điều này làm việc hoàn toàn cho tôi. Tôi muốn biết tại sao mặc dù. –

+2

Điều này làm việc cho tôi. layoutIfNeeded đang gây ra sự cố trên chế độ xem không có người giám sát. – grez