How to center a subview of UIView

前端 未结 14 1835
無奈伤痛
無奈伤痛 2020-11-30 16:47

I have a UIView inside a UIViewm and I want the inner UIView to be always centered inside the outer one, without it having to resize t

相关标签:
14条回答
  • 2020-11-30 17:36

    Before we'll begin, let's just remind that origin point is the Upper Left corner CGPoint of a view. 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

    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)

    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:

    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".

    And you'll get this result:

    0 讨论(0)
  • 2020-11-30 17:39

    Another solution with PureLayout using autoCenterInSuperview.

    // ...
    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:

    Center with PureLayout

    0 讨论(0)
提交回复
热议问题