Swift 3: Cant programmatically create label on Collectionview header properly?

Deadly 提交于 2019-12-13 17:19:48

问题


Alright, so Im working in Swift 3 here and Im new to uicollectionviews. I am trying to programmatically add a label as a subview of a header UICollectionReusableView in my collection view. I have added the label like any other view, but I cant for the life of me CENTER the label on the header.

Here is my label code in the custom header class, which is added to the header in the storyboard:

let pointsLabel = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.customInit()
    }


    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        self.customInit()
    }

    func customInit() {

        //center inside content
        pointsLabel.frame = CGRect(x: 0, y: 0, width: self.bounds.width, height: 100)
    pointsLabel.center = CGPoint(x: self.bounds.width * 0.5, y: self.bounds.height * 0.5)
    pointsLabel.textColor = UIColor.darkGray
    pointsLabel.textAlignment = .center

        pointsLabel.text = "Testing 123"
        pointsLabel.font = UIFont(name: "Montserrat", size: 30)
        self.addSubview(pointsLabel)

    }

My Collectionview does have a margin on either side:

self.collectionView.contentInset = UIEdgeInsets(top: 0, left: 32.5, bottom: 0, right: 32.5)

However that should just affect the size of the header view, meaning the label should still be centered at the header.bounds.width * 0.5. And I centered the text alignment, yet the text is skewed to the left:

If it helps, my collection view is within an message app extension, but again I don't know how that would change things. What is wrong here?

Even with:

pointsLabel.frame = CGRect(x: 0, y: 0, width: self.bounds.width, height: 100)
    //pointsLabel.center = CGPoint(x: self.bounds.width * 0.8, y: self.bounds.height * 0.5)
        pointsLabel.center = self.center
        pointsLabel.textColor = UIColor.darkGray
        pointsLabel.backgroundColor = UIColor.blue

Or changing my width to less, I get:

Why?


回答1:


If you have both header and footer so You may replace viewForSupplementaryElementOfKind function with below code

 func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

       switch kind {
        case UICollectionElementKindSectionHeader:

            let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier:
            headerId, for: indexPath) as! CustomHeader
            return header

        default:
            return UIHeaderView()
        }
}



回答2:


You can use Swift anchoring system to have the label fill the header. You can create your own custom header class like such. The way the anchoring works it'll set constraints on the label to expand to the top, left, right and bottom of the view no matter the size. By adding the constants [32.5 and -32.5] to the left and right anchor it'll add the insets spacing you're looking for. Hope this helps.

Custom Header Class

class CustomHeader: UICollectionViewCell {

    let pointsLabel: UILabel = {
     let n = UILabel()
         n.textColor = UIColor.darkGray
         n.textAlignment = .center
         n.text = "Testing 123"
         n.font = UIFont(name: "Montserrat", size: 30)
     return n
   }()

   override init(frame: CGRect) {
    super.init(frame: frame)
     addSubview(pointsLabel)

     pointsLabel.translatesAutoresizingMaskIntoConstraints = false
     pointsLabel.leftAnchor.constraint(equalTo: leftAnchor, constant: 32.5).isActive = true
     pointsLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: -32.5).isActive = true
     pointsLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
     pointsLabel.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
   }
}

ViewController that uses this header you can register and declare the width and height you would like the header to be like below. So which every class you have that's to use the custom header add the below functions to your file and it should give you what you're looking for. =]

class ControllerUsesHeader: UICollectionViewController {
  let headerId = "headerId"

  override func viewDidLoad() {
   super.viewDidLoad()

   collectionView?.register(CustomHeader.self, forSupplementaryViewOfKind:
        UICollectionElementKindSectionHeader, withReuseIdentifier: headerId)
  }


  override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind:
    String, at indexPath: IndexPath) -> UICollectionReusableView {
        let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier:
            headerId, for: indexPath) as! CustomHeader
        return header
      }

} 

extension ControllerUsesHeader: UICollectionViewDelegateFlowLayout {
  func collectionView(_ collectionView: UICollectionView, layout 
    collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection 
    section: Int) -> CGSize {
    return CGSize(width: view.frame.width, height: 100)
}


来源:https://stackoverflow.com/questions/39989307/swift-3-cant-programmatically-create-label-on-collectionview-header-properly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!