最初我有一个密集的控制器,其中包含delegate
和datasource
以及与CollectionView
相关的许多其他内容,这些内容会呈现我的画廊。为了清理代码,我将CollectionView
移动到基于.xib
的自定义创建视图中,这里的关键点是许多数字量保持不变。
以前,一切都很好,每行3张缩略图。然而,现在,虽然每行仍然有3个缩略图,但是这些行溢出屏幕的右侧,实际上是在屏幕外。
我的观点是这样加载的:
@IBOutlet var gridPhotoGalleryView: UICollectionView!
// MARK: Initialization
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
NSBundle.mainBundle().loadNibNamed("GridPhotoGalleryView", owner: self, options: nil)
gridPhotoGalleryView.frame = self.bounds
// gridPhotoGalleryView.frame = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, UIScreen.mainScreen().bounds.size.width + 5, self.bounds.height)
self.addSubview(self.gridPhotoGalleryView)
self.gridPhotoGalleryView.delegate = self
self.gridPhotoGalleryView.dataSource = self
self.gridPhotoGalleryView.registerNib(UINib(nibName: "ThumbnailCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: galleryPhotoCellIdentifier)
}
当我将gridPhotoGalleryView.frame = self.bounds
替换为其下方的注释行时,我的问题已得到纠正。
这里发生了什么?我的猜测是,这与加载此视图的控制器的AutoLayout
约束有某种关系,但这在我的任何其他视图中都不是问题。看起来任意宽度的神奇数字是什么让我的3个缩略图像完全适合屏幕?
不确定是否有必要,但这里有更多代码w.r.t.数据源。
let galleryThumbnailSize = UIScreen.mainScreen().bounds.size.width / 3 - 3
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell: ThumbnailCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(galleryPhotoCellIdentifier, forIndexPath: indexPath) as! ThumbnailCollectionViewCell
let asset: PHAsset = photosAsset!.objectAtIndex(indexPath.item) as! PHAsset
let retinaMultiplier: CGFloat = UIScreen.mainScreen().scale
let retinaSquare: CGSize = CGSizeMake(cell.bounds.size.width * retinaMultiplier, cell.bounds.size.height * retinaMultiplier)
PHImageManager.defaultManager().requestImageForAsset(
asset,
targetSize: retinaSquare,
contentMode: .AspectFill,
options: nil,
resultHandler: {(result, _) in cell.setThumbnailImage(result!, thumbnailSize: self.galleryThumbnailSize)})
return cell
}
答案 0 :(得分:1)
您的猜测是正确的 - 在初始化时,您的最顶层视图具有故事板的大小(如果您使用的数字大小可能是600x600),并且子视图的大小基于约束(或基于硬件)如果您不使用自动布局,则为编码值。由于您在初始化期间设置了gridPhotoGalleryView的大小一次,所以在布局发生时,它永远不会调整大小以适应其父级。
以下是解决此问题的3种方法:
如果您使用自动布局,则可以跳过设置框架并在init中使用约束以确保gridPhotoGalleryView的框架与其超视图的边界匹配。
self.addSubview(self.gridPhotoGalleryView)
self.gridPhotoGalleryView.translatesAutoresizingMaskIntoConstraints = false
let topConstraint = NSLayoutConstraint(item: gridPhotoGalleryView, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1.0, constant: 0.0)
let leftConstraint = NSLayoutConstraint(item: gridPhotoGalleryView, attribute: .Leading, relatedBy: .Equal, toItem: self, attribute: .Leading, multiplier: 1.0, constant: 0.0)
let rightConstraint = NSLayoutConstraint(item: gridPhotoGalleryView, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: 1.0, constant: 0.0)
let bottomConstraint = NSLayoutConstraint(item: gridPhotoGalleryView, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1.0, constant: 0.0)
topConstraint.active = true
leftConstraint.active = true
rightConstraint.active = true
bottomConstraint.active = true
如果你没有使用自动布局(或者即使你是),你可以在你的init中使用弹簧和支柱,以确保你的视图根据其超级视图调整大小。
gridPhotoGalleryView.frame = self.bounds
gridPhotoGalleryView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
如果由于某种原因这些都不适合你,你可以覆盖layoutSubviews(每当视图的帧改变时都会调用它)并调整那里的子视图帧。
override func layoutSubviews() {
super.layoutSubviews()
gridPhotoGalleryView.frame = self.bounds
}
我认为#2可以在您的情况下提供更清晰的代码,但如果需要,您可以使用#1实现更复杂的布局。
至于你的幻数是什么 - 我猜你需要在屏幕宽度上添加5,因为你的集合视图布局中的单元格之间有一些水平填充?或者你的sizeForCellAtIndexPath
返回的格式太大了。