Search code examples
swiftuicollectionviewconstraintsuisegmentedcontrol

Constraints Removing SegmentController from view


I have a UICollectionView and a SegmentController.

The required end result:

SegmentController fully in view, UICollectionView beneath it

Before adding constraints:

enter image description here

After adding constraints (Notice the SegmentController is almost entirely hidden):

enter image description here

The Constraints added:

ProductsCollection.removeConstraints(ProductsCollection.constraints) SegmentController.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
    SegmentController.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    SegmentController.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 100),
    //ProductsCollection.topAnchor.constraint(equalTo: SegmentController.bottomAnchor, constant: 10),
    ProductsCollection.leftAnchor.constraint(equalTo: view.leftAnchor),
    ProductsCollection.rightAnchor.constraint(equalTo: view.rightAnchor),
    ProductsCollection.bottomAnchor.constraint(equalTo: view.bottomAnchor)
    ])

I am guessing the problem is I did not add SegmentController constraints, but I had same result when I added :

SegmentController.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 100),
SegmentController.centerXAnchor.constraint(equalTo: view.centerXAnchor),

Edit:

This view inherits from another one, which has :

    private func createProductsCollection()
        {
            let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
            layout.itemSize = CGSize(width: 200, height: 250)

            self.ProductsCollection = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)

            ProductsCollection.dataSource = self
            ProductsCollection.delegate = self
            ProductsCollection.register(ProductsCollectionViewCell.self, forCellWithReuseIdentifier: "product_collection_cell")
            ProductsCollection.backgroundColor = UIColor.clear
            self.view.addSubview(ProductsCollection)

ProductsCollection.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
                NSLayoutConstraint(item: ProductsCollection, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1, constant: 20),
                NSLayoutConstraint(item: ProductsCollection, attribute: .bottom, relatedBy: .equal, toItem: self.view, attribute: .bottom, multiplier: 1, constant: -50), //leaving space for search field
                NSLayoutConstraint(item: ProductsCollection, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leading, multiplier: 1, constant: 0),
                NSLayoutConstraint(item: ProductsCollection, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailing, multiplier: 1, constant: 0)
                ])
        }

EDIT #2:

I am now using these constraints:

SegmentController.translatesAutoresizingMaskIntoConstraints = false
        SegmentController.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor).isActive = true
        SegmentController.heightAnchor.constraint(equalToConstant: 40).isActive = true
        SegmentController.widthAnchor.constraint(equalToConstant: 120).isActive = true
        SegmentController.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true

        self.view.addSubview(ProductsCollection)
        ProductsCollection.translatesAutoresizingMaskIntoConstraints = false
        ProductsCollection.topAnchor.constraint(equalTo: self.SegmentController.bottomAnchor).isActive = true
        ProductsCollection.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
        ProductsCollection.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
        ProductsCollection.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true

And my view now looks like :

enter image description here


Solution

  • Your constraints are not correct. It should not be self.view.safeAreaLayoutGuide.bottomAnchor It should be self.view.safeAreaLayoutGuide.topAnchor. Check what exactly safe area guide gives. From Apple:

    The layout guide representing the portion of your view that is unobscured by bars and other content.

    From that it is easy to get that it is the area inside of the "margins".

    EDIT

            self.view.addSubview(segmentController)
            segmentController.translatesAutoresizingMaskIntoConstraints = false
            segmentController.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor).isActive = true
            segmentController.heightAnchor.constraint(equalToConstant: 40).isActive = true
            segmentController.widthAnchor.constraint(equalToConstant: 120).isActive = true
            segmentController.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
    
            self.view.addSubview(collectionView)
            collectionView.translatesAutoresizingMaskIntoConstraints = false
            collectionView.topAnchor.constraint(equalTo: self.segmentController.bottomAnchor).isActive = true
            collectionView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
            collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
            collectionView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true 
    

    You will also need to remove this frame

    self.ProductsCollection = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
    

    Change it to frame: .zero And the contraints should do the rest