无法更改标题中的按钮标题

Posted

技术标签:

【中文标题】无法更改标题中的按钮标题【英文标题】:Unable to change button title in header 【发布时间】:2021-06-07 08:25:42 【问题描述】:

我有一个带有标题的 UICollectionView VC。此标题是一个自定义单元格,在该单元格内有一个打开 UITableView(下拉菜单)的按钮。

每当我点击该按钮并选择一个值时,我都需要更改该按钮的标题,但我一定做错了,因为它没有改变。

您可以在 UITableView 中看到下面的 didSelectRowAt 我做了以下操作:

let title = self.dropdownDataSource[indexPath.row]
selectedButton.setTitle(title, for: .normal)

页眉单元

protocol HeaderCellDelegate: class 
    func setDropdown()
    func tapOnSelection()


class HeaderCell: UIGestureRecognizerDelegate 

    // delegate
    weak var hDelegate: HeaderCellDelegate?

    @objc
    lazy var selectionBtn: UIButton = 
        let button = UIButton(type: .system)
        button.setTitle("One", for: .normal)
        button.addTarget(self, action: #selector(changeSelection), for: .touchUpInside)
        return button
    ()
    
    @objc
    lazy var oneOrTwo: UIButton = 
        let button = UIButton()
        button.setImage(UIImage(named: "oneOff")?.withRenderingMode(.alwaysTemplate), for: .normal)
        button.addTarget(self, action: #selector(toggleOneOrTwo), for: .touchUpInside)
        return button
    ()
    
    override init(frame: CGRect) 
        super.init(frame: frame)
    
        // I setup view helper
        // Just a button and icon on the right
        // button opens DropDown list
    
    
    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    
    
    // MARK: - Delegate Functions
    
    @objc
    func toggleOneOrTwo(_ sender: Any) 
        self.hDelegate?.setDropdown()
    
    
    @objc
    func changeSelection(sender: UIButton) 
        self.hDelegate?.tapOnSelection()
    

视图控制器

class CellClass: UITableViewCell 


class ViewController: UICollectionViewController, UIGestureRecognizerDelegate 

    let transparentView = UIView()
    let tableView = UITableView()
    var dropdownDataSource: [String] = ["One", "Two"]
    var selectedButton = UIButton()
    fileprivate let headerCellId = "headerCellId"
    lazy var headerCell = HeaderCell()

    override func viewDidLoad() 
        super.viewDidLoad()
        
        // Register Cell Class
        self.collectionView.register(HeaderCell.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: headerCellId)

        // Dropdown table
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(CellClass.self, forCellReuseIdentifier: "Cell")
    

    override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView 
        switch kind 
        case UICollectionView.elementKindSectionHeader:
            let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerCellId, for: indexPath) as! HeaderCell
            header.backgroundColor = .groupTableViewBackground
            header.hDelegate = self
            
            return header
        default:
            fatalError("This should never happen!!")
        
    

    // This is for the background of dropdown view
    func addTransparentView(frames: CGRect) 
         let window = UIApplication.shared.keyWindow
         transparentView.frame = window?.frame ?? self.view.frame
         self.view.addSubview(transparentView)
    
         tableView.frame = CGRect(x: frames.origin.x, y: frames.origin.y + frames.height, width: frames.width, height: 0)
         self.view.addSubview(tableView)
         tableView.layer.cornerRadius = 5
         
         transparentView.backgroundColor = UIColor.black.withAlphaComponent(0.9)
         tableView.reloadData()
         let tapgesture = UITapGestureRecognizer(target: self, action: #selector(removeTransparentView))
         transparentView.addGestureRecognizer(tapgesture)
         transparentView.alpha = 0
         UIView.animate(withDuration: 0.4, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 1.0, options: .curveEaseInOut, animations: 
             self.transparentView.alpha = 0.5
             self.tableView.frame = CGRect(x: frames.origin.x + 200, y: frames.origin.y + frames.height + 5, width: frames.width + 130, height: CGFloat(self.dropdownDataSource.count * 50))
         , completion: nil)
     
    
    @objc
    func removeTransparentView() 
        let frames = selectedButton.frame
        UIView.animate(withDuration: 0.4, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 1.0, options: .curveEaseInOut, animations: 
             self.transparentView.alpha = 0
             self.tableView.frame = CGRect(x: frames.origin.x, y: frames.origin.y + frames.height, width: frames.width, height: 0)
         , completion: nil)
     


extension ViewController: HeaderCellDelegate 
    func setDropdown() 
        // do something
    
    
    func tapOnSelection() 
        selectedButton = headerCell.selectionBtn
        addTransparentView(frames: headerCell.selectionBtn.frame)
    


extension ViewController: UITableViewDelegate, UITableViewDataSource 
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return dropdownDataSource.count
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = dropdownDataSource[indexPath.row]
        cell.textLabel?.font = UIFont.openSansFontOfSize(14)
        return cell
    
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
        return 50
    
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        tableView.deselectRow(at: indexPath, animated: true)
        let title = self.dropdownDataSource[indexPath.row]
        selectedButton.setTitle(title, for: .normal)
        removeTransparentView()
    

【问题讨论】:

【参考方案1】:

先取headerView Globly

var headerView: DemoHeaderView?

现在viewForSupplementaryElementOfKind函数

func collectionView(_ collectionView: UICollectionView,
                             viewForSupplementaryElementOfKind kind: String,
                             at indexPath: IndexPath) -> UICollectionReusableView 
  // 1
  switch kind 
  // 2
  case UICollectionView.elementKindSectionHeader:
    // 3
    guard
        let headerView = collectionView.dequeueReusableSupplementaryView(
        ofKind: kind,
        withReuseIdentifier: "DemoHeaderView",
        for: indexPath) as? DemoHeaderView
      else 
        fatalError("Invalid view type")
    

    self.headerView = headerView
    self.headerView?.label.text = "Demo"
    return self.headerView ?? UICollectionReusableView()
  default:
    // 4
    assert(false, "Invalid element type")
  

还有UICollectionReusableView(我用label做demo)

   class DemoHeaderView: UICollectionReusableView 
      @IBOutlet weak var label: UILabel!
    

现在在 didSelectRowAt

 guard let header = self.headerView else  return 
        header.label.text = "Button Tapped"

希望对你有帮助。谢谢。

【讨论】:

您无法在 hader 上重新加载数据。不知道还有什么其他方法可以重新加载它。 @learningswift 我已经更新了整个代码,所以请看一下。它对我来说很好,如果你需要任何其他帮助,请告诉我。

以上是关于无法更改标题中的按钮标题的主要内容,如果未能解决你的问题,请参考以下文章

无法更改 EKEvent 代码中的 UIButton

点击时无法更改 UItableViewCell 中按钮的图像

如何更改按钮悬停属性中的文本颜色

无法更改按钮 iOS 的标题

无法更改后退栏按钮文本

从输入类型日期中删除“X”(清除按钮)并更改 Firefox 中的字体系列