简体   繁体   English

如何将 UIView 的子视图居中

[英]How to center a subview of UIView

I have a UIView inside a UIView m and I want the inner UIView to be always centered inside the outer one, without it having to resize the width and height.我在UIView m 中有一个UIView ,我希望内部UIView始终位于外部UIView中心,而不必调整宽度和高度的大小。

I've set the struts and springs so that it's on top/left/right/bottom without setting the resize.我已经设置了支柱和弹簧,使其位于顶部/左侧/右侧/底部,而无需设置调整大小。 But it still doesn't center.但它仍然没有居中。 Any idea?任何的想法?

You can do this and it will always work:你可以这样做,它总是有效的:

child.center = [parent convertPoint:parent.center fromView:parent.superview];

And for Swift:而对于斯威夫特:

child.center = parent.convert(parent.center, from:parent.superview)

Objective-C目标-C

yourSubView.center = CGPointMake(yourView.frame.size.width  / 2, 
                                 yourView.frame.size.height / 2);

Swift迅速

yourSubView.center = CGPoint(x: yourView.frame.size.width  / 2,
                             y: yourView.frame.size.height / 2)

Before we'll begin, let's just remind that origin point is the Upper Left corner CGPoint of a view.在开始之前,让我们提醒一下,原点是视图的左上角CGPoint An important thing to understand about views and parents.了解观点和父母的重要事情。

Lets take a look at this simple code, a view controller that adds to it's view a black square:让我们看一下这个简单的代码,一个视图控制器,在它的视图中添加一个黑色方块:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        createDummyView()
        super.view.backgroundColor = UIColor.cyanColor();
    }

    func createDummyView(){
        var subView = UIView(frame: CGRect(x: 15, y: 50, width: 50 , height: 50));
        super.view.addSubview(subView);
        view.backgroundColor = UIColor.blackColor()
    }

}

This will create this view: the black rectangle origin and center does fit the same coordinates as it's parent这将创建此视图:黑色矩形的原点和中心与它的父级坐标相同

在此处输入图片说明

Now let's try to add subView another SubSubView, and giving subSubview same origin as subView, but make subSubView a child view of subView现在让我们尝试添加 subView 另一个 SubSubView,并赋予 subSubview 与 subView 相同的原点,但让 subSubView 成为 subView 的子视图

We'll add this code:我们将添加以下代码:

var subSubView = UIView();
subSubView.frame.origin = subView.frame.origin;
subSubView.frame.size = CGSizeMake(20, 20);
subSubView.backgroundColor = UIColor.purpleColor()
subView.addSubview(subSubView)

And this is the result:这是结果:

在此处输入图片说明

Because of this line:因为这一行:

subSubView.frame.origin = subView.frame.origin;

You expect for the purple rectangle's origin to be same as it's parent (the black rectangle) but it goes under it, and why is that?您希望紫色矩形的原点与其父项(黑色矩形)相同,但它位于其下方,这是为什么呢? Because when you add a view to another view, the subView frame "world" is now it's parent BOUND RECTANGLE, if you have a view that it's origin on the main screen is at coords (15,15) for all it's sub views, the upper left corner will be (0,0)因为当你将一个视图添加到另一个视图时,子视图框架“世界”现在是它的父 BOUND RECTANGLE,如果你有一个视图,它在主屏幕上的原点在所有子视图的坐标 (15,15) 上,左上角将为 (0,0)

This is why you need to always refer to a parent by it's bound rectangle, which is the "world" of it's subViews, lets fix this line to:这就是为什么你需要总是通过它的绑定矩形来引用父级,这是它的子视图的“世界”,让我们将此行修复为:

subSubView.frame.origin = subView.bounds.origin;

And see the magic, the subSubview is now located exactly in it's parent origin:看到神奇的是,subSubview 现在正好位于它的父原点:

在此处输入图片说明

So, you like "ok I only wanted to center my view by my parents view, what's the big deal?"所以,你喜欢“好吧,我只想以我父母的观点为中心,这有什么大不了的?” well, it isn't big deal, you just need to "translate" the parent Center point which is taken from it's frame to parent's bounds center by doing this:好吧,这没什么大不了的,您只需要通过执行以下操作,将父中心点从其框架中“转换”到父边界中心即可:

subSubView.center = subView.convertPoint(subView.center, fromView: subSubView);

You're actually telling him "take parents view center, and convert it into subSubView world".您实际上是在告诉他“将父母视图中心,并将其转换为 subSubView 世界”。

And you'll get this result:你会得到这个结果:

在此处输入图片说明

I would use:我会用:

self.childView.center = CGPointMake(CGRectGetMidX(self.parentView.bounds),
                                    CGRectGetMidY(self.parentView.bounds));

I like to use the CGRect options...我喜欢使用CGRect选项...

SWIFT 3:快速 3:

self.childView.center = CGPoint(x: self.parentView.bounds.midX,
                                        y: self.parentView.bounds.midY);

1. If you have autolayout enabled: 1. 如果您启用了自动布局:

  • Hint: For centering a view on another view with autolayout you can use same code for any two views sharing at least one parent view.提示:为了使用自动布局将视图居中放在另一个视图上,您​​可以对共享至少一个父视图的任何两个视图使用相同的代码。

First of all disable child views autoresizing首先禁用子视图自动调整大小

UIView *view1, *view2;
[childview setTranslatesAutoresizingMaskIntoConstraints:NO];
  1. If you are UIView+Autolayout or Purelayout :如果您是 UIView+Autolayout 或Purelayout

     [view1 autoAlignAxis:ALAxisHorizontal toSameAxisOfView:view2]; [view1 autoAlignAxis:ALAxisVertical toSameAxisOfView:view2];
  2. If you are using only UIKit level autolayout methods:如果您仅使用 UIKit 级别的自动布局方法:

     [view1 addConstraints:({ @[ [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeCenterX multiplier:1.f constant:0.f], [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeCenterY multiplier:1.f constant:0.f] ]; })];

2. Without autolayout: 2. 没有自动布局:

I prefer:我更喜欢:

UIView *parentView, *childView;
[childView setFrame:({
    CGRect frame = childView.frame;

    frame.origin.x = (parentView.frame.size.width - frame.size.width) / 2.0;
    frame.origin.y = (parentView.frame.size.height - frame.size.height) / 2.0;

    CGRectIntegral(frame);
})];

最简单的方法:

child.center = parent.center

在此处输入图片说明

Set this autoresizing mask to your inner view.将此自动调整大小蒙版设置为您的内部视图。

You can use您可以使用

yourView.center = CGPointMake(CGRectGetMidX(superview.bounds), CGRectGetMidY(superview.bounds))

And In Swift 3.0在 Swift 3.0 中

yourView.center = CGPoint(x: superview.bounds.midX, y: superview.bounds.midY)

With IOS9 you can use the layout anchor API.使用 IOS9,您可以使用布局锚点 API。

The code would look like this:代码如下所示:

childview.centerXAnchor.constraintEqualToAnchor(parentView.centerXAnchor).active = true
childview.centerYAnchor.constraintEqualToAnchor(parentView.centerYAnchor).active = true

The advantage of this over CGPointMake or CGRect is that with those methods you are setting the center of the view to a constant but with this technique you are setting a relationship between the two views that will hold forever, no matter how the parentview changes.CGPointMakeCGRect相比,它的优势在于,使用这些方法,您将视图的中心设置为常量,但使用此技术,您将设置两个视图之间的关系,无论parentview视图如何更改,该关系都将永远保持。

Just be sure before you do this to do:在执行此操作之前,请确保:

        self.view.addSubview(parentView)
        self.view.addSubView(chidview)

and to set the translatesAutoresizingMaskIntoConstraints for each view to false.并将每个视图的translatesAutoresizingMaskIntoConstraints设置为 false。

This will prevent crashing and AutoLayout from interfering.这将防止崩溃和 AutoLayout 干扰。

Using the same center in the view and subview is the simplest way of doing it.在视图和子视图中使用相同的中心是最简单的方法。 You can do something like this,你可以做这样的事情,

UIView *innerView = ....;
innerView.view.center = self.view.center;
[self.view addSubView:innerView];

Another solution with PureLayout using autoCenterInSuperview .另一个使用autoCenterInSuperview PureLayout解决方案。

// ...
UIView *innerView = [UIView newAutoLayoutView];
innerView.backgroundColor = [UIColor greenColor];
[innerView autoSetDimensionsToSize:CGSizeMake(100, 30)];

[outerview addSubview:innerView];

[innerView autoCenterInSuperview];

This is it how it looks like:这是它的样子:

以 PureLayout 居中

In c# or Xamarin.ios, we can use like this在 c# 或 Xamarin.ios 中,我们可以这样使用

imageView.Center = new CGPoint(tempView.Frame.Size.Width / 2, tempView.Frame.Size.Height / 2); imageView.Center = new CGPoint(tempView.Frame.Size.Width / 2, tempView.Frame.Size.Height / 2);

This worked for me这对我有用

childView.centerXAnchor.constraint(equalTo: parentView.centerXAnchor).isActive = true
childView.centerYAnchor.constraint(equalTo: parentView.centerYAnchor).isActive = true

I would use:我会用:

child.center = CGPointMake(parent.bounds.height / 2, parent.bounds.width / 2)

This is simple, short, and sweet.这很简单,简短而甜蜜。 If you use @Hejazi's answer above and parent.center is set to anything other than (0,0) your subview will not be centered!如果您使用上面@Hejazi 的答案并且parent.center设置为(0,0)以外的任何值,您的子视图将不会居中!

func callAlertView() {

    UIView.animate(withDuration: 0, animations: {
        let H = self.view.frame.height * 0.4
        let W = self.view.frame.width * 0.9
        let X = self.view.bounds.midX - (W/2)
        let Y = self.view.bounds.midY - (H/2)
        self.alertView.frame = CGRect(x:X, y: Y, width: W, height: H)
        self.alertView.layer.borderWidth = 1
        self.alertView.layer.borderColor = UIColor.red.cgColor
        self.alertView.layer.cornerRadius = 16
        self.alertView.layer.masksToBounds = true
        self.view.addSubview(self.alertView)

    })


}// calculation works adjust H and W according to your requirement

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM