Einfache Möglichkeit, die Position von UIView zu ändern?

72

Ich ändere die Position einer UIView mit folgenden Codes, ohne die Größe der Ansicht zu ändern.

CGRect f = aView.frame;
f.origin.x = 100; // new x
f.origin.y = 200; // new y
aView.frame = f;

Gibt es eine einfachere Möglichkeit, nur die Ansichtsposition zu ändern?

Seunghoon
quelle
3
Hinweis: Es funktioniert nicht, wenn Sie AutoLayouts verwenden.
Anton Kashpor

Antworten:

228
aView.center = CGPointMake(150, 150); // set center

oder

aView.frame = CGRectMake( 100, 200, aView.frame.size.width, aView.frame.size.height ); // set new position exactly

oder

aView.frame = CGRectOffset( aView.frame, 10, 10 ); // offset by an amount

Bearbeiten:

Ich habe das noch nicht kompiliert, aber es sollte funktionieren:

#define CGRectSetPos( r, x, y ) CGRectMake( x, y, r.size.width, r.size.height )

aView.frame = CGRectSetPos( aView.frame, 100, 200 );
TomSwift
quelle
2
Ja, stimme auch von mir für CGRectOffset. Es reduziert den Kauderwelsch. Gibberish kann ich jetzt für etwas anderes ausgeben.
Thomax
3
Für Swift 3: aView.frame = aView.frame.offsetBy (dx: 100, dy: 100)
Sulabh
Gibt es eine Möglichkeit, diesen Übergang zu animieren - er sieht ziemlich irritierend aus.
Schnurrende Taube
32

Ich hatte das gleiche Problem. Ich habe eine einfache UIView-Kategorie erstellt, die das behebt.

.h

#import <UIKit/UIKit.h>


@interface UIView (GCLibrary)

@property (nonatomic, assign) CGFloat height;
@property (nonatomic, assign) CGFloat width;
@property (nonatomic, assign) CGFloat x;
@property (nonatomic, assign) CGFloat y;

@end

.m

#import "UIView+GCLibrary.h"


@implementation UIView (GCLibrary)

- (CGFloat) height {
    return self.frame.size.height;
}

- (CGFloat) width {
    return self.frame.size.width;
}

- (CGFloat) x {
    return self.frame.origin.x;
}

- (CGFloat) y {
    return self.frame.origin.y;
}

- (CGFloat) centerY {
    return self.center.y;
}

- (CGFloat) centerX {
    return self.center.x;
}

- (void) setHeight:(CGFloat) newHeight {
    CGRect frame = self.frame;
    frame.size.height = newHeight;
    self.frame = frame;
}

- (void) setWidth:(CGFloat) newWidth {
    CGRect frame = self.frame;
    frame.size.width = newWidth;
    self.frame = frame;
}

- (void) setX:(CGFloat) newX {
    CGRect frame = self.frame;
    frame.origin.x = newX;
    self.frame = frame;
}

- (void) setY:(CGFloat) newY {
    CGRect frame = self.frame;
    frame.origin.y = newY;
    self.frame = frame;
}

@end
gcamp
quelle
Am Ende habe ich genau die gleichen Klassenmethoden entwickelt, aber nicht daran gedacht, sie an die ursprüngliche UIView-Klasse anzuhängen! +1 für praktisch und klug!
NoodleOfDeath
Wenn Sie so etwas wie dies in Swift- fühlen Sie sich frei zu verwenden github.com/katleta3000/UIView-Frame
katleta3000
12

UIViews haben auch eine centerEigenschaft. Wenn Sie nur die Position verschieben möchten, anstatt die Größe zu ändern, können Sie dies einfach ändern - z.

aView.center = CGPointMake(50, 200);

Andernfalls würden Sie es so machen, wie Sie es gepostet haben.

lxt
quelle
6

Ich fand einen ähnlichen Ansatz (es wird auch eine Kategorie verwendet) mit der Antwort von gcamp, der mir hier sehr geholfen hat . In Ihrem Fall ist das so einfach:

aView.topLeft = CGPointMake(100, 200);

Wenn Sie jedoch beispielsweise horizontal und links mit einer anderen Ansicht zentrieren möchten, können Sie einfach:

aView.topLeft = anotherView.middleLeft;
Meda
quelle
6

Die Lösung in der ausgewählten Antwort funktioniert bei Verwendung von Autolayout nicht. Wenn Sie Autolayout für Ansichten verwenden, sehen Sie sich diese Antwort an .

Sahil
quelle
4
aView.frame = CGRectMake(100, 200, aView.frame.size.width, aView.frame.size.height);
Mark Adams
quelle
Ich glaube, wir haben alle zur gleichen Zeit dasselbe geschrieben.
TomSwift
2
Ich liebe den Nervenkitzel, zuerst die beste Antwort zu haben.
Mark Adams
2

In meiner Arbeit verwenden wir keine Makros. Die von @TomSwift bereitgestellte Lösung hat mich also inspiriert. Ich sehe die Implementierung für CGRectMake und erstelle die gleichen CGRectSetPos, jedoch ohne Makros.

CG_INLINE CGRect
CGRectSetPos(CGRect frame, CGFloat x, CGFloat y)
{
  CGRect rect;
  rect.origin.x = x; rect.origin.y = y;
  rect.size.width = frame.size.width; rect.size.height = frame.size.height;
  return rect;
}

Zur Verwendung setze ich nur Frame, X und Y.

viewcontroller.view.frame = CGRectSetPos(viewcontroller.view.frame, 100, 100);

Arbeite für mich ^ _ ^

gzfrancisco
quelle
Ich überprüfe die ursprüngliche Implementierung von CGRectMake und so machen sie (Apple) es. Also folge ich ihnen.
Gzfrancisco
2

Wenn jemand Licht braucht SwiftErweiterung Änderung UIViewleicht Margen - können Sie nutzen diese

view.top = 16
view.right = self.width
view.bottom = self.height
self.height = view.bottom
katleta3000
quelle
2

@ TomSwift Swift 3 Antwort

aView.center = CGPoint(x: 150, y: 150); // set center

Oder

aView.frame = CGRect(x: 100, y: 200, width: aView.frame.size.width, height: aView.frame.size.height ); // set new position exactly

Oder

aView.frame = aView.frame.offsetBy(dx: CGFloat(10), dy: CGFloat(10)) // offset by an amount
Ayman Ibrahim
quelle
0

Hier ist die Swift 3-Antwort für alle, die suchen, da Swift 3 "Make" nicht akzeptiert.

aView.center = CGPoint(x: 200, Y: 200)
Pearson Basham
quelle
0

Andere Weise:

CGPoint position = CGPointMake(100,30);
[self setFrame:(CGRect){
      .origin = position,
      .size = self.frame.size
}];

Dies speichere ich Größenparameter und ändere nur den Ursprung.

Bimawa
quelle
0

schnell

view.frame = view.frame.offsetBy(dx: offsetX, dy: offsetY)
William Hu
quelle