首页 > 解决方案 > Swift 中的函数

问题描述

我试图通过构建一个非常基本的杠铃重量板计算器来快速学习 - 用户在文本字段中输入一个数字并显示所需的板。

我在 Swift Playgrounds 中编写了一个非常适合我尝试做的函数,但我不明白如何将它移动到用户输入数字并进行过滤的应用程序视图中。

我曾尝试在网上寻找对此的解释,但没有任何运气:这是我的 Swift Playground 代码,理想情况下我想使用它:

import UIKit

func barbellweight (weight: Int){
    var plate_hash : [Int:Int] = [:]

    if weight == 45 {
        print("You only need the bar!")
    }else if weight < 45{
        print("Must be divisible by 5!")
    }else if (weight % 5 != 0){
           print("Must be divisible by 5!")
    }else{
        
        let plate_array = [45, 35, 25, 10, 5, 2.5]
        var one_side_weight = Double(weight - 45) / 2.0

        for plate_size in plate_array {
            var plate_amount = (one_side_weight / plate_size)
            plate_amount.round(.towardZero)
            one_side_weight -= (plate_size * plate_amount)
            plate_hash[Int(plate_size)] = Int(plate_amount)
        }
    }
    let plate_hash_filtered = plate_hash.filter { $0.value > 0 }
    //print(plate_hash_filtered)
    print(plate_hash_filtered)
}

barbellweight(weight: 225)

这是尝试在 Swift UI 中实现它,但没有任何运气。我知道它已经解构并且略有不同——我不太明白如何将函数集成到 SwiftUI 中。如果有人对这个特定问题的资源有任何建议,我将不胜感激。

import SwiftUI

struct Weight_Plate: View {
    @State var weight: String = "135"
    @State var plate_hash = [String]()
    @State var plate_array = [45, 35, 25, 10, 5, 2.5]
    
    
    var body: some View {
        var one_side_weight = Double(Int(weight)! - 45) / 2.0
                
        List{
            Text("Number of Plates Needed Per Side")
                .multilineTextAlignment(.center)
            ForEach(self.plate_array, id: \.self) { plate_size in
                var plate_amount = (one_side_weight / plate_size)
                if Int(weight) == 45 {
                    Text("You only need the bar!")
                } else if Int(weight)! < 45 {
                    Text("Must be divisible by 5!")
                } else if (Int(weight)! % 5 != 0) {
                       Text("Must be divisible by 5!")
                } else {
                        //Text("Error")
                        plate_amount.round(.towardZero)
                        one_side_weight -= (plate_size * plate_amount)
                    Text("\(Int(plate_size)) x \(Int(plate_amount))")
                            
                       // Text("\(plate):\(Int(plate_amount))")
            }
        }
            
        HStack(alignment: .center) {
            Text("Weight:")
                .font(.callout)
                .bold()
            TextField("Enter Desired Weight", text: $weight)
                .textFieldStyle(RoundedBorderTextFieldStyle())
        }.padding()
    }
}

}
struct Weight_Plate_Previews: PreviewProvider {
    static var previews: some View {
        Weight_Plate()
    }
}

我感谢任何有关参考资料的帮助和建议,以帮助我解决这个问题。谢谢!

标签: swiftfunctionswiftui

解决方案


你知道你仍然可以定义和调用函数吗?

将您的代码更改为此

import SwiftUI
func barbellWeight (weight: Int) -> [String] { // naming convention in Swift is camelcase
    var plate_hash = [Int: Int]()

    if weight == 45 {
        return ["You only need the bar!"]
    } else if weight < 45 {
        return ["Insufficient weight!"]
    } else if weight % 5 != 0 {
        return ["Must be divisible by 5!"]
    } else {
        let plate_array = [45, 35, 25, 10, 5, 2.5]
        var one_side_weight = Double(weight - 45) / 2.0

        for plate_size in plate_array {
            var plate_amount = (one_side_weight / plate_size)
            plate_amount.round(.towardZero)
            one_side_weight -= plate_size * plate_amount
            plate_hash[Int(plate_size)] = Int(plate_amount)
        }
    }
    
    return plate_hash.compactMap {
        if $0.value < 0 {
            return nil
        } else {
            return "\($0.key): \($0.value)"
        }
    }
    
}
    
struct Weight_Plate: View {
    @State var weight = "135"
    
    var body: some View {
        List {
            ForEach(barbellWeight(weight: Int(weight) ?? 135), id: \.self) {
                Text($0)
            }
        }
            
        HStack(alignment: .center) {
            Text("Weight:")
                .font(.callout)
                .bold()
            TextField("Enter Desired Weight", text: $weight)
                .textFieldStyle(RoundedBorderTextFieldStyle())
        }.padding()
    }
}
struct Weight_Plate_Previews: PreviewProvider {
    static var previews: some View {
        Weight_Plate()
    }
}

当然,你可以玩弄这个,让它看起来更好。还有其他方法可以更有效地执行此操作,但这是有效的。

编辑:您只需像往常一样定义函数!我重写了你的函数来返回一个字符串数组,每个字符串对应一个盘子,当你运行它时你可以看到计数对。由于 weight 是一个 @State 变量,因此当您通过接受用户的输入来更改它时,SwiftUI 会自动重新加载依赖于该变量的任何视图。这会导致重新加载 ForEach 并再次调用您的函数。ForEach 接受一组项目,所以这就是我将字典的键和值粘合在一起的原因。也许这可以清除一点。

如需帮助学习 SwiftUI,请查看 Paul Hudson 的网站。这就是我开始学习 SwiftUI 以及如何过渡到 UIKit 的方式。

https://www.hackingwithswift.com/100/swiftui


推荐阅读