Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autolayout within Manual Layout

Can I add autolayout views inside parent views that are using frame, bounds, autoresizingMask to position itself?

Usually on the internet you see the other way around, but I'm not able to achieve this case.

Edit: I've added some code for you guys. Just create a new Xcode project with "Single View Application" and paste the following code on the ViewController.swift created for us.

class ViewController: UIViewController
{

    override func viewDidLoad()
    {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let custom = CustomManualLayoutSubviews()
        let subview = UIView()
        let childView = UIView()

        custom.backgroundColor = UIColor.red
        subview.backgroundColor = UIColor.green
        childView.backgroundColor = UIColor.blue

        custom.translatesAutoresizingMaskIntoConstraints = false
        subview.translatesAutoresizingMaskIntoConstraints = false
        childView.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(custom)
        custom.addSubview(subview)
        subview.addSubview(childView)

        pin(child: custom, parent: view)
        pin(child: childView, parent: subview)
    }

    private func pin(child: UIView, parent: UIView) {
        parent.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-10-[view]-10-|", options: [], metrics: nil, views: ["view" : child]))
        parent.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-10-[view]-10-|", options: [], metrics: nil, views: ["view" : child]))
    }
}


class CustomManualLayoutSubviews : UIView
{
    override func layoutSubviews() {
        super.layoutSubviews()

        for subview in subviews {
            subview.frame = bounds.insetBy(dx: 10, dy: 10)
            print("subview frame: \(subview)")
        }
    }
}

As you can see from the code, subview is using Manual Layout while custom and childView are using Autolayout. But the result is that the childView that uses autolayout is not displayed on the screen and when I inspect it I see it has a 0 width, 0 height.

That's what I get, there is no blue area at all. enter image description here

like image 625
mohamede1945 Avatar asked May 23 '15 09:05

mohamede1945


People also ask

What is Autolayout when and where would you use it?

What is Auto Layout? Auto Layout is a constraint-based layout system designed for building dynamically sized user interfaces. It lets you create user interface layouts that dynamically adapt for all screen sizes without manually setting the frame of every view.

What does Autolayout do in Figma?

Auto layout is a property you can add to frames and components. It lets you create designs that grow to fill or shrink to fit, and reflow as their contents change. This is great when you need to add new layers, accommodate longer text strings, or maintain alignment as your designs evolve.

What is Autolayout aspect ratio?

If you select Aspect Ratio for a single item, the width of the item is used as the numerator for the ratio, and the height is used for the denominator. If you select Aspect Ratio for multiple items, Auto Layout chooses the width of one of the items for the numerator and the height of another item for the denominator.

How does Autolayout work in Swift?

Auto Layout constraints allow us to create views that dynamically adjust to different size classes and positions. The constraints will make sure that your views adjust to any size changes without having to manually update frames or positions.


2 Answers

Yes, but you have to be very careful and are fairly limited.

Technically, if any view in a window is using auto layout, everything in the window uses auto layout. It's just that constraints are generated automatically from the frame and autoresizingMask for views whose translatesAutoresizingMaskIntoConstraints is left on.

So, you have to make sure your constraints don't interfere with those automatically-generated constraints. You can "hang" stuff loosely off of the views using translatesAutoresizingMaskIntoConstraints, but your constraints must not "push" or "pull" on those views. The views using translatesAutoresizingMaskIntoConstraints must have complete freedom of movement and sizing.

For example, you could use constraints to position a button a short distance in from the leading edge of the container view, but if you also constrain to the trailing edge, you had better make the content-hugging and compression-resistance priorities very low so that they don't try to change the width of the container. Even so, you may end up with conflicts. In auto layout, the width of views is not allowed to go negative. If the container is set to have zero width and the button has non-zero distance to the edges, then that will be a conflict. So, the constraint to the trailing edge should also have a low priority so that it can be broken if necessary. (Or you could do that for the leading edge.)

You say you're not able to achieve using auto layout within a view using translatesAutoresizingMaskIntoConstraints. You'll need to explain what you tried and what happened when you tried if you want further help.

like image 192
Ken Thomases Avatar answered Sep 27 '22 18:09

Ken Thomases


Yes. As soon as 1 view has auto layout enabled, the entire window enables auto layout, translating frames into top, left, width and height constraints (respecting autoresizing mask)

So even though you might think you are manipulating frame or bounds or center properties, it'll be translated into auto layout behind the scenes, making it 100% compatible with you auto layout-enabled views.

like image 20
Sash Zats Avatar answered Sep 27 '22 18:09

Sash Zats