wake-up-neo.net

Kann ich das Autolayout zur Laufzeit für eine bestimmte Unteransicht deaktivieren?

Ich habe eine Ansicht, deren Rahmen programmgesteuert manipuliert werden muss - es handelt sich um eine Art Dokumentansicht, die sich auf den Inhalt des Dokuments auswirkt, der dann durch eine Bearbeitung des Rahmens Origin verschoben und vergrößert wird. Autolayout kämpft damit zur Laufzeit.

Die Deaktivierung des Autolayouts scheint etwas hart zu sein, da dies für die Layouterstellung der anderen Ansichten sinnvoll verwendet werden kann. Es scheint, als würde ich eine Art "Null-Einschränkung" wünschen.

98
terriblememory

Ich hatte das gleiche Problem. Aber ich habe es gelöst. 
Ja, Sie können das automatische Layout zur Laufzeit für ein bestimmtes UIView deaktivieren, anstatt es für das gesamte Xib oder Storyboard zu deaktivieren, das standardmäßig in Xcode 4.3 und höher festgelegt ist.

Setzen Sie translatesAutoresizingMaskIntoConstraints auf YES, bevor Sie den Rahmen Ihrer Unteransicht festlegen:

self.exampleView.translatesAutoresizingMaskIntoConstraints = YES;
self.exampleView.frame = CGRectMake(20, 20, 50, 50);
164

Ich hatte ein ähnliches Problem, bei dem Autolayout einige meiner Frames zur Laufzeit überschrieb (ich hatte eine dynamische Ansicht, die in einigen Fällen einen neuen View-Controller drückte ... Durch Drücken und dann Zurück wurde die ursprüngliche Ansicht zurückgesetzt).

Ich bin damit umgekommen, indem ich meinen Manipulationscode in viewDidLayoutSubviews meines View Controllers gesetzt habe. Dies wird anscheinend nach dem Aufruf von mojo aufgerufen, der vor dem Aufruf von viewDidAppear aufgerufen wurde, sodass der Benutzer nicht schlauer ist.

49
jmstone617

Wenn Sie einfach translatesAutoresizingMaskIntoConstraints auf YES setzen (und keine zusätzlichen Einschränkungen für diese Ansicht hinzufügen), können Sie den Rahmen festlegen, ohne das automatische Layout-System zu bekämpfen.

26
Jon Hull

In iOS 8 können Sie eine NSLayoutConstraint als aktiv festlegen oder nicht. Wenn ich also den Interface Builder verwende, füge ich alle meine Einschränkungen zu einer OutletCollection hinzu und aktiviere oder deaktiviere sie mit:

NSLayoutConstraint.deactivateConstraints(self.landscapeConstraintsPad)
NSLayoutConstraint.activateConstraints(self.portraitConstraintsPad)

Die spezielle Anwendung, für die ich es hier verwende, besteht in der Einschränkung im Hoch- und Querformat, und ich aktiviere/deaktiviere die Rotation des Geräts. Dies bedeutet, dass ich im Interface Builder einige komplexe Layoutänderungen für beide Ausrichtungen erstellen kann und weiterhin das automatische Layout ohne den ausführlichen automatischen Layoutcode verwenden kann. 

Oder Sie können mit removeConstraints und addConstraints aktivieren/deaktivieren. 

17
bandejapaisa

Ich weiß nicht, ob dies jemandem helfen wird, aber ich habe eine Kategorie geschrieben, um das bequemer zu gestalten, weil ich dies oft tue.

UIView + DisableAutolayoutTemporarily.h

#import <UIKit/UIKit.h>

@interface UIView (DisableAutolayoutTemporarily)

// the view as a parameter is a convenience so we don't have to always
// guard against strong-reference cycles
- (void)resizeWithBlock:(void (^)(UIView *view))block;

@end

UIView + DisableAutolayoutTemporarily.m

#import "UIView+DisableAutoResizeTemporarily.h"
@implementation UIView (DisableAutoResizeTemporarily)

- (void)resizeWithBlock:(void (^)(UIView * view))block
{
    UIView *superview = self.superview;
    [self removeFromSuperview];
    [self setTranslatesAutoresizingMaskIntoConstraints:YES];
    __weak UIView *weakSelf = self;
    block(weakSelf);
    [superview addSubview:self];
}

@end

Ich benutze es so:

[cell.argumentLabel resizeWithBlock:^(UIView *view) {
    [view setFrame:frame];
}];

Ich hoffe es hilft.

8
michaelsnowden

Sie können den translatesAutoresizingMaskIntoConstraints-Typ Boolean, Value Yes in den benutzerdefinierten Laufzeitattributen der gewünschten UIView im xib/storyboard festlegen.

6
renaun

Bei mir funktionierte es, die Unteransicht programmatisch zu erstellen. In meinem Fall verwirrte das automatische Layout mit einer Ansicht, die ich um seine Mitte drehen musste, aber nachdem ich diese Ansicht programmgesteuert erstellt hatte, funktionierte es.

1
Andrespch

Aus meiner Sicht hatte ich ein Label und einen Text. Das Etikett hatte eine Schwenkbewegung. Während des Ziehens bewegt sich das Etikett gut. Wenn ich jedoch die Textfeldtastatur verwende, setzt das Label seine Position auf die im automatischen Layout definierte ursprüngliche Position zurück. Das Problem wurde behoben, als ich in Swift Folgendes für das Label hinzufügte. Ich habe dies in viewWillAppear hinzugefügt, aber es kann überall hinzugefügt werden, wo Sie Zugriff auf das Zielfeld haben.

self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true
1
Big D
  • Projekt in 4.5 öffnen
  • Storyboard auswählen
  • Öffnen Sie den Dateiinspektor
  • Deaktivieren Sie unter Interface Builder Document die Option "Use Autolayout".

Sie können sich auf mehrere Storyboards aufteilen, wenn Sie für einige Ansichten das automatische Layout verwenden möchten.

1
Mike Bobbitt

Ich bin einem ähnlichen Szenario begegnet, in dem ich einem Projekt beigetreten bin, das mit Auto-Layout initiiert wurde, aber ich musste dynamische Anpassungen an mehreren Ansichten vornehmen. Folgendes hat für mich funktioniert:

  1. Lassen Sie sich NICHT Ansichten oder Komponenten im Interface Builder anzeigen.

  2. Fügen Sie Ihre Ansichten rein programmgesteuert hinzu. Beginnen Sie mit Allocation/Init und setzen Sie ihre Frames entsprechend.

  3. Erledigt.

0
Yup.

Das ist mir in einem Projekt ohne Storyboards oder Xib-Dateien passiert. Alle 100% Code. Ich hatte ein Werbebanner am unteren Rand und wollte, dass die Ansichtsgrenze beim Werbebanner endet. Die Ansicht ändert sich automatisch nach dem Laden. Ich habe alle Auflösungen auf dieser Seite ausprobiert, aber keine davon hat funktioniert. 

Am Ende habe ich nur eine Unteransicht mit der verkürzten Höhe erstellt und diese in die Hauptansicht des Controllers eingefügt. Dann ging mein gesamter Inhalt in die Untersicht. Dies löste das Problem sehr leicht, ohne etwas zu tun, das sich anfühlte, als würde es gegen den Strich laufen.

Ich denke, wenn Sie eine Ansicht haben möchten, die nicht die normale Größe hat, die das Fenster ausfüllt, sollten Sie dafür eine Unteransicht verwenden.

0
RandallTo

Anstatt Autolayout zu deaktivieren, würde ich die neue Einschränkung einfach mit dem Frame berechnen, den Sie ersetzen. Das scheint mir der richtige Weg zu sein. Wenn Sie Komponenten anpassen, die auf Einschränkungen angewiesen sind, passen Sie sie entsprechend an. 

Wenn Sie beispielsweise zwischen zwei Ansichten (myView und otherView) eine vertikale Einschränkung von 0 haben und eine Schwenkbewegung oder etwas, das die Höhe von myView anpasst, vorhanden ist, können Sie die Einschränkung mit den angepassten Werten neu berechnen.

self.verticalConstraint.constant = newMyViewYOriginValue - (self.otherView.frame.Origin.y + self.otherView.frame.size.height);
[self.myView needsUpdateConstraints];
0
Myles Caley

Für diejenigen unter Ihnen, die das automatische Layout verwenden, überprüfen Sie bitte meine Lösung hier . Sie sollten @IBOutlets der Einschränkungen vornehmen, die Sie anpassen möchten, und dann deren Konstanten ändern.

0
Mike