Pertanyaan Centering subview X di autolayout melempar "tidak siap untuk kendala"


Saya memiliki subkelas UIView khusus yang sedang diinisialisasi melalui sebuah pena.

Di -awakeFromNib, Saya membuat subview dan mencoba memusatkannya di superview-nya.

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

Ini pecah, dan menyebabkan keluaran berikut:

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>>

75
2017-08-11 22:18


asal


Jawaban:


Ketika kesalahan menyatakan, Anda harus menambahkan kendala ke tampilan sedemikian rupa sehingga pandangan yang terlibat dalam kendala adalah tampilan yang Anda tambahkan ke atau subview dari pandangan itu. Dalam kasus kode Anda di atas, Anda harus menambahkan batasan itu ke self, daripada [self internalView]. Alasan mengapa tidak berfungsi seperti yang tertulis adalah salah satu pandangan yang terlibat dalam kendala (self) tidak dalam hierarki tampilan jika Anda hanya mempertimbangkan [self internalView] dan di bawah).

Untuk detail lebih lanjut, lihat bagian diskusi dokumentasi pada addConstraint: metode.

Berikut adalah baris kode Anda, seperti yang saya sarankan:

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]];

88
2017-08-11 22:23



Bagi yang lain yang datang ke sini: Saya mendapat kesalahan ini, karena saya menambahkan batasan sebelum saya menambahkan sublihat ke hierarki.


111
2017-07-29 17:21



Jawaban singkat: menukar tampilan orang tua dan anak.
Asumsi self adalah tampilan induk:

  • buruk: [subview addConstraint [NSLayoutConstraint constraintWithItem:self...

  • baik: [self addConstraint [NSLayoutConstraint constraintWithItem:subview...


Cepat

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)]];

33
2017-07-23 05:39



Kiat Tambahan:

Saya memiliki Aplikasi yang baru dikembangkan yang berjalan dengan baik di iOS7 tetapi mendapatkan error pada iOS8 "Hirarki tampilan tidak disiapkan untuk kendala".

Baca beberapa posting lain mengatakan bahwa pandangan (sub) perlu ditambahkan sebelum membuat batasan. Saya melakukan itu tetapi masih mendapat kesalahan.

Kemudian saya tahu bahwa saya harus membuat batasan di bawah - (void) viewDidAppear, bukan viewDidLoad


9
2018-05-19 16:54



Ini adalah pertanyaan lama tetapi saya ingin menunjukkan baris ini dari dokumen:

Saat mengembangkan iOS 8.0 atau lebih baru, tetapkan properti isActive constraint menjadi true alih-alih memanggil addConstraint (metode _ :) secara langsung. Properti isActive secara otomatis menambahkan dan menghilangkan batasan dari tampilan yang benar.

Paling tidak, ini akan menghilangkan satu titik kegagalan karena Anda tidak perlu lagi khawatir untuk memanggil addConstraint pada tampilan yang salah


2
2018-05-25 21:23



Seperti yang ditunjukkan oleh @CharlesA dalam jawabannya, masalahnya adalah pandangan yang Anda tambahkan tidak dalam hierarki tampilan yang tepat. Jawabannya bagus, tapi saya akan memberikan beberapa detail untuk kasus penggunaan tertentu yang menyebabkan masalah ini untuk saya:

Saya memiliki ini terjadi ketika mencoba untuk menambah kendala untuk pandangan yang pengontrol tampilan saya telah menggunakan instantiated instantiateViewControllerWithIdentifier. Untuk mengatasi masalah, saya menggunakan [childViewController didMoveToParentViewController:self]. Ini menambahkan pandangan ke dalam hierarki tampilan yang direferensikan oleh kendala saya.


1
2018-06-29 15:23



Dalam kasus saya, itu diselesaikan dengan menggunakan tampilan root sebagai wadah kendala, bukan tampilan yang dibuat saat ini.

Maksud saya, gunakan di dalam viewController

view.addConstraints([leftConstraintImage, topConstraintImage]) dari pada imageView.addConstraints...


0
2018-05-10 21:45