StackView 内的 CollectionView

Posted

技术标签:

【中文标题】StackView 内的 CollectionView【英文标题】:CollectionView inside of StackView 【发布时间】:2018-05-04 07:30:14 【问题描述】:

我在UIStackView 中有一个UICollectionViewUICollectionViewCell 有一个 UIImageView 固定在单元格上。

我想在这里做什么:

在一行中显示用户在UICollectionView 上选择的图片。 UICollectionView 可以水平滚动(Thinking 在 Twitter 的发帖屏幕上显示图片。) UICollectionView 仅在用户添加照片时显示。 使用UIImagePickerController 拍照。

我遇到的问题:

UICollectionView 显示任何内容,即使在用户选择要添加的照片之后。 我什至不知道是代码问题还是storyBoard

到目前为止我尝试了什么。 (所有尝试都失败了。):​​

UICollectionViewUIStackView 分开。 设置UICollectionViewUICollectionViewCellUIImageView的固定宽度和高度。 设置UIImageView的特定图片。

这是我的代码和storyBoard

ImageCell.swift

import UIKit

class ImageCell: UICollectionViewCell 
  @IBOutlet weak var cellImage: UIImageView!

  // Avoiding showing cached image
  override func prepareForReuse() 
    cellImage.image = nil
  

ViewController.swift

import UIKit

class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate, UITextViewDelegate 

@IBOutlet weak var albumTitle: UITextField!
@IBOutlet weak var pageTitle: UITextField!
@IBOutlet weak var date: UITextField!
@IBOutlet weak var location: UITextField!
@IBOutlet weak var bodyText: UITextView!
@IBOutlet weak var imageCollection: UICollectionView!
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var frameStack: UIStackView!

var imageStore: ImageStore!
var images = NSMutableArray()
var selectedImage: UIImage?

override func viewDidLoad() 
  super.viewDidLoad()

  // UITextView
  self.bodyText.delegate = self

  // UITextFields
  self.albumTitle.delegate = self
  self.pageTitle.delegate = self
  self.date.delegate = self
  self.location.delegate = self

  // Create close button above the textView keyboard
  // Tool bar
  let closeBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: 320, height: 40))
  closeBar.barStyle = UIBarStyle.default  // Style
  closeBar.sizeToFit()  // Size change depends on screen size
  // Spacer
  let spacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: self, action: nil)
  // Close Botton
  let closeButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: self, action: #selector(CreateVC.closeButtonTapped))

  closeBar.items = [spacer, closeButton]
  bodyText.inputAccessoryView = closeBar


  override func viewDidLayoutSubviews() 
    scrollView.contentSize = frameStack.bounds.size
    scrollView.flashScrollIndicators()
  

  // Enable textView to close
  @objc func closeButtonTapped() 
    self.view.endEditing(true)
  

  // Enable return key of UITextFields
  func textFieldShouldReturn(_ textField: UITextField) -> Bool 
    albumTitle.resignFirstResponder()
    pageTitle.resignFirstResponder()
    date.resignFirstResponder()
    location.resignFirstResponder()
    return true
  

  // Open up device's camera
  @IBAction func takePicture(_ sender: UIButton) 
    let imagePicker = UIImagePickerController()
    if UIImagePickerController.isSourceTypeAvailable(.camera) 
      imagePicker.sourceType = .camera
     else 
      imagePicker.sourceType = .photoLibrary
    
    imagePicker.delegate = self

    // Place image picker on the screen
    present(imagePicker, animated: true, completion: nil)
  

  // Open up device's camera
  @IBAction func pickPicture(_ sender: UIButton) 
    let imagePicker = UIImagePickerController()
    imagePicker.sourceType = .photoLibrary
    imagePicker.delegate = self
    // Place image picker on the screen
    present(imagePicker, animated: true, completion: nil)
  

  func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) 
    // Get picked image from info directory
    let image = info[UIImagePickerControllerOriginalImage] as! UIImage

    // Put that image on the screen in the image view
    selectedImage = image
    images.add(selectedImage!)

    imageCollection.reloadData()

    // Take image picker off the screen
    dismiss(animated: true, completion: nil)
  



extension CreateVC: UICollectionViewDelegate, UICollectionViewDataSource 

  func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 

    return images.count
  

  // Assign cells contents
  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! ImageCell

    cell.cellImage.isHidden = true
    if let image = cell.cellImage.image 
      cell.cellImage.isHidden = false
      cell.cellImage.image = images[indexPath.row] as? UIImage
    

    return cell
  


The Picture of my storyboard. The cell seems weird.

我是 ios 开发的新手,完全被困在这里。

进一步发现:

我发现单元格大小看起来很奇怪。 故事板是这样说的。

单元格 预期:宽度 0 实际:宽度 120

【问题讨论】:

[更新]确保你已经为 imageView 设置了正确的约束 我同意 Matthew 的观点,您可能没有正确配置单元格约束。是否正确设置了子视图? 对于单元格,我只使用 UICollectionView 的“单元格大小”属性,因为它似乎无法直接为单元格设置特定的约束。我将 UIImageView 固定到单元格上。 【参考方案1】:

我发现了问题所在。这是细胞的限制。以下是我解决此问题的方法。

override func viewDidLayoutSubviews() 
  let layout = UICollectionViewFlowLayout()
  layout.itemSize = CGSize(width: 120, height: 120)
  layout.minimumInteritemSpacing = 0
  layout.minimumLineSpacing = 10
  layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
  layout.scrollDirection = .horizontal
  imageCollection.collectionViewLayout = layout

    为 Storyboard 上的 CollectionView 设置特定高度 像上面一样在 viewDidLayoutSubviews() 方法中设置单元格的约束

【讨论】:

以上是关于StackView 内的 CollectionView的主要内容,如果未能解决你的问题,请参考以下文章

StackView 内的 CollectionView

如何从 StackView 内的 UITextfield 获取文本

在水平 StackView 内的 TextView 中删除 Padding top

collectionview 或 uitableview 内的 Stackview

如何在 StackView 内的两个视图之间进行动画处理?

在 StackView 内动态添加 ViewControllers - UIScrollView 内的 UIStackView