Ich habe einen View-Controller, der eine einzelne benutzerdefinierte Ansicht besitzt; Die benutzerdefinierte Ansicht zeichnet ein Spielbrett mit Core Graphics. (Keine anderen Subviews sind involviert.)Warum verkleinert sich meine Superview mit Subview, wenn sie modal präsentiert wird (mit Auto Layout)?
Ich richte Auto-Layout-Einschränkungen ein, damit das Spielbrett seine Superansicht füllt. Wenn ich den View-Controller als Root-View-Controller einstelle, füllt das Spielbrett (und Superview) den Bildschirm, wie es meine Absicht ist. Wenn ich jedoch den View-Controller modal präsentiere, verkleinert sich das Spielbrett (und Superview) auf nichts/Minimum, und die Auto-Layout-Ablaufverfolgung meldet, dass das Layout mehrdeutig ist.
Ich schrieb einen vereinfachten Testfall, um die Frage zu veranschaulichen.
Hier ist meine BoardViewController
, die eine Top-Level-Ansicht mit einem grünen Hintergrund hat, aber eine einzelne expansive Subview mit einem roten Hintergrund erstellt. Ich mag den Bildschirm all rot sehen, wenn diese Ansicht-Controller übernehmen:
- (void)loadView
{
UIView *mainView = [[UIView alloc] init];
mainView.translatesAutoresizingMaskIntoConstraints = NO;
mainView.backgroundColor = [UIColor greenColor];
UIView *subView = [[UIView alloc] init];
subView.translatesAutoresizingMaskIntoConstraints = NO;
subView.backgroundColor = [UIColor redColor];
[mainView addSubview:subView];
self.view = mainView;
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(subView);
NSArray *c1 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subView(>=10)]|"
options:0
metrics:nil
views:viewsDictionary];
NSArray *c2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subView(>=10)]|"
options:0
metrics:nil
views:viewsDictionary];
[self.view addConstraints:c1];
[self.view addConstraints:c2];
}
Wenn ich das als meine root-View-Controller gesetzt, dann habe ich mein schönes rotes Spielbrett zu sehen füllt den Bildschirm. Allerdings schrumpft das Spielbrett auf das Minimum 10x10 Platz, wenn ich die BoardViewController
aus einer anderen RootViewController
präsentieren:
- (void)loadView
{
UIView *rootView = [[UIView alloc] init];
rootView.translatesAutoresizingMaskIntoConstraints = NO;
UIButton *presentButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
presentButton.translatesAutoresizingMaskIntoConstraints = NO;
[presentButton setTitle:@"Present" forState:UIControlStateNormal];
[presentButton addTarget:self
action:@selector(present:)
forControlEvents:UIControlEventTouchUpInside];
[rootView addSubview:presentButton];
self.view = rootView;
[rootView addConstraint:[NSLayoutConstraint constraintWithItem:presentButton
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:rootView
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[rootView addConstraint:[NSLayoutConstraint constraintWithItem:presentButton
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:rootView
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];
}
- (void)present:(id)sender
{
BoardViewController *bvc = [[BoardViewController alloc] init];
[self presentViewController:bvc animated:YES completion:NULL];
}
ich verschiedene Auto-Layout-Regeln immer wieder versuchen, aber egal was ich tue, ich kann das Spiel nicht bekommen Board, um den Bildschirm zu füllen, wenn der View-Controller modal präsentiert wird. (Zur gleichen Zeit, die ich diese Frage stelle, versuche ich, die Laufzeit zu erhalten, um mir zu sagen, was es denkt, ist mehrdeutig. Aber ich bin nicht sehr gut dieses Debuggen noch, daher meine Frage hier.)
Brilliant! Vielen Dank! Also, Erklärung: Ich habe irrigerweise mit dem Layout meiner Top-Level-Ansicht, die der Bereich von wem auch immer mich darstellt, falsch gemacht. In diesem Fall fügt 'presentViewController: animate: completion:' (wir nehmen an) seine Ansichten mithilfe von Springs-and-Struts hinzu, also habe ich es abgebrochen. Ist das eine faire Art, es zu sagen? –
Aus dem, was ich sehen kann, scheint es, dass das 'rootViewController' eines Fensters ein spezieller Fall ist, der Einschränkungen umgeht.Es wäre interessant zu experimentieren mit dem, was passieren würde, wenn man 'mainView.translationsAutoresizingMaskIntoConstraints = NO;' verlässt und 'updateConstraints' implementiert, um einige Einschränkungen manuell hinzuzufügen ... –
Ich habe versucht, den Wert von '[self.view translateAutoresizingMaskIntoConstraints]' zu verwerfen bei 'viewDidAppear:' für die modale Darstellung und das Setzen als Root-View-Controller. In beiden Fällen hat es JA verschenkt. Vielleicht legt das Setzen einer Ansicht als root-View-Controller explizit seinen Frame fest, während das Darstellen eines View-Controllers dies nicht tut. –