我有使用Matlab的丰富经验,但直到最近我才开始使用Swift 4进行编程。我当前的项目涉及构建调查表。我已使用Xcode中的“拖放”功能为情节提要中的按钮生成@IBAction函数,然后可以导致按下的按钮更改其外观。此功能包含在下面的代码片段的ButtonResponse类中:

    struct ResponseProfile {

       var responseArray: Array<String>
       init(responseArray: Array<String>) {
            self.responseArray = ["unchecked","unchecked","unchecked","unchecked","unchecked","unchecked","unchecked"]
        }

        mutating func updateArray(_ anArray: Array<String>) -> (Array<String>) {
            responseArray = anArray
            return responseArray
        }

    }

    class ButtonResponse: UIButton {

        var responseVariables: ResponseProfile

        var checkedImage = UIImage(named: "checkedResponseBox")! as UIImage
        var uncheckedImage = UIImage(named: "uncheckedResponseBox")! as UIImage

        required init?(coder aDecoder: NSCoder) {
            self.responseVariables = ResponseProfile(
                responseArray: []
            )
            super.init(coder: aDecoder)
        }


        @IBAction func checkboxTapped(_ sender: UIButton) {
            switch sender.accessibilityIdentifier {
                case "excellent":

                    let oldResponseStatus = responseVariables.responseArray[0]
                    if oldResponseStatus == "unchecked"{
                        sender.setImage(checkedImage, for: UIControlState.normal)
                        let oldResponsePresence = responseVariables.responseArray.contains("checked")

                        if oldResponsePresence == true {
                            responseVariables.responseArray = ["unchecked","unchecked","unchecked","unchecked","unchecked","unchecked","unchecked"]
                        }
                        responseVariables.responseArray[0] = "checked"
                    } else if oldResponseStatus == "checked" {
                        sender.setImage(uncheckedImage, for: UIControlState.normal)
                        responseVariables.responseArray[0] = "unchecked"
                }

                case "veryGood":
                    let oldResponseStatus = responseVariables.responseArray[1]
                    if oldResponseStatus == "unchecked" {
                        sender.setImage(checkedImage, for: UIControlState.normal)
                        let oldResponsePresence = responseVariables.responseArray.contains("checked")
                        if oldResponsePresence == true {
                            responseVariables.responseArray = ["unchecked","unchecked","unchecked","unchecked","unchecked","unchecked","unchecked"]
                        }
                        responseVariables.responseArray[1] = "checked"
                    } else if oldResponseStatus == "checked" {
                        sender.setImage(uncheckedImage, for: UIControlState.normal)
                        responseVariables.responseArray[1] = "unchecked"
                    }

                default: break

            }
        }

    }


我以为我可以使用数组在内部表示用户界面中按钮的状态(这就是“ responseArray”变量)。通过在按下按钮后更改responseArray中的元素,我认为我可以跟踪按下了哪些按钮,并确保一次只检查一个按钮。我错误地认为responseArray将被更新,但事实并非如此。阵列始终恢复为其初始状态。

N.B.由于有七个响应选项,所以responseArray包含七个元素。到目前为止,我仅尝试对两个响应选项进行编程:“优秀”和“非常好”。

为了找到解决方案,我尝试在操场上简化以上代码:

import UIKit

    struct ResponseProfile {
        var responseArray: Array<String>
        init(responseArray: Array<String>) {
            self.responseArray =     ["unchecked","unchecked","unchecked","unchecked","unchecked","unchecked","unchecked"]
        }
        mutating func updateArray(input anArray: Array<String>) -> (Array<String>) {
            responseArray = anArray
            return responseArray
        }
    }

    class ButtonResponse {
        var responseVariables: ResponseProfile
        init(){
            self.responseVariables = ResponseProfile(responseArray: [])
        }
        var responseA = ResponseProfile(responseArray: [])

    }

    var responseOne = ResponseProfile(responseArray: [])
    responseOne.responseArray[0] = "checked" //user performs action resulting in first element being changed from a starting value of "unchecked" to "checked"
    responseOne.updateArray(input: responseOne.responseArray)

    var responseTwo = ResponseProfile(responseArray:[])
    responseTwo.responseArray //responseArray revert to initialization values. How can I keep changes to the responseArray?


如何在ResponseProfile结构内更新responseArray,而不必创建新变量来记录每个更改?这是我应该关注的问题,还是从更一般的角度来看,我应该采取的更好的策略?

我为解决这个问题而付出如此艰巨的努力感到惊讶。我认为,如果我阅读了文档的相关部分并研究了一些示例代码,答案将会很清楚。我发现的所有示例代码都过于简单,仅关注于更新数组的一次迭代。

任何意见或建议将不胜感激!

最佳答案

查看您的运动场代码,我发现您在初始化期间将一个空白[]数组传递给ResponseProfile结构的参数。并且它总是在初始化您的responseArray。

如果要通过引用传递事物,可以将Response配置文件更改为class
在那里,您可以实现类似的功能,并使用inout参数保留相同的数组,而无需使用updateArray函数。

我在这里显示的示例是针对类的,可以通过引用传递类的对象。因此保留您以前的更改。

var responseTwo = ResponseProfile(responseArray:[])


如果您想保留旧的响应,则可以将该数组作为参数传递

var responseTwo = ResponseProfile(responseArray:responseOne.responseArray)


要么

var responseTwo = responseOne


将保留responseArray。

您可以在官方blog上了解有关此内容的更多信息

您也可以this post对该案例有更多的了解。

希望能帮助到你。

09-15 19:01