草庐IT

ios - 在 UICollectionViewCell 中处理 ScrollView 大小

coder 2023-07-15 原文

我正在制作一个水平的 UICollectionView,在 UICollectionViewCell 里面我有 ScrollView ,在 ScrollView 里面我有一个 imageView。

我遇到的问题是,当我放大 imageView 时,scrollView 占用了所有单元格大小,因此它不适合图像大小的高度和宽度。因此,通过上下滚动,图像从 scrollview 中消失,我不知道我的代码出了什么问题。

我的 ColectionViewCell 代码:

class CollectionViewCell: UICollectionViewCell {
    @IBOutlet var scrollView: UIScrollView!
    @IBOutlet var ImageV: UIImageView!
}

Collection View 代码:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
  let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CollectionViewCell

  cell.scrollView.contentMode = UIViewContentMode.ScaleAspectFit
  cell.scrollView.delegate = self
  cell.ImageV.image = UIImage(named: array[indexPath.row])
  cell.ImageV.contentMode = UIViewContentMode.ScaleAspectFit

  cell.scrollView.minimumZoomScale = 1
  cell.scrollView.maximumZoomScale = 4;
  cell.scrollView.contentSize = cell.ImageV.frame.size

  return cell
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

  return CGSize(width: self.collectionView.frame.size.width , height: self.collectionView.frame.size.height - 100)

}

func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {

  let indexPath = NSIndexPath(forItem: Int(currentIndex), inSection: 0)

  if let cell1 = self.collectionView.cellForItemAtIndexPath(indexPath) {  
    let cell = cell1 as! CollectionViewCell
    let boundsSize = cell.scrollView.bounds.size
    var contentsFrame = cell.ImageV.frame

    if contentsFrame.size.width < boundsSize.width{
      contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2
    }else{
      contentsFrame.origin.x = 0
    }

    if contentsFrame.size.height < boundsSize.height {
      contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2
    }else{
      contentsFrame.origin.y = 0
    }
    return cell.ImageV    
  }      
   return UIView()     
 }


func scrollViewDidEndDecelerating(scrollView: UIScrollView) {

  currentIndex = self.collectionView.contentOffset.x / self.collectionView.frame.size.width;
  oldcell = currentIndex - 1

  let indexPath = NSIndexPath(forItem: Int(oldcell), inSection: 0)
  if let cell1 = self.collectionView.cellForItemAtIndexPath(indexPath) {
    let cell = cell1 as! CollectionViewCell
    cell.scrollView.zoomScale = 0 
  }
}

图片预览: https://i.imgur.com/Gr2p09A.gifv

我的项目在这里找到: https://drive.google.com/file/d/0B32ROW7V8Fj4RVZfVGliXzJseGM/view?usp=sharing

最佳答案

好吧,首先让我们从持有 UICollectionViewUIViewController 开始:

定义一个变量来保存 Collection View 布局:

var flowLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout()

您必须重写 viewWillLayoutSubviews,这将处理 collectionView 的大小。

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    flowLayout.itemSize = CGSize(width: view.frame.width, height:view.frame.height)

}

此外,您还需要覆盖 viewDidLayoutSubviews 来处理每个新单元格的大小,以将其设置为默认大小:

    override func viewDidLayoutSubviews() {

        if let currentCell = imageCollectionView.cellForItemAtIndexPath(desiredIndexPath) as? GalleryCell {
            currentCell.configureForNewImage()
        }
}

ViewDidLoad 中将 collectionView 设置为水平流布局:

    // Set up flow layout
    flowLayout.scrollDirection = UICollectionViewScrollDirection.Horizontal
    flowLayout.minimumInteritemSpacing = 0
    flowLayout.minimumLineSpacing = 0

    // Set up collection view
    imageCollectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height), collectionViewLayout: flowLayout)

    imageCollectionView.translatesAutoresizingMaskIntoConstraints = false
    imageCollectionView.registerClass(GalleryCell.self, forCellWithReuseIdentifier: "GalleryCell")
    imageCollectionView.dataSource = self
    imageCollectionView.delegate = self
    imageCollectionView.pagingEnabled = true
    view.addSubview(imageCollectionView)

    imageCollectionView.contentSize = CGSize(width: 1000.0, height: 1.0)

