Constraints Removing SegmentController from view

2019-09-20 01:58发布

问题:

I have a UICollectionView and a SegmentController.

The required end result:

SegmentController fully in view, UICollectionView beneath it

Before adding constraints:

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

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 :

回答1:

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



回答2:

You can try

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

Note top of segment should be hooked with top of view not bottom as you did here

SegmentController.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor,

//

let SegmentController = UISegmentedControl(items: ["Safe","Ask"])

let ProductsCollection = UIView()

ProductsCollection.backgroundColor = .red

view.addSubview(SegmentController)

view.addSubview(ProductsCollection)

SegmentController.translatesAutoresizingMaskIntoConstraints = false

ProductsCollection.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)
])