如何定位 UIView 的子视图

我有一个 UIView内的 UIViewm 和我想内部的 UIView始终是中心内的外一个,没有它必须调整宽度和高度。

我已经设置了支柱和弹簧,所以它在上/左/右/底部,而没有设置调整大小。但它还是不在中心。知道吗?

172699 次浏览

1. 如果启用了自动布局:

  • 提示: 使用自动布局将视图集中在另一个视图上,可以对共享至少一个父视图的任意两个视图使用相同的代码。

首先禁用子视图自动调整大小

UIView *view1, *view2;
[childview setTranslatesAutoresizingMaskIntoConstraints:NO];
  1. 如果你是 UIView + 自动布局或 纯布局:

    [view1 autoAlignAxis:ALAxisHorizontal toSameAxisOfView:view2];
    [view1 autoAlignAxis:ALAxisVertical toSameAxisOfView:view2];
    
  2. If you are using only UIKit level autolayout methods:

    [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:

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

目标 C

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

斯威夫特

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

你可以这样做,而且它总是有效的:

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

至于斯威夫特:

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

在视图和子视图中使用相同的中心是最简单的方法。你可以这么做,

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

enter image description here

将此自动调整大小掩码设置为内部视图。

我会用:

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

这很简单,很短,也很贴心。如果你使用@Hejazi 的答案上面和 parent.center被设置为除 (0,0)以外的任何东西,你的子视图将不会居中!

我会用:

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

我喜欢使用 CGRect选项..。

SWIFT 3:

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

另一种使用 autoCenterInSuperview纯布局解决方案。

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


[outerview addSubview:innerView];


[innerView autoCenterInSuperview];

这就是它看起来的样子:

Center with PureLayout

在我们开始之前,让我们提醒一下,原点是视图的左上角 CGPoint。 了解观点和父母是很重要的。

让我们看看这个简单的代码,一个视图控制器添加到它的视图黑色方块:

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()
}


}

这将创建以下视图: 黑色矩形的原点和中心确实与它的父坐标相同

enter image description here

现在让我们尝试添加 subView 另一个 SubSubView,并给予 subView 与 subView 相同的起源,但是使 subSubView 成为 subView 的子视图

我们将添加以下代码:

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

这就是结果:

enter image description here

因为这句话:

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

您期望紫色矩形的原点与它的父矩形(黑色矩形)相同,但它位于它的下方,这是为什么呢? 因为当你将一个视图添加到另一个视图时,subView 框架“ world”现在是它的父 BOUND 矩形,如果你有一个视图,它在主屏幕上的原点是坐标(15,15) ,它的所有子视图,左上角将是(0,0)

这就是为什么你需要总是通过它的绑定矩形来引用父视图,这是它的子视图的“世界”,让我们把这一行修改为:

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

神奇的是,子视图现在正好位于它的父视图中:

enter image description here

所以,你喜欢“好吧,我只是想以我父母的观点为中心,这有什么大不了的?” 嗯,这没什么大不了的,你只需要“转换”父中心点,这是从它的框架取到父的边界中心 通过这样做:

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

你实际上是在告诉他“把家长视图中心转换成 SubView 世界”。

你会得到这样的结果:

enter image description here

最简单的方法:

child.center = parent.center

有了 IOS9,你可以使用布局锚 API。

代码应该是这样的:

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

CGPointMakeCGRect相比,这种方法的优势在于,使用这些方法,你可以将视图的中心设置为一个常量,但使用这种技术,你可以在两个视图之间建立一种关系,无论 parentview如何变化,这种关系都将永远存在。

在你这样做之前,一定要确定:

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

并将每个视图的 translatesAutoresizingMaskIntoConstraints设置为 false。

这将防止崩溃和自动布局的干扰。

你可以用

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

在 Swift 3.0中

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

在 c # 或 Xamarin.ios 中,我们可以这样使用

Center = new CGPoint (temView.Frame.Size. Width/2, 大小高度/2) ;

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

这招对我很管用

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