以编程方式集中UIViews

时间:2010-03-26 16:33:31

标签: iphone user-interface

我已经看到了一堆类似的问题,但似乎没有什么是我正在寻找的。如果我错过了在另一个问题中回答的解决方案,请原谅我!

右。我有一个观点。 160像素既高又宽。我知道这个视图将被用作子视图,我知道总是需要在任何使用它的情况下都以两个轴为中心。

如果以编程方式定义视图,我怎样才能确保它相对于超级视图总是完全居中,水平和垂直?

到目前为止,我所拥有的只是这个简单的代码:

- (void)loadView {
    self.view = [[UIView alloc] initWithFrame:CGRectMake(80, 150, 160, 160)];
    self.view.backgroundColor = [UIColor greenColor];
    self.view.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
    [self.view release];
}

这是集中化,但仅限于最简单的情况。非常感谢任何见解。

编辑1:

添加以下代码行:

 self.view.center = self.view.superview.center;

子视图的中心点成为超视图的(0,0)坐标。也许我还没有正确设置超视图?

5 个答案:

答案 0 :(得分:47)

除了@Jasarien和@Brad所说的,不要忘记你可以使用自动调整弹簧和支柱强制自动定心。基本上(在Interface Builder中)你点击四周,直到没有可见的自动调整线,如下所示:

alt text http://gallery.me.com/davedelong/100084/Screen-20shot-202010-03-26-20at-2010-49-18-20AM/web.jpg?ver=12696222220001

在代码中,您将-[UIView autoresizingMask]设置为:

目标C:

(UIViewAutoresizingFlexibleLeftMargin   | 
 UIViewAutoresizingFlexibleRightMargin  | 
 UIViewAutoresizingFlexibleTopMargin    | 
 UIViewAutoresizingFlexibleBottomMargin)

Swift 3.x:

[.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin]

如果你这样做,那么视图会自动居中。

编辑#1

回答你的编辑,你做不到:

self.view.center = self.view.superview.center;

除非您的视图已添加为另一个视图的子视图([anotherView addSubview:self.view];)。我的猜测是,self.view.superview正在返回nil,因此您(幸运的是)在{0,0}上尝试调用center时,将nil作为返回值

使视图居中的适当位置可能在视图控制器的viewWillAppear:方法中。一旦视图即将出现,您就知道必须具有超级视图(否则它将如何出现?)。您可以安全地在那里设置视图center

答案 1 :(得分:41)

我想说最简单的方法是将视图的中心设置在它的超视图的中心(你可以从superview的高度和宽度属性中获得):

// Init as above and then...
// Get superview's CGSize
CGSize size = self.superview.frame.size;
[self.view setCenter:CGPointMake(size.width/2, size.height/2)];

我认为你不能做得更简单:

self.view.center = self.view.superview.center;

由于superview的中心是在superview的superview中定义的。因此,超级视图可以以(0,0)为中心,但您不希望在此时将视图居中。

引用Apple文档:

  

中心在其超级视图的坐标系中指定

答案 2 :(得分:3)

假设你在UIView的子类中,你可以这样做:

-(void) layoutSubviews {
  self.center = self.superview.center;
}

或者,如果如上所述,您在ViewController内部工作,则可以

- (void)loadView {
//...
    self.view.center = self.view.superview.center;
}

答案 3 :(得分:1)

布拉德·史密斯用一种稍微优雅的解决方案击败了我:D

如果这不是你想要的,请告诉我,但你试过了吗?

// when adding to a subview, try this, where myView is the view you need centered,
// and myMainView is the view you'll be adding it to as a subview
myView.center = myMainView.center;
[myMainView addSubview:myView];

答案 4 :(得分:-2)

我有同样的问题。每次我尝试访问viewDidLoad上的self.view.superview或self.view.window时,都返回nil。在viewDidLoad中(我猜它对于loadView来说是一样的)那些指针尚未初始化。为了解决这个问题,我可以给你一个技巧:

- (void)viewDidLoad 
{
    [super viewDidLoad];

    // both equal to nil
    id lwindow = self.view.window;
    id lparent = self.view.superview;

    [self performSelector:@selector(myViewDidLoad) withObject:nil afterDelay:0.01];
}

- (void)myViewDidLoad
{
    // both not equal to nil!
    id lwindow = self.view.window;
    id lparent = self.view.superview;
} 

就像在viewDidLoad和loadView之后初始化self.view.parent和self.view.window。