在您的 UICollectionView 方法 cellForItemAtIndexPath 中仅加载图像而不设置任何内容:

 cell.image = UIImage(named: array[indexPath.row])

现在让我们转到 GalleryCell 类并在缩放时处理 scrollView:

class GalleryCell: UICollectionViewCell, UIScrollViewDelegate {

    var image:UIImage? {
        didSet {
            configureForNewImage()
        }
    }

     var scrollView: UIScrollView
     let imageView: UIImageView

   override init(frame: CGRect) {

        imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        scrollView = UIScrollView(frame: frame)
        scrollView.translatesAutoresizingMaskIntoConstraints = false

        super.init(frame: frame)
        contentView.addSubview(scrollView)
        contentView.addConstraints(scrollViewConstraints)

        scrollView.addSubview(imageView)

        scrollView.delegate = self
        scrollView.maximumZoomScale = 4
    }

    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    internal func configureForNewImage() {
        imageView.image = image
        imageView.sizeToFit()

        setZoomScale()
        scrollViewDidZoom(scrollView)
    }

    public func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
        return imageView
    }

    public func scrollViewDidZoom(scrollView: UIScrollView) {

        let imageViewSize = imageView.frame.size
        let scrollViewSize = scrollView.bounds.size

        let verticalPadding = imageViewSize.height < scrollViewSize.height ? (scrollViewSize.height - imageViewSize.height) / 2 : 0
        let horizontalPadding = imageViewSize.width < scrollViewSize.width ? (scrollViewSize.width - imageViewSize.width) / 2 : 0

        if verticalPadding >= 0 {
            // Center the image on screen
            scrollView.contentInset = UIEdgeInsets(top: verticalPadding, left: horizontalPadding, bottom: verticalPadding, right: horizontalPadding)
        } else {
            // Limit the image panning to the screen bounds
            scrollView.contentSize = imageViewSize
        }


}

我已经用示例对其进行了测试,它应该可以解决您的 scrollview 问题,@Spencevail 主要解释了它的原因!

关于ios - 在 UICollectionViewCell 中处理 ScrollView 大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34043654/

有关ios - 在 UICollectionViewCell 中处理 ScrollView 大小的更多相关文章

  1. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  2. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  3. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  4. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  5. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  6. HBase Region 简介和建议数量&大小 - 2

    Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile

  7. ruby-on-rails - Ruby 中意外的大小写行为 - 2

    我在一段非常简单的代码(如我所想)中得到了一个错误的值:org=4caseorgwhenorg=4val='H'endputsval=>nil请不要生气,我希望我错过了一些非常明显的东西,但我真的想不通。谢谢。 最佳答案 这是典型的Ruby错误。case有两种被调用的方法,一种是你传递一个东西作为分支的基础,另一种是你不传递的东西。如果您确实在case中指定了一个表达式语句然后评估所有其他条件并与===进行比较.在这种情况下org评估为false和org===false显然不是真的。所有其他情况也是如此,它们要么是真的,要么是假的。

  8. ruby - 改变替换的大小写 - 2

    我有以下内容:text.gsub(/(lower)(upper)/,'\1\2')我可以将\2替换为大写吗?类似于:sed-e's/\(abc\)/\U\1/'这在Ruby中可行吗? 最佳答案 查看gsub文档:str.gsub(模式){|匹配|block}→new_str在block形式中,当前匹配字符串作为参数传入,$1、$2、$`、$&、$'等变量将被适当设置。block返回的值将替换为每次调用的匹配项。"alowerupperb".gsub(/(lower)(upper)/){|s|$1+""+$2.upcase}

  9. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  10. Ruby-vips 图像处理库。有什么好的使用示例吗? - 2

    我对图像处理完全陌生。我对JPEG内部是什么以及它是如何工作一无所知。我想知道,是否可以在某处找到执行以下简单操作的ruby​​代码:打开jpeg文件。遍历每个像素并将其颜色设置为fx绿色。将结果写入另一个文件。我对如何使用ruby​​-vips库实现这一点特别感兴趣https://github.com/ender672/ruby-vips我的目标-学习如何使用ruby​​-vips执行基本的图像处理操作(Gamma校正、亮度、色调……)任何指向比“helloworld”更复杂的工作示例的链接——比如ruby​​-vips的github页面上的链接,我们将不胜感激!如果有ruby​​-

随机推荐