【问题标题】:Swift: modifying data format through a button clickSwift:通过单击按钮修改数据格式
【发布时间】:2020-09-28 01:53:33
【问题描述】:

我的目标是使用一个按钮(包含多条消息)触发一个文本(制作标记,例如第一次单击将是方法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&lt;Float&gt;]),因为它带有错误:Cannot convert value of type '[SIMD3&lt;Float&gt;].Type' to expected argument type '[SIMD3&lt;Float&gt;]'

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

【问题讨论】:

  • 突变不应该发生在结构而不是枚举中吗?
  • 感谢您的回复!我对 swift 有点陌生,目前正在努力学习。你的意思是在结构中改变模式或 v 吗?你能指导我一下吗?

标签: ios swift xcode uibutton


【解决方案1】:

枚举是一种数据类型,它更像是一个常量,但可读性更高。

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

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 中的枚举有点不同,但功能更强大。有关枚举的更多信息here

回到主题。

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

希望这会有所帮助。

【讨论】:

  • 您好@Joshua,非常感谢您的回复!我能够修复结构中的变异错误。我尝试在我的 UIbutton 中实现 var instance = CaptureData() 以在单击后切换案例。但是,现在我无法按照您的指示执行 CaptureData(),因为 var vertices: [SIMD3]。我上传了那个。我能问你这种方法是否适合我的情况吗? (我也试过 var instance = CaptureData(vertices: [SIMD3])
  • 只要 CaptureData 的初始化在您的 IBAction 之外,就像您所做的 var x 一样。 CaptureData 的初始化是您指出的方式,您需要传入差异顶点,即 CaptureData(vertices: [])。那么该实例的所有功能都应该可以在 IBAction 中访问。事情搞清楚了吗?
  • 一切都好,你能在你的帖子中添加编辑吗,发生了什么变化,你是如何调用 CaptureData 实例的?需要了解遇到这些问题的原因。
  • @swiftLearneer 我明白了问题所在。我认为您需要了解如何初始化事物。 CaptureData 需要一个顶点列表。即 CaptureData(vertices: [SIMD3(1), SIMD(2)]) 我不知道 SIMD3 实际上是什么,所以我希望它像这样初始化?阅读有关变量初始化的更多信息。
  • 感谢您的时间@Joshua!我编辑了我所拥有的和我正在处理的问题。我希望它是同一个主题,这样我的问题不会偏离原来的主题。我将看看变量的初始化,看看我是否能弄清楚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-09
  • 1970-01-01
  • 2020-11-16
  • 1970-01-01
  • 2014-04-17
  • 2014-09-27
相关资源
最近更新 更多