问题
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