我正在开发一个Swift程序,它将计算用户的燃烧卡路里并相应地更新计数器图表,以便用户可以看到他们的进度。但是我实际更新显示器的计数器时遇到了麻烦,因为我不确定如何将更新调用为另一个视图控制器中存在的变量。
所以我的所有卡路里计算都发生在我的主ViewController文件中,我在那里用必要的数据更新标签。
然后我尝试将必要的卡路里数据传递给另一个名为CounterView的视图控制器,我的意思是更新计数变量,以便我的图形能够做出相应的反应。
我想要做的就是更新我的CounterView中存在的count
变量,并在ViewController中计算数据。我认为我的代码是有道理的,我知道我必须做什么,我只是认为我的语法是错误的...无论如何,任何帮助将不胜感激!
参考代码:
主ViewController:
class ViewController: UIViewController {
//So that I can access the CounterView view controller
// I think this is where I am messing up...
var counterView: CounterView!
@IBOutlet weak var displayData: UILabel!
@IBOutlet weak var pizzaData: UILabel!
var arrayImage : [UIImageView]?
var data = HKHealthStore()
var timer: NSTimer?
var track: Int = 0
override func viewDidLoad() {
print("first")
super.viewDidLoad()
// Asks the user to allow access to HealthKit data
if let energyType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierActiveEnergyBurned) {
print("Test1")
let setType = Set<HKSampleType>(arrayLiteral: energyType)
data.requestAuthorizationToShareTypes(setType, readTypes: setType, completion: { (success, error) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.loadData()
print("Test2")
// Below code attempts to refresh the loadData function periodically
self.timer = NSTimer.scheduledTimerWithTimeInterval(15, target: self, selector: Selector("loadData"), userInfo: nil, repeats: true)
})
})
}
print("Test3")
}
func notifyWatch(data:String){
let session = WCSession.defaultSession()
if session.paired && session.watchAppInstalled {
session.sendMessage(["data":data], replyHandler: { (dataReply) -> Void in
print("It works")
}, errorHandler: { (error) -> Void in
print("An error has occured \(error.localizedDescription)")
})
}
}
var time: NSDate?
func fetch(completion: () -> Void) {
time = NSDate()
completion()
}
// Collect and load the data
func loadData() {
let startDate = NSDate.distantPast()
let endDate = NSDate()
if let energyType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierActiveEnergyBurned) {
// Predicate so that we collect data from within the same day
let timeFrame = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: endDate, options: .None)
// Sort descriptor to get most recent data first
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)
// Execute query and gather Health data
data.executeQuery(HKSampleQuery(sampleType: energyType, predicate: timeFrame, limit: 0, sortDescriptors: [sortDescriptor], resultsHandler: { (query: HKSampleQuery?, results: [HKSample]?, err: NSError?) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
if err != nil {
// ERROR Occurred
print(err)
return
}
var calories = 0
var pizzas = 0
for result in results as! [HKQuantitySample]! {
// SUCCESS, use results here
print("Sample:", result)
print("Quantity", Int(result.quantity.doubleValueForUnit(HKUnit.kilocalorieUnit())), "Calories")
calories += Int(result.quantity.doubleValueForUnit(HKUnit.kilocalorieUnit()))
print("Pizzas", pizzas)
print(calories)
}
//Line where I get the Bad Instruction Error
self.counterView.count += (calories%480)/480 * 360
pizzas = Int(calories/480)
self.displayData.text = "\(String(calories)) Calories"
self.pizzaData.text = "Slices:\(String(pizzas))x"
self.notifyWatch(self.pizzaData.text!)
})
}))
}
}
我的CounterView代码:
var NoOfGlasses = 360
let π:CGFloat = CGFloat(M_PI)
@IBDesignable class CounterView: UIView {
@IBInspectable var count: Int = 0
@IBInspectable var outlineColor: UIColor = UIColor.brownColor()
@IBInspectable var counterColor: UIColor = UIColor.orangeColor()
override func drawRect(rect: CGRect) {
// 1
let center = CGPoint(x:bounds.width/2, y: bounds.height/2)
// 2
let radius: CGFloat = max(bounds.width, bounds.height)
// 3
let arcWidth: CGFloat = 169
// 4
let startAngle: CGFloat = 3 * π / 2
let endAngle: CGFloat = 3 * π / 2
// 5
let path = UIBezierPath(arcCenter: center,
radius: radius/2 - arcWidth/2,
startAngle: startAngle,
endAngle: endAngle,
clockwise: true)
// 6
path.lineWidth = arcWidth
counterColor.setStroke()
path.stroke()
//Draw the outline
//1 - first calculate the difference between the two angles
//ensuring it is positive
let angleDifference: CGFloat = 2 * π - startAngle + endAngle
//then calculate the arc for each single glass
let arcLengthPerGlass = angleDifference / CGFloat(NoOfGlasses)
//then multiply out by the actual glasses drunk
let outlineEndAngle = arcLengthPerGlass * CGFloat(count) + startAngle
//2 - draw the outer arc
let outlinePath = UIBezierPath(arcCenter: center,
radius: bounds.width/2 - 2.5,
startAngle: startAngle,
endAngle: outlineEndAngle,
clockwise: true)
//3 - draw the inner arc
outlinePath.addArcWithCenter(center,
radius: bounds.width/2 - arcWidth + 2.5,
startAngle: outlineEndAngle,
endAngle: startAngle,
clockwise: false)
//4 - close the path
outlinePath.closePath()
let fillColor: UIColor = UIColor.orangeColor()
outlineColor.setStroke()
outlinePath.lineWidth = 5.0
outlinePath.stroke()
fillColor.setFill()
outlinePath.fill()
//Counter View markers
let context = UIGraphicsGetCurrentContext()
//1 - save original state
CGContextSaveGState(context)
outlineColor.setFill()
}