2016-09-14 59 views
0

最初,我有一个密集的控制器,其中包含一个delegatedatasource以及其他与呈现我的画廊的CollectionView相关的其他内容。为了清理代码,我将CollectionView转换为基于.xib的自定义创建视图,这里的关键点在于很多数字量保持不变。自定义基于.xib的CollectionView超出预期界限

以前,一切正常加载,每行3个缩略图。但是,现在,每行仍有3个缩略图,这些行溢出屏幕的右侧,实际上是在屏幕之外。

我的看法是加载,这样的:当我与它下面的注释行替换gridPhotoGalleryView.frame = self.bounds

@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) 
} 

我的问题得到解决。

这里发生了什么?我的猜测是,这与加载该视图的控制器的约束有关,但这在我的任何其他视图中都不是问题。这个看似随意的宽度是什么,这个幻数让我的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 
} 

回答

1

你的猜测是正确的 - 在初始化,您最上面的观点有大小从故事板(如果您使用的大小类,数量大概是600×600),和子视图是基于约束在其中大小(或如果您未使用自动布局,则基于硬编码值)。由于您在初始化期间将gridPhotoGalleryView的大小设置为一次,所以在布局发生时,它的大小永远不会调整到适合父级的大小。

这里有3种方式就可以解决这个问题:

  1. 如果您正在使用自动布局可以跳过设置框架和使用约束的初始化,以确保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 
    
  2. 如果你不使用自动布局(或者即使你是),你可以用弹簧和支柱在你的初始化,以确保您的视图根据它的父调整大小。

    gridPhotoGalleryView.frame = self.bounds 
    gridPhotoGalleryView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight] 
    
  3. 如果由于某种原因既不是你的工作,你可以重写layoutSubviews(其被称为每当视图的框架的改变),调整子视图帧那里。

    override func layoutSubviews() { 
        super.layoutSubviews() 
        gridPhotoGalleryView.frame = self.bounds 
    } 
    

我认为,#2,就使得你的情况更干净的代码,但如果需要的话,你可以实现与1号更复杂的布局。

至于怎么了你的幻数 - 我猜你需要添加5到屏幕宽度,因为你的集合视图布局中的单元格之间有一些水平填充?或者你的sizeForCellAtIndexPath正在返回一个太大的smidge大小。

+0

非常彻底的回应,这有助于理解iOS如何呈现内容 – mike