【问题标题】:How to tell if button in collection view header is selected when populating collection view?填充集合视图时如何判断是否选择了集合视图标题中的按钮?
【发布时间】:2016-08-22 07:19:19
【问题描述】:

在填充我的集合视图时,如何判断我是否选择了集合视图标题中的按钮?我在标题中有 2 个选项卡,它们确定我使用哪些数据填充集合视图,因此我希望能够在用户选择不同的选项卡时切换数据并重新加载集合视图。

头类中的一些代码应要求...虽然它只是一个按钮,但我看不出重点。我想查看在填充单元格和单元格计数等时是否选择了此按钮。

class UserSearchHeader: UICollectionReusableView {

@IBOutlet weak var friendsButton: UIButton!
@IBOutlet weak var peopleButton: UIButton!
@IBOutlet weak var customSlider: UIView!

override func awakeFromNib() {
    super.awakeFromNib()
    self.friendsButton.selected = true
    customSlider.layer.cornerRadius = customSlider.frame.height / 2

}

@IBAction func friendsButtonTapped(sender: AnyObject) {
    if self.friendsButton.selected == false {
        self.friendsButton.selected = true
        self.peopleButton.selected = false
        UIView.animateWithDuration(0.3, animations: { () -> Void in
            self.customSlider.frame.origin.x = 0
        })
    }
}

【问题讨论】:

    标签: swift button header collectionview


    【解决方案1】:

    UICollectionviewHeader + UI 按钮
    UIcollectionviewHeader 正在使用 dequeueReusableSupplementaryView 并且由于某种原因它创建了每个 Headerview 的 UIView Infront,这将阻止所有正在发生的手势。解决方案是将视图置于前面,如下所示:

    override func awakeFromNib() {
       super.awakeFromNib()
       self.bringSubview(toFront: friendsButton) // this depends on you .xib
    }
    

    这将解决您的手势问题。

    有多种方法可以在 CollectionViewHeader 中创建 UIButton 操作。

    • AddTarget(@derdida 回答)
    • CollectionViewHeader 类中的拖放操作。

    添加目标:-(参考derdida回答)
    viewForSupplementaryElementOfKind// ps: 你需要注册你的 CollectionView Class & Nib

    1. 像这样将 Target 添加到 UIButton。

    header.friendsButton.tag = 0
    header.friendsButton.addTarget(self, action: #selector(self.HeaderClick(_:)), for: .touchUpInside)

    1. 像这样创建函数。

    @objc func HeaderClick1(_ sender : UIButton){ print("sender.tag \(sender.tag)") }//sender.tag 0

    CollectionViewHeader 类中的拖放操作。
    对于这个例子,我将使用@Wayne Filkins 问题。

    1. Ctrl + 拖动 UIButton 到标题类
    2. 选择连接类型以操作创建函数,如下所示

    @IBAction func friendsButtonTapped(_ sender: Any) { print("something from friendsButtonTapped") }

    就是这样。

    但这里的主要关键是让视图位于前面。使用调试视图层次结构了解更多信息。

    请有人修复我的代码视图!

    更新解决方案
    使用 UIButtonSetOnClickListener.Swift 和代码:

    extension UIControl {
         func setOnClickListener(for controlEvents: UIControl.Event = .primaryActionTriggered, action: @escaping () -> ()) {
            removeTarget(nil, action: nil, for: .allEvents)
            let sleeve = ClosureSleeve(attachTo: self, closure: action)
            addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: 
     controlEvents)
         }
    }
    class ClosureSleeve {
         let closure: () -> ()
    
     init(attachTo: AnyObject, closure: @escaping () -> ()) {
        self.closure = closure
        objc_setAssociatedObject(attachTo, "[\(arc4random())]", self, .OBJC_ASSOCIATION_RETAIN)
     }
    
     @objc func invoke() {
         closure()
     }
    }
    

    这里的使用方法是:
    添加目标:-(参考derdida回答)
    viewForSupplementaryElementOfKind// ps: 你需要注册你的 CollectionView Class & Nib

        header.friendsButton.setOnClickListener {
            //put your code here
        }
    

    【讨论】:

      【解决方案2】:

      有 2 个委托方法对于决定显示哪些项目很重要。例如:

      您有 2 个不同的项目,它们被填充在:

      let items1 = [Item]()
      let items2 = [Item]()
      

      然后你有一个变量,它保存应该显示哪些项目:

      let items1Shown:Bool = true
      

      现在用类似的方式实现委托方法:

      override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
         if(items1Shown == true) {
            return items1.count
         } else {
            return items2.count
         }
      }
      

      还有

      override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
      
         var item:Item!
      
         if(items1Shown == true) {
            item =  items1[indexPath.row]
         } else {
            item =  items1[indexPath.row]
         }
      
         // format your cell 
      
      }
      

      并实现任意按钮功能

      func ChangeItems() {
         if(items1Shown == true) {
            items1Shown = false
         } else {
            items1Shown = true
         }
      
         // reload your collectionView
      
         self.collectionView.reloadData()
      
      }
      

      编辑:

      为什么不给你的按钮一个目标? (在你将 headerView 出列的地方添加这个!)

      headerView.friendsButton.addTarget(self, action: #selector(YourViewControllerWithFunction.cellButtonClick(_:)), forControlEvents: .TouchUpInside)
      

      // 例如:

      func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
          let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: headerId, forIndexPath: indexPath)
      
          headerView.friendsButton.addTarget(self, action: #selector(YourViewControllerWithFunction.cellButtonClick(_:)), forControlEvents: .TouchUpInside)
      
          return headerView
      }
      

      // 类 YourViewControllerWithFunction

      func cellButtonClick(button: UIButton) {
          // you can do anything with that button now 
      }
      

      【讨论】:

      • 是的,我知道那部分,但我有一个集合视图“标题”,它有自己的类。该标题中有一些我无法从“cellforitematindexpath”中访问的按钮。我的意思是我假设我无法访问它们,因为它们在标题类中。它不允许我将按钮连接到 UICollectionView 类。
      • 请展示一些你的头类和实现的代码。
      • 我添加了标题类。真的很直接。带有按钮的标题。需要检查是否选择了该按钮,以决定使用哪些数据填充集合视图。
      • @WayneFilkins 好的,现在我明白了。真正的问题是它是一个 CollectionHeaderView。我试图重现这个问题。此解决方案仅适用于 tableview 单元格、tableview 标题、集合项。但不在 CollectionHeader 上。当我尝试在分解视图中查看时,collectionHeaderview 前面会有一个未知的 UIview。我还没有弄清楚如何做到这一点
      • @WayneFilkins 找到了答案。你需要把视图放在前面我已经发布了一个答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 2020-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多