wake-up-neo.com

iOS7 - Ansicht in der Statusleiste - KantenForExtendedLayout funktioniert nicht

Ich habe ein Projekt, das im letzten Jahr erstellt wurde und XIBs verwendet, keine Storyboards. Die XIBs verwenden kein automatisches Layout, jedoch etwas Autosizing. Ich habe ein Problem mit iOS7, bei dem alle Ansichten unter der Statusleiste angezeigt werden. Ich verstehe voll und ganz, dass es sich bei iOS7 um ein neues Feature handelt, bei dem dies zu erwarten ist. Alle Lösungen, um dies zu beheben, funktionieren jedoch nicht. Ich habe ein Bild oben in der Ansicht, das immer unter der Statusleiste angezeigt wird, und ich verwende keine Navigationsleisten oder ähnliches.

Ich habe versucht, die Y-Deltas in der XIB zu aktualisieren (sie haben keine Auswirkung auf die Ansicht), ich habe versucht, die Variable edgesForExtendedLayout auf UIRectEdgeNone zu setzen (tut nichts) und eine Vielzahl anderer Dinge. Jedes Mal wird in der Statusleiste die Ansicht darunter angezeigt, egal, was ich mache. Das heißt, es sei denn, ich bewege die Ansicht in der XIB manuell nach unten, um Platz für die Statusleiste zuzulassen (aber diese Lösung funktioniert nicht, weil sie funktioniert) sieht in iOS6 natürlich nicht richtig aus).

Seltsam ist, dass selbst wenn ich versuche, eine Codezeile in einem View-Shift zu hacken, dies nicht funktioniert (wie im Folgenden):

self.view.frame = CGRectMake(self.view.frame.Origin.x, self.view.frame.Origin.y+20, self.view.frame.size.width, self.view.frame.size.height);

..Nicht dass ich mit dieser Art von Lösung gehen würde, aber es ist nur seltsam, dass es nicht funktioniert hat (das einzige Mal, dass ich sehe, dass es nicht funktioniert, ist, wenn Auto Layout vorhanden ist, was in diesem Fall nicht der Fall ist).

Es ist eine Designanforderung, die in der Statusleiste angezeigt wird, und ich bin nur verblüfft, warum ich die Ansicht nicht unter iOS7 einstellen kann. Ich habe jeden einzelnen Stack Overflow-Beitrag zu diesem Thema sowie die Übergangs-/Leitfäden von Apple gelesen. Um es noch einmal zu sagen, ich verstehe völlig, wie es funktionieren sollte und welche Lösung dies sein sollte, aber nichts davon scheint für dieses spezielle Projekt zu funktionieren. 

Ich bin ein erfahrener iOS-Entwickler, aber dieses Projekt wurde von einem anderen Team erstellt. Daher weiß ich nicht, ob irgendwo in den XIB-Dateien, in der Plist oder in Code etwas versteckt ist, das die obigen Einstellungen beeinträchtigen könnte. Bitte lassen Sie mich wissen, ob es noch etwas gibt, über das Sie nachsehen können, oder ob Sie weitere Informationen zur Verfügung stellen können.

Danke im Voraus!

20
svguerin3

Wenn Sie die Delta-Werte für iOS 6/7 im Interface Builder festlegen, denken Sie daran, im Interface Builder-Dokument "Anzeigen als" auf "iOS 6" zu setzen, da das iOS 6-Layout zu replizieren ist. Die Deltas werden dann nur unter iOS 7 verwendet, um den Inhalt unter der Statusleiste zu pushen. Wenn Sie "Anzeigen als" auf "iOS 7" (Standardeinstellung) setzen, erhalten Sie stattdessen den iOS 7-Look von Deltas.

Die Deltas helfen Ihnen jedoch nicht, wenn Sie Ansichten programmgesteuert basierend auf dem Ansichtsrahmen neu positionieren oder deren Größe ändern, da der Rahmen die Deltas nicht berücksichtigt.

Anstatt die Deltas zu verwenden, ist die beste Lösung, die ich gefunden habe, die Aktivierung von Auto Layout auf der Haupt-XIB und die Einstellung der oberen Platzbeschränkung in der oberen/Inhaltsansicht entsprechend der Anleitung für oberste Layouts. Dieses Handbuch wurde in iOS 7 eingeführt und repräsentiert die Position unterhalb der Statusleiste. Leider ist das Handbuch nicht im Interface Builder verfügbar, wenn Storyboards nicht verwendet werden. Sie können es jedoch programmgesteuert hinzufügen.

Was ich getan habe, war, dem Interface in Interface Builder eine Top-Space-Einschränkung hinzuzufügen, und im Code einen Auslass dafür zu erstellen. Ersetzen Sie dann in viewDidLoad, wenn topLayoutGuide verfügbar ist (iOS 7+), die Einschränkung in dieser Steckdose durch eine Version, die stattdessen das Top Layout Guide verwendet.

if ([self respondsToSelector:@selector(topLayoutGuide)]) {
    [self.view removeConstraint:self.containerTopSpaceConstraint];

    self.containerTopSpaceConstraint =
    [NSLayoutConstraint constraintWithItem:self.contentView
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.topLayoutGuide
                                 attribute:NSLayoutAttributeBottom
                                multiplier:1
                                  constant:0];

    [self.view addConstraint:self.containerTopSpaceConstraint];

    [self.view setNeedsUpdateConstraints];
    [self.view layoutIfNeeded];
}
17
Kim André Sand

Als Referenz funktionierte die Lösung unten, als ich sie auf meine ViewControllers anwendete. Es ist jedoch nicht ideal und ein bisschen hackig. Wenn es die einzige Herangehensweise ist, die ich ergreifen kann, dann soll es auch so sein.

float systemVersion=[[[UIDevice currentDevice] systemVersion] floatValue];
if(systemVersion>=7.0f)
{
    CGRect tempRect;
    for(UIView *sub in [[self view] subviews])
    {
        tempRect = [sub frame];
        tempRect.Origin.y += 20.0f; //Height of status bar
        [sub setFrame:tempRect];
    }
}
6
svguerin3

Apple fordert Sie dazu auf, Autolayout zu verwenden. Sie müssen in der oberen Unteransicht Ihrer Ansicht eine Einschränkung für die "Top Layout Guide" festlegen.

In diesem Dokument finden Sie Beispiele:

https://developer.Apple.com/library/ios/qa/qa1797/_index.html

Um dies ohne XIBs zu tun, müssen Sie die Einschränkung programmgesteuert hinzufügen. Die Dokumente von Apple geben ein gutes Beispiel dafür, das ich unten zusammengefasst habe.

Wenn die Variable topLayoutGuide eine Eigenschaft eines View-Controllers ist, verwenden Sie sie einfach in Ihrem Wörterbuch der Variablenbindungen. Dann richten Sie Ihre Einschränkung wie gewohnt ein:

id topGuide = [myViewController topLayoutGuide];
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(button, topGuide);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide]-20-[button]" options:0 metrics:nil views:viewsDictionary]; 

Die Dokumentation dazu finden Sie in der Klassenreferenz UIViewController .

5
petehare

1) Die einfachste Lösung, wenn es Ihnen nichts ausmacht, eine undurchsichtige Navigationsleiste zu verwenden:

self.navigationController.navigationBar.translucent = NO;

2) Die Antwort von svguerin3 kann im allgemeinen Fall nicht funktionieren. Wenn beispielsweise bei einer Ihrer Unteransichten Autosizing verwendet wird, um am unteren Rand des Containers angehängt zu werden, ist die neue Position falsch. Und im schlimmsten Fall könnte es den Bildschirm verlassen.

3
Aurelien Porte
- (void)viewDidAppear:(BOOL)animated {
        [self.view setFrame:CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height)];
// OR
        self.view.transform = CGAffineTransformMakeTranslation(0, 20);
}
2
Mazen Kasser

Wenn Sie das Storyboard verwenden, nachdem Sie das oberste Layout Ihrer Ansicht festgelegt haben, können Sie das Kontrollkästchen "Unter undurchsichtigen Balken" im Informations-Inspektor deaktivieren

Storyboard

0
dhin

Haben Sie versucht, Ihre XIBs als Quelle anzuzeigen und Zeilen mit Kanten für das erweiterte Layout zu entfernen?

Wir mussten diese Zeile in den Szenen unseres Storyboards entfernen, da die Hauptansichten unserer Storyboards durch XIBs dargestellt werden

Was für uns passierte, war, dass in einigen Szenen der XIB-Inhalt für die Hauptansicht der Szene um die Höhe der Statusleiste und der Navigationsleiste gedrückt wurde.

Wenn Sie diese Linie entfernen, können die XIBs so angezeigt werden, als ob ihre Spitze am selben oberen Rand der Storyboard-Szene stünde.

Leider haben wir keine Ahnung, was das ausgelöst hat, aber ich habe gesehen, dass dies passiert, wenn Sie die Reihenfolge der Inhalte in der Hauptansicht von XIB so ändern, dass zuerst eine UITextView erscheint. Das Umstellen der Reihenfolge der Elemente nach dem Auslösen hatte keine Auswirkung auf die Beseitigung dieses unerwünschten Verhaltens. 

Ich hoffe, das hilft allen anderen, die auf dieses Problem stoßen.

0
Alex Zavatone