有没有办法在 Swift 中一次将委托分配给同一类的多个对象?

Posted

技术标签:

【中文标题】有没有办法在 Swift 中一次将委托分配给同一类的多个对象?【英文标题】:Is there a way to assign delegate to more than one object of the same class just one time in Swift? 【发布时间】:2020-10-03 04:36:52 【问题描述】:

例如,我在视图控制器中放置了 20 个按钮,它们都继承自一个继承自 UIButton 的 CommonButton,并且 CommonButton 符合一个名为 ButtonDelegate 的协议,现在我想将委托分配给视图控制器中的按钮。与其制作 20 个按钮的 IBOutlet 并一个一个地为每个按钮分配代理,有没有一种方法可以简化分配?

【问题讨论】:

您可能只是在寻找 IBOutletCollection? 【参考方案1】:

有几种方法:

    就我个人而言,我会将delegate 属性设为@IBOutlet,然后我可以在 IB 的“连接检查器”中指定委托权限,根本不必在代码中做任何事情,例如

    @objc protocol CustomButtonDelegate: class  ... 
    
    class CustomButton: UIButton 
    
        @IBOutlet weak var delegate: CustomButtonDelegate?
    
        ...
    
    

    或者,如果您真的想以编程方式执行此操作,当您为 IB 中的按钮创建插座时,您还可以创建一个“插座集合”:

    @IBOutlet var buttons: [CustomButton]!
    

    然后你可以control-从IB中的控件拖动到“Assistant”视图中的这个插座集合。

    一旦你这样做了,你就可以遍历出口集合:

    for button in buttons 
        button.delegate = self
    
    

    显然,您可以自己手动填充按钮数组,但同样,我会将按钮连接到 IB 中的这个“插座集合”数组。

【讨论】:

【参考方案2】:

没有明确的方法。您可以将 20 个按钮存储到一个数组中,以便下次高效使用。

buttons = [btn0, ......., btn19]

for btn in buttons 
    btn.delegate = self

另一种方式,您可以制作静态委托。当按钮事件触发时,检查您的静态委托类型,并控制一切。

import UIKit

class ViewController1: UIViewController 
    var buttons: [CustomButton] = [CustomButton]()
    
    override func viewDidLoad() 
        super.viewDidLoad()
        loadUI()
    
    
    func loadUI()  
        buttons = (0..<5).map( (index) -> CustomButton in
            let button = CustomButton()
            button.tag = index
            button.setTitle("\(index)", for: .normal)
            button.setTitleColor(.black, for: .normal)
            button.backgroundColor = UIColor.green
            return button
        )
        
        for (index, button) in buttons.enumerated()  
            view.addSubview(button)
            button.translatesAutoresizingMaskIntoConstraints = false
            button.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
            if index == 0 
                button.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
            else 
                button.leftAnchor.constraint(equalTo: (buttons[index-1]).rightAnchor).isActive = true
            
            if index == buttons.count - 1 
                button.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
            
            button.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
            button.widthAnchor.constraint(equalTo: (buttons[0]).widthAnchor).isActive = true
            button.addTarget(self, action: #selector(self.buttonEvent(_:)), for: .touchUpInside)
        
        
        CustomButton.delegate = self
    
    
    @objc func buttonEvent(_ button: UIButton) 
        if let viewController = CustomButton.delegate as? ViewController1 
            print("tag: \(button.tag) viewController: \(viewController)")
        
    


extension ViewController1: CustomButtonProtocol 


protocol CustomButtonProtocol 


class CustomButton: UIButton 
    public static var delegate: CustomButtonProtocol?

【讨论】:

【参考方案3】:

您可以为按钮使用带有不同标签的IBOutletCollection

【讨论】:

以上是关于有没有办法在 Swift 中一次将委托分配给同一类的多个对象?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 C# winforms 中一次将文本写入多个文本框?

如何在 Django 中一次将多个对象添加到 ManyToMany 关系?

如何在不使用游标的情况下一次将查询结果分配给多个变量?

在 python openCV 中一次将许多图像读入内存

Swift3.2 - 如何将 2 个类分配给同一个视图控制器?

Swift UICollectionView 文本字段