无法为类似 Pinterest 的 iOS 应用加载 [UIButton] 数组的所有项目

Posted

技术标签:

【中文标题】无法为类似 Pinterest 的 iOS 应用加载 [UIButton] 数组的所有项目【英文标题】:Failing to load all items of an [UIButton] array for Pinterest-like iOS App 【发布时间】:2018-04-13 21:39:27 【问题描述】:

我的目标是创建一个类似于 Pinterest 的 ios 应用。我使用一个集合视图,然后以编程方式添加一个堆栈视图。我在一个函数中创建了按钮及其各自的图像,然后我将所有 UIButtons 返回到 [UIButtons] 数组中。我将该函数的值存储在一个名为buttonsArray 的变量中,然后在各自的Collection View 数据源和委托方法中使用它。我还使用 RayWenderlich 创建的 PinterestLayout。除了加载所有按钮,它只加载前两个之外,一切都按预期工作。我添加项目的功能如下:

func createArrayButtons() -> [UIButton]

    var items:[UIButton] = []

    let item1 = UIButton(frame: CGRect(x:0, y:0, width:346,height:275))
    item1.setImage(UIImage(named: "1"), for: .normal)
    item1.addTarget(self, action: #selector(editButtonTapped), for: UIControlEvents.touchUpInside)
    item1.tag = 1
    items.append(item1)

    let item2 = UIButton(frame: CGRect(x:0, y:0, width:346,height:275))
    item2.setImage(UIImage(named: "2"), for: .normal)
    item2.addTarget(self, action: #selector(editButtonTapped), for: UIControlEvents.touchUpInside)
    item2.tag = 2
    items.append(item2)

    let item3 = UIButton(frame: CGRect(x:0, y:0, width:346,height:275))
    item3.setImage(UIImage(named: "3"), for: .normal)
    item3.addTarget(self, action: #selector(editButtonTapped), for: UIControlEvents.touchUpInside)
    item3.tag = 3
    items.append(item3)

    let item4 = UIButton(frame: CGRect(x:0, y:0, width:346,height:275))
    item4.setImage(UIImage(named: "4"), for: .normal)
    item4.addTarget(self, action: #selector(editButtonTapped), for: UIControlEvents.touchUpInside)
    item4.tag = 4
    items.append(item4)

    let item5 = UIButton(frame: CGRect(x:0, y:0, width:346,height:275))
    item5.setImage(UIImage(named: "5"), for: .normal)
    item5.addTarget(self, action: #selector(editButtonTapped), for: UIControlEvents.touchUpInside)
    item5.tag = 5
    items.append(item5)

    let item6 = UIButton(frame: CGRect(x:0, y:0, width:346,height:275))
    item6.setImage(UIImage(named: "6"), for: .normal)
    item6.addTarget(self, action: #selector(editButtonTapped), for: UIControlEvents.touchUpInside)
    item6.tag = 6
    items.append(item6)

    let item7 = UIButton(frame: CGRect(x:0, y:0, width:346,height:275))
    item7.setImage(UIImage(named: "7"), for: .normal)
    item7.addTarget(self, action: #selector(editButtonTapped), for: UIControlEvents.touchUpInside)
    item7.tag = 7
    items.append(item7)

    return items


我从资产文件夹中给每个人一个相应的标签和一个相应的图像,然后将它作为一个数组返回。

我按如下方式计算collectionViewDataSource

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

    let buttonsArray = createArrayButtons()
    return buttonsArray.count


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)

    let buttonsArray = createArrayButtons()

    let stackView = UIStackView(arrangedSubviews: buttonsArray)
    stackView.axis = .vertical
    stackView.distribution = .equalSpacing
    stackView.alignment = .fill
    stackView.spacing = 5
    stackView.translatesAutoresizingMaskIntoConstraints = false

    cell.addSubview(stackView)





    return cell

我计算每个项目的高度如下:

extension ViewController: PinterestLayoutDelegate 
func collectionView(_ collectionView: UICollectionView, heightForPhotoAtIndexPath indexPath: IndexPath) -> CGFloat 
    let buttonArray = createArrayButtons()

    let button = buttonArray[indexPath.item]

    let height = button.imageView?.image?.size.height

    return height!

如您所见,该应用仅显示存储在每个 dataSource 方法中的 createButtonsArray() 变量的前两张图像

我存储为 createArrayButtons 的返回值的每个图像都是不同的,但是它只加载了两个。我该如何解决这个问题?

如果有任何帮助,我的项目可以在以下链接中找到:

https://github.com/francisc112/PinterestTutorial

【问题讨论】:

【参考方案1】:

在为每个单元格加载整个按钮数组时更新cellForItemAt indexPath 处的代码。

    let stackView = UIStackView(arrangedSubviews: [buttonsArray[indexPath.row]])

【讨论】:

@FranciscoRuiz,欢迎您。【参考方案2】:

请按照以下步骤获得所需的结果,

1 - 在情节提要中,将UIStackView 拖动到collectionCell 中,并从所有方面将约束设置为零。设置分布和间距如图

2 -更新ButtonCollectionViewCell如下

class ButtonCollectionViewCell: UICollectionViewCell 

    @IBOutlet weak var button:UIButton!
    @IBOutlet weak var stackView: UIStackView!


3 - 再次打开storyboard并与stackView建立连接,如图

4 -viewDidLoad改成这个

override func viewDidLoad() 
    super.viewDidLoad()
    collectionView.delegate = self

    let collectionViewLayout = UICollectionViewFlowLayout()
    self.collectionView.collectionViewLayout = collectionViewLayout

    collectionView.contentInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
    // Do any additional setup after loading the view, typically from a nib.

5 -符合ViewController这个

extension ViewController: UICollectionViewDelegateFlowLayout 

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
        return CGSize(width: UIScreen.main.bounds.width/2 - 20, height: UIScreen.main.bounds.height)
    

6 - 用这个更新cellForItemAt

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ButtonCollectionViewCell

        for (_, view) in cell.stackView.arrangedSubviews.enumerated() 
            cell.stackView.removeArrangedSubview(view)
        
        let buttonsArray = createArrayButtons()
        buttonsArray.forEach  button in
            cell.stackView.addArrangedSubview(button)
        
        cell.stackView.layoutIfNeeded()
        cell.contentView.layoutIfNeeded()
        return cell
    

现在您应该可以看到正确的结果了。

【讨论】:

以上是关于无法为类似 Pinterest 的 iOS 应用加载 [UIButton] 数组的所有项目的主要内容,如果未能解决你的问题,请参考以下文章

iOS 上的 Pinterest Gridview 实现

如何将 Pinterest 集成到 ios 应用程序中

如何使用 iOS Pin It SDK 在 Pinterest 中实现 Followboard 按钮功能?

iOS Pinterest 插入 nil 对象

在类似于 facebook 或 pinterest 的 tableview 单元格中显示图像

我们如何将 Pinterest 的 iOS 应用大小减少 30% 以上