我的印象是UICollectionView中的自动调整大小单元在iOS 8中变得非常简单。所以,我可能在这里遗漏了一些东西。
我使用UICollectionViewFlowLayout
的子类作为我的布局:
class BuildCollectionViewFlowLayout: UICollectionViewFlowLayout {
required init(coder: NSCoder) {
super.init(coder: coder)
self.minimumLineSpacing = 1
self.sectionInset.top = 20
self.estimatedItemSize = CGSize(width: UIScreen.mainScreen().bounds.width, height: 90)
}
}
然后我的ViewController
是UICollectionViewController
的子类,如下所示:
class ViewController: UICollectionViewController {
let CellIdentifier = "CellIdentifier"
let apiClient: APIClient()
var builds:Array<JSON>? = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.collectionView.registerClass(BuildProjectStatusCollectionViewCell.self, forCellWithReuseIdentifier: CellIdentifier)
self.apiClient.getProjects({ (projects, error) -> Void in
if (error == nil) {
dispatch_async(dispatch_get_main_queue(), {
self.builds = projects
self.collectionView.reloadData()
})
}
else {
}
})
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.builds!.count;
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell:BuildProjectStatusCollectionViewCell = self.collectionView.dequeueReusableCellWithReuseIdentifier(CellIdentifier, forIndexPath: indexPath) as BuildProjectStatusCollectionViewCell;
cell.setup(self.builds?[indexPath.row])
return cell;
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
最后我的观察细胞:
class BuildProjectStatusCollectionViewCell : UICollectionViewCell {
var projectNameLabel: UILabel!
var lastCommitMessageLabel: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
self.initialize()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initialize()
}
override func awakeFromNib() {
self.initialize()
}
func initialize() {
self.contentView.frame = self.bounds;
self.contentView.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
self.projectNameLabel = UILabel(forAutoLayout: ())
self.lastCommitMessageLabel = UILabel(forAutoLayout: ())
self.lastCommitMessageLabel.autoresizingMask = UIViewAutoresizing.FlexibleHeight
self.lastCommitMessageLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
self.lastCommitMessageLabel.numberOfLines = 0
self.contentView.addSubview(self.projectNameLabel)
self.contentView.addSubview(self.lastCommitMessageLabel)
setNeedsUpdateConstraints()
}
func setup(project:JSON!) -> Void {
self.projectNameLabel!.text = project["name"].stringValue
let builds: Array<JSON> = project["builds"].arrayValue!
if builds.count == 1 {
if builds[0]["status"].stringValue == "success" {
self.backgroundColor = UIColor(red: 68/255, green: 175/255, blue: 105/255, alpha: 1.0)
}
else {
self.backgroundColor = UIColor(red: 254/255, green: 57/255, blue: 48/255, alpha: 1.0)
}
self.lastCommitMessageLabel!.text = builds[0]["message"].stringValue
}
}
override func preferredLayoutAttributesFittingAttributes(layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes! {
let attr: UICollectionViewLayoutAttributes = layoutAttributes.copy() as UICollectionViewLayoutAttributes
// Without this, it crashes. AutoLayout constraints playing around. Error: the item width must be less than the width of the UICollectionView minus the section insets left and right values.
return attr;
}
override func updateConstraints() {
super.updateConstraints()
self.projectNameLabel.autoPinEdgesToSuperviewEdgesWithInsets(UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5), excludingEdge: ALEdge.Bottom)
self.lastCommitMessageLabel.autoPinEdge(ALEdge.Top, toEdge: ALEdge.Bottom, ofView: self.projectNameLabel, withOffset: 10)
self.lastCommitMessageLabel.autoPinEdgeToSuperviewEdge(ALEdge.Leading, withInset: 5)
self.lastCommitMessageLabel.autoPinEdgeToSuperviewEdge(ALEdge.Trailing, withInset: 25)
}
}
单元格的大小设置为布局类中的estimatedItemSize
。
我是否应该在preferredLayoutAttributesFittingAttributes
方法中手动计算项目高度?
如果是这样,表格视图是否支持100%自我调整行? (http://www.appcoda.com/self-sizing-cells/)
答案 0 :(得分:4)
您无需覆盖preferredLayoutAttributesFittingAttributes
。并且你的覆盖不会调用super,根据文档:
此方法的默认实现调整大小值以适应自调整单元格所做的更改。子类可以覆盖此方法并使用它来调整其他布局属性。如果您覆盖此方法并希望调整单元格大小,请先调用super,然后对返回的属性进行自己的修改。
所以你得到的警告是合法的。它告诉你你的细胞不能比你的集合视图宽。这可能是因为当您设置estimatedItemSize
时,您没有考虑项目间距(默认情况下为> 0)。尝试设置更小的尺寸。它应该工作。
如果您正在尝试仅尝试自动调整一个尺寸(即始终保持整个宽度),那么请不要打扰。它不起作用,因为estimatedItemSize
意味着两个维度都可以调整大小。