【问题标题】:Can I retrieve an item from a tuple in the same way as indexing an item from an array in a for loop?我可以像在 for 循环中从数组中索引项目一样从元组中检索项目吗?
【发布时间】:2017-08-04 18:37:34
【问题描述】:

以下是我的自定义 UICollectionViewCell 类代码的一部分,我在for 循环中收到错误消息,指出函数定义中的元组类型没有下标成员。有谁知道是否有办法像检索数组一样检索元组的成员?谢谢!

    func initializeStuff(objectType: AnyObject, xOriginCgFloat: (CGFloat, CGFloat, CGFloat?), yOriginCgFloat: (CGFloat, CGFloat, CGFloat?), width: (CGFloat, CGFloat, CGFloat?), height: (CGFloat, CGFloat, CGFloat?))  {

        if objectType === UIButton.self {
            if xOriginCgFloat.2 != nil || yOriginCgFloat.2 != nil || width.2 != nil || height.2 != nil {
                for index in 0..<3 {
                    var button = UIButton(frame: CGRect.init(origin: CGPoint.init(x: xOriginCgFloat[index], y: yOriginCgFloat[index]), size: CGSize.init(width: width[index], height: height[index])))

                    buttonArray.append(button)
                }
            } else {
                fatalError("Each tuple for a button object must have exactly three values.")
            }

【问题讨论】:

标签: arrays swift xcode for-loop tuples


【解决方案1】:

查看this link 以获得此答案的灵感。首先将此函数添加到代码中可访问的位置:

func iterate<Tuple>(_ tuple:Tuple, body:(_ label:String?,_ value:Any)->Void) {
    for child in Mirror(reflecting: tuple).children {
        body(child.label, child.value)
    }
}

然后使用您的代码的这个更新版本:

if objectType === UIButton.self {
        if xOriginCgFloat.2 != nil || yOriginCgFloat.2 != nil || width.2 != nil || height.2 != nil {
            var buttonOneData:[CGFloat] = [CGFloat]()
            var buttonTwoData:[CGFloat] = [CGFloat]()
            var buttonThreeData:[CGFloat] = [CGFloat]()
            var buttonsData:[[CGFloat]] = [buttonOneData,buttonTwoData,buttonThreeData]
            var tuples = [xOriginCgFloat,yOriginCgFloat,width,height]

            for tuple in tuples {
                iterate(tuple) {
                    var indexStr = $0! //index = .0,.1,.2, etc
                    indexStr.remove(at:indexStr.startIndex) //remove the . from .0,.1,.2,etc.
                    let index = Int(indexStr)
                    buttonsData[index].append(CGFloat($1 as! Int)) //$1 = the value of tuple.0, tuple.1, tuple.2, etc.
                }
            } 

            for (index,buttonData) in buttonsData.enumerated() {
                var button = UIButton(frame: CGRect.init(origin: CGPoint.init(x: buttonData[index], y: buttonData[index]), size: CGSize.init(width: buttonData[index], height: buttonData[index])))
                buttonArray.append(button)
            }

        } else {
            fatalError("Each tuple for a button object must have exactly three values.")
        }
}

它非常复杂,老实说我不是它的忠实粉丝,但如果你需要使用元组,那么这(可能)对你有用。我基本上使用了这个答案顶部列表中的迭代函数来遍历你的元组并将它们添加到数组中,这些数组将元组中的数据分隔成一个按钮数据数组,然后我制作了一个数组,这样你就可以遍历并制作实际的按钮。

【讨论】:

  • 谢谢!随着我重复同一件事的次数,它确实看起来确实令人费解。也就是说,我从另一条评论中意识到,我的错误消息基本上只是为了让我调试我的代码,因为 func 在自定义类中。另外,你知道为什么func 在我尝试在同一个类中调用它时没有给我参数吗?它给了self.initializeStuff(self: customCollectionViewCell)
  • 您是从单独的静态函数中调用initializeStuff 吗?我需要查看您的更多代码才能给您更具体的答案。
  • 不,我是从函数外部调用它,但在同一个类中
  • 如何发送消息?有点长
  • 天哪,请不要这样做。
【解决方案2】:

为什么不使用这样的函数:

func makeButtons(frames: [CGRect]) {
    for frame in frames {
        let button = UIButton(frame: frame)
        buttonArray.append(button)
    }
}

【讨论】:

  • 我有 UIButton,但我也有 UIView 和 UILabel,所以对于其他两个,我是否只需添加两个完全相同的功能?
  • 实际上,您根本不清楚为什么您需要一个函数。重点是应该使用CGRect的数组,保证一致,而不是CGFloat的四个数组/元组,长度可能不一致。
  • 谢谢!我制作函数是因为我不想手动初始化 3 个 UIButton、2 个 UIView 和 2 个 UILabel。我认为必须有一条捷径。
猜你喜欢
  • 2011-12-27
  • 2014-01-30
  • 1970-01-01
  • 2013-01-15
  • 2018-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多