首页 > 解决方案 > Swift:通过单击按钮修改数据格式

问题描述

我的目标是使用一个按钮(包含多条消息)来触发文本(制作标记,例如第一次单击将是方法1,第二次单击将是方法2)相应添加在我的数据末尾(加入后(分隔符:"~")) 以便我在查看数据时分析单击了哪个按钮。

目前,我有一个将输出数据的结构:

struct CaptureData {
var vertices: [SIMD3<Float>] //A vector of three scalar values. It will return a list of [SIMD3<Float>(x,y,z)]
var mode: Mode = .one
mutating func nextCase() { // the data method will be changed
    mode = mode.next()
}
var verticesFormatted : String {  //I formatted in such a way so that it can be read more clearly without SIMD3
let v = "<" + vertices.map{ "\($0.x):\($0.y):\($0.z)" }.joined(separator: "~") + "trial: \(mode.next().rawValue)"
        return "\(v)"
    }
}

基于@Joshua 的建议

enum Mode: String, CaseIterable {
    case one, two, three
}
extension CaseIterable where Self: Equatable {
    var allCases: AllCases { Self.allCases }
    var nextCase: Self {
        let index = allCases.index(after: allCases.firstIndex(of: self)!)
        guard index != allCases.endIndex else { return allCases.first! }
        return allCases[index]
    }
    @discardableResult
    func next() -> Self {
        return self.nextCase
    }
}

每次点击后,按钮都会交替显示消息,

  var x = 0
  var instance = CaptureData(vertices: [SIMD3<Float>])
// Next button for changing methods
@IBAction func ChangingTapped(_ btn: UIButton) {
  if(x==0){
      Textfield.text = "changing to driving"
  }
  else if(x==1){
       Textfield.text = "changing to walking"
     instance.nextCase()
  }
  else{
     Textfield.text = "changing to cycling"
     instance.nextCase()
  }
   x += 1
}

更新:我可以在分隔符“~”之后打印其中一种方法,.two(方法二)。但是,目前我仍然无法单击按钮来切换数据中的案例。

主要问题是变量的初始化。我无法定义var instance = CaptureData(vertices: [SIMD3<Float>]),因为它带有错误:Cannot convert value of type '[SIMD3<Float>].Type' to expected argument type '[SIMD3<Float>]'

如果我的解释在这里有点混乱,我很抱歉。我试图描述我在这里遇到的问题。让我知道是否缺少任何东西!非常感谢你。

标签: iosswiftxcodeuibutton

解决方案


Enums 是一种数据类型,它更像是一个常量,但更具可读性。

一个例子是将状态传递给函数。

enum Status {
   case success
   case failure
}

func updateStatus(_ status: Status) {
    statusProperty = status
}

// somewhere in your code
instance.updateStatus(.success)

与使用 Int 作为值相比。

func updateStatus(_ status: Int) {
    statusProperty = status
}

// somewhere in your code
instance.updateStatus(1) // eventually you'll forget what this and you'll declare more of a global variable acting as constant, which technically what enums are for.

swift 中的枚举虽然有点不同,但功能更强大。有关枚举的更多信息在这里

回到主题。

enum Mode: String, CaseIterable {
    case one, two, three
}

extension CaseIterable where Self: Equatable {
    var allCases: AllCases { Self.allCases }
    var nextCase: Self {
        let index = allCases.index(after: allCases.firstIndex(of: self)!)
        guard index != allCases.endIndex else { return allCases.first! }
        return allCases[index]
    }

    @discardableResult
    func next() -> Self { // you don't need to update self here, remember self here is one of the items in the enum, i.e. one, so assigning one = two just doesn't work.
        return self.nextCase
    }
}

// The data struct
struct CaptureData {
    var mode: Mode = .one
   // we add a mutation function here so we can update the mode
    mutating func nextCase() { // the data your concern about, that can actually mutate is the mode property inside CaptureData struct. 
        mode = mode.next()
    }
}

所以让我们说在应用程序的某个地方你可以像这样使用它你初始化了一个 CaptureData 的实例:

var instance = CaptureData() // Don't forget it should be var and not let, as we are updating its property.
instance.nextCase() // get the next case, initially it was .one
print(instance.mode) // prints two
instance.nextCase() // from .two, changes to .three
print(instance.mode) // prints three

希望这可以帮助。


推荐阅读