Простой способ изменить положение UIView?

Я меняю положение UIView с помощью следующих кодов без изменения размера представления.

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

Есть ли более простой способ изменить только позицию просмотра?


person Seunghoon    schedule 01.03.2011    source источник
comment
Примечание. Это не работает, если вы используете AutoLayouts.   -  person Anton Kashpor    schedule 01.12.2015


Ответы (13)


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

or

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

or

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

Изменить:

Я еще не скомпилировал это, но оно должно работать:

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

aView.frame = CGRectSetPos( aView.frame, 100, 200 );
person TomSwift    schedule 01.03.2011
comment
Ура, проголосуйте за CGRectOffset и от меня. Это сокращает тарабарщину. Тарабарщина, которую я теперь трачу на что-то другое. - person thomax; 24.10.2013
comment
Для Swift 3: aView.frame = aView.frame.offsetBy(dx: 100, dy: 100) - person sulabh; 06.06.2017
comment
Есть ли способ анимировать этот переход - он выглядит довольно резким. - person purring pigeon; 28.12.2017

У меня такая же проблема. Я сделал простую категорию UIView, которая исправляет это.

.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
person gcamp    schedule 01.03.2011
comment
В итоге я создал точно такие же методы класса, но не подумал добавить их к исходному классу UIView! +1 за практичность и ум! - person NoodleOfDeath; 04.01.2014
comment
Если вам нужно что-то подобное в Swift — смело используйте github.com/katleta3000/UIView-Frame - person katleta3000; 28.11.2015

UIView также имеет свойство center. Если вы просто хотите переместить положение, а не изменить размер, вы можете просто изменить это, например:

aView.center = CGPointMake(50, 200);

В противном случае вы бы сделали это так, как вы написали.

person lxt    schedule 01.03.2011

Я нашел аналогичный подход (он также использует категорию) с ответом gcamp, который мне очень помог здесь. В вашем случае все просто:

aView.topLeft = CGPointMake(100, 200);

но если вы хотите, например, центрировать по горизонтали и слева с другим видом, вы можете просто:

aView.topLeft = anotherView.middleLeft;
person Meda    schedule 25.01.2013

Решение в выбранном ответе не работает в случае использования Autolayout. Если вы используете Autolayout для представлений, взгляните на этот ответ< /а>.

person Sahil    schedule 15.11.2013

С тех пор CGRectOffset был заменен методом экземпляра offsetBy.

https://developer.apple.com/reference/coregraphics/cgrect/1454841-offsetby

Например, то, что раньше

aView.frame = CGRectOffset(aView.frame, 10, 10)

теперь будет

aView.frame = aView.frame.offsetBy(dx: CGFloat(10), dy: CGFloat(10))
person Roope    schedule 12.04.2017

В моей работе мы не используем макросы. Так что решение, предоставленное @TomSwift, вдохновило меня. Вижу реализацию для CGRectMake и создаю такой же CGRectSetPos но без макросов.

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

Для использования я поставил только рамку, X и Y

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

Работай на меня ^_^

person gzfrancisco    schedule 30.10.2013
comment
Я проверяю оригинальную реализацию CGRectMake, и вот как они (Apple) это делают. Так что я следую за ними. - person gzfrancisco; 11.06.2015

Если кому-то нужно легкое Swift расширение для простого изменения UIView полей, вы можете использовать это

view.top = 16
view.right = self.width
view.bottom = self.height
self.height = view.bottom
person katleta3000    schedule 28.11.2015

@TomSwift Свифт 3 ответ

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

Or

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

Or

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

Вот ответ Swift 3 для тех, кто ищет, поскольку Swift 3 не принимает «Сделать».

aView.center = CGPoint(x: 200, Y: 200)
person Pearson Basham    schedule 09.01.2017

Другой путь:

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

Это я сохраняю параметры размера и меняю только происхождение.

person Bimawa    schedule 17.09.2017

быстро

view.frame = view.frame.offsetBy(dx: offsetX, dy: offsetY)
person William Hu    schedule 26.05.2020

person    schedule
comment
Я думаю, что мы печатали одно и то же в одно и то же время. - person TomSwift; 02.03.2011
comment
Я люблю острые ощущения от попытки получить лучший ответ первым. - person Mark Adams; 02.03.2011