ChatGPT解决这个技术问题 Extra ChatGPT

如何使 UIView 的子视图居中

我在 UIViewm 中有一个 UIView,我希望内部 UIView 始终位于外部 UIView 的中心,而不必调整宽度和高度。

我已经设置了支柱和弹簧,使其位于顶部/左侧/右侧/底部,而无需设置调整大小。但它仍然没有居中。任何想法?

接受的答案是错误的,会崩溃。 Hejazi 的回答效果很好。

H
Hejazi

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

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

对于斯威夫特:

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

之后不要忘记 child.frame = CGRectIntegral(child.frame);
一个:这仅在您没有更改父视图的中心/位置时才有效。 第二:如果您使用这种方法,则无需转换点(它已经采用正确的格式)只需使用child.center = parent.center。我会使用`child.center = CGPointMake(parent.bounds.height/2, parent.bounds.width/2)'。无论您的父视图中心设置为什么,这将始终使您的子视图居中。
如果视图尚未添加到视图层次结构中(例如在初始化对象时),它也没有用
@Hejazi 也可以添加快速答案;)
@Soumen 不,有区别。 UIView.bounds 相对于 视图本身(因此 bounds.origin 最初为零),而 UIView.centersuperview 的坐标系中指定。
C
Cœur

Objective-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)

您应该使用 bounds 而不是 frame,因为如果视图具有 transform,则 frame 是未定义的。
在这种情况下,它实际上不会有什么不同,因为只使用了 size
没关系,如果视图具有不是身份转换的 transform,则整个 frame 属性是未定义的;阅读documentation on the frame property of UIView
不幸的是,这个答案实际上是错误的。只需使用 Heja 的正确答案。
@Fattie 这里到底出了什么问题?我用它来使 ImageView 在 View 中居中,它正在工作。
A
Alexander Abakumov

在开始之前,让我们提醒一下,原点是视图的左上角 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()
    }

}

这将创建这个视图:黑色矩形的原点和中心确实适合与其父级相同的坐标

https://i.stack.imgur.com/kNM0f.png

现在让我们尝试将 subView 添加到另一个 SubSubView,并赋予 subSubview 与 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)

这是结果:

https://i.stack.imgur.com/viHzv.png

因为这条线:

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

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

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

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

看看魔术,subSubview 现在正好位于它的父原点:

https://i.stack.imgur.com/fpudG.png

所以,你喜欢“好吧,我只想以我父母的观点为中心,有什么大不了的?”好吧,这没什么大不了的,您只需要通过执行以下操作将从其框架中获取的父中心点“翻译”到父边界中心:

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

您实际上是在告诉他“获取父母视图中心,并将其转换为 subSubView 世界”。

你会得到这个结果:

https://i.stack.imgur.com/XDbSd.png


'subSubView.center = subView.convertPoint(subView.center, fromView: subSubView)' 放置在哪里?
t
theprojectabot

我会使用:

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

我喜欢使用 CGRect 选项...

斯威夫特 3:

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

C
Cemal Eker

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

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

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

UIView *view1, *view2;
[childview setTranslatesAutoresizingMaskIntoConstraints:NO];

如果你是 UIView+Autolayout 或者 Purelayout:[view1 autoAlignAxis:ALAxisHorizontal toSameAxisOfView:view2]; [view1 autoAlignAxis:ALAxisVertical toSameAxisOfView:view2];如果您仅使用 UIKit 级别的自动布局方法: [view1 addConstraints:({ @[ [NSLayoutConstraint constraintWithItem:view1 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeCenterX multiplier:1.f constant:0.f], [NSLayoutConstraint constraintWithItem :view1 属性:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:view2 属性:NSLayoutAttributeCenterY 乘数:1.f 常量:0.f] ]; })];

2.没有自动布局:

我更喜欢:

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.frame = CGRectIntegral(child.frame);是 BL 描述的问题的一种优雅的包罗万象/随处使用的解决方案。
@JoeBlow:感谢您的提醒。我曾经喜欢四舍五入,但使用块样式时使用起来更优雅CGRectIntegral
“如果你只使用 UIKit 级别的自动布局方法:”会导致错误。
j
juancazalla

最简单的方法:

child.center = parent.center

我的意思是你应该添加更多关于它是如何工作的解释/描述。
搜索了很多这种类型的答案,这个简单的答案对我有用。谢谢。
S
Sayali Shinde

您可以使用

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

在 Swift 3.0 中

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

第二个代码示例在 swift 4 中完美运行。太棒了👍🏻!
是的!谢谢你,终于。不知道 midX / midY 的事情。完美。
M
Mayank Jain

https://i.stack.imgur.com/oJ3wL.png

将此自动调整大小蒙版设置为您的内部视图。


使用自动布局,没有自动调整窗口大小。
@Allen 如果要使用自动调整大小,则必须禁用自动布局。
F
Foobar

使用 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。

这将防止崩溃和 AutoLayout 干扰。


c
codeFood

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

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

这将使子视图相对于视图的超级视图居中。在上述情况下,它正在工作,因为原点位于 (0, 0)。
H
H6.

PureLayout 使用 autoCenterInSuperview 的另一种解决方案。

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

[outerview addSubview:innerView];

[innerView autoCenterInSuperview];

这就是它的样子:

https://i.stack.imgur.com/M7dIN.png


A
Anisetti Nagendra

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

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


K
KamyFC

这对我有用

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

O
Old Name

我会使用:

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

这很简单,简短而甜蜜。如果您在上面使用@Hejazi 的答案并且 parent.center 设置为 (0,0) 以外的任何内容,您的子视图将不会居中!


S
Sidd Redkar
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