Rythm
Rythm

Reputation: 191

Auto-layout with constraintsWithVisualFormat is not working well

I have Set scrollview and add constraints to scrollview. But it is showing blank screen. Please check below code.

override func loadView()
    {
        super.loadView()
        scrollView = UIScrollView(frame:CGRectZero)
        scrollView.backgroundColor = UIColor.whiteColor()

        scrollView.sizeToFit()

        self.view.addSubview(scrollView)
        scrollView.backgroundColor = UIColor.blueColor()

        contentView = UIView()
//        contentView.setTranslatesAutoresizingMaskIntoConstraints(false)
        contentView.backgroundColor = UIColor.redColor()
        scrollView.addSubview(contentView)

        var viewBindingsDictBoth = [String: AnyObject]()
        viewBindingsDictBoth["scrollView"] = scrollView
        viewBindingsDictBoth["contentView"] = contentView
        viewBindingsDictBoth["mainView"] = self.view


        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[scrollView]-0-|",options: [], metrics: nil,  views:viewBindingsDictBoth))

        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[scrollView]-0-|",options: [], metrics: nil, views:viewBindingsDictBoth))

        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[contentView]|",options: [], metrics: nil, views:viewBindingsDictBoth))
        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[contentView]|",options: [], metrics: nil, views:viewBindingsDictBoth))

        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[contentView(==mainView)]",options: [], metrics: nil, views:viewBindingsDictBoth))

        self.view.contentMode = UIViewContentMode.Redraw
    }

Thanks in Advance..

Upvotes: 1

Views: 612

Answers (4)

MCMatan
MCMatan

Reputation: 8843

You have a few mistakes:

    override func loadView()
        {
            super.loadView()
            scrollView = UIScrollView(frame:CGRectZero)
            scrollView.backgroundColor = UIColor.whiteColor()
            scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)

            // No need for sizeToFit with autoLayout
            //scrollView.sizeToFit()

            self.view.addSubview(scrollView)
            scrollView.backgroundColor = UIColor.blueColor()

            contentView = UIView()

           //Always set TranslatesAutoresizingMaskIntoConstraints to false, on every view that users AutoLayout

            contentView.setTranslatesAutoresizingMaskIntoConstraints(false)
            contentView.backgroundColor = UIColor.redColor()
            scrollView.addSubview(contentView)

            var viewBindingsDictBoth = [String: AnyObject]()
            viewBindingsDictBoth["scrollView"] = scrollView
            viewBindingsDictBoth["contentView"] = contentView
            viewBindingsDictBoth["mainView"] = self.view


            view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[scrollView]-0-|",options: [], metrics: nil,  views:viewBindingsDictBoth))

            view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[scrollView]-0-|",options: [], metrics: nil, views:viewBindingsDictBoth))

            view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[contentView]|",options: [], metrics: nil, views:viewBindingsDictBoth))
            view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[contentView]|",options: [], metrics: nil, views:viewBindingsDictBoth))

            view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[contentView(==mainView)]",options: [], metrics: nil, views:viewBindingsDictBoth))

           // self.view.contentMode = UIViewContentMode.Redraw
        }

Upvotes: 0

Sulthan
Sulthan

Reputation: 130122

The most important thing you are missing is

scrollView.translatesAutoresizingMaskIntoConstraints = false

and

contentView.translatesAutoresizingMaskIntoConstraints = false

I think that some of your constraints are not perfect but the biggest problem is that every view is using its autoresizing properties for positioning by default. Those will then collide with your constraints.

From UIView.translatesAutoresizingMaskIntoConstraints documentation:

Note that the autoresizing mask constraints fully specify the view’s size and position; therefore, you cannot add additional constraints to modify this size or position without introducing conflicts. If you want to use Auto Layout to dynamically calculate the size and position of your view, you must set this property to false, and then provide a non ambiguous, nonconflicting set of constraints for the view.

(emphasis mine)

Upvotes: 2

Sonny Saluja
Sonny Saluja

Reputation: 7287

I usually find it very unnecessary to override loadView unless I'm really trying to get the base view (self.view) to be of a different subclass of UIView. loadView is for initializing the value of self.view, which you have forgotten to do.

In your case, for legibility I would recommend moving view initialization to viewDidLoad.

override func viewDidLoad() {
    // Do your init here
}

Upvotes: 1

iSashok
iSashok

Reputation: 2446

In loadView() method of your viewcontroller you need create a root view. Your root view right now is nil
view = UIView()

Upvotes: 0

Related Questions