如何动态更改分段控件中标签中的值? Swift 4, iOS
How to dinamically change values in labels in a SegmentedControl? Swift 4, iOS
我在执行分段控件时遇到了一些问题。
我来找你(更有经验的人)是为了得到一些关于我应该做什么来解决这个问题的建议。我来了:
对于"current"选项卡,"Panel's optimal azimuth"和"Panel's optimal tilt angle"应该是"tracking the sun"(我稍后会添加的代码),换句话说:这2个字段必须实时更新(同样,我稍后会做的代码)。 "Panel's current azimuth" 和 "Panels current tilt angle" 基本上根据 phone 的位置而变化(我使用 coreMotion 和 coreLocation 来获取它们)。
问题是这样的(解释后添加图片):
对于"current"选项卡,"panel's optimal azimuth"和"Panel's optimal tilt angle"的字段必须随时间变化。 "Panel's current tilt angle" 必须从头开始显示
面板 (phone's) 倾斜但它不这样做(仅当您 select 另一个选项卡时才这样做)。
"Panel's Optimal Tilt Angle" 必须有一个固定的(但不同的)值
3、6 个月和 "Year" 选项卡。 "Panel's Optimal Azimuth" 与 3、6 个月和 "year" 选项卡相同(该代码我稍后也会添加)。然而,当我 select "Current" 选项卡时,我遇到了问题,在这里,"Panel's optimal Azimuth" 获得值 "tracking the sun",并且
当我选择另一个选项卡时,该值应该保持为“180º”。只有当 phone 仍在表面上时才会发生这种情况,只要我移动 phone,该字段中的值就会变为 180º。当我从其他选项卡转到 "current" 选项卡时会发生相反的情况(而不是显示 "tracking the sun" 它显示“180º”,同样,当 phone 移动时会出现此值,但是如果phone 静止,"tracking the sun" 显示)。
基本上,唯一正常工作的字段是分段控件中所有 4 个选项卡中的 "Panel's current Azimuth"。
请参考图片以获得更好的想法。
What I get in the initial view
What I want in the initial view
What I get if the phone is moving (this is correct for the 3, 6 months and year tabs)
What I get if the phone is still, if I chose the "current" tab while the phone was still and then I selected another tab
Same as previos image
所以,我的问题是:我该怎么做才能防止这种情况发生?我尝试在与分段控件对应的@IBAction 中使用switch-case 语句,但显然它不起作用。我在这
与您分享我在项目中使用的代码:
import UIKit
import CoreMotion
import CoreLocation
class PVOrientationViewController: UIViewController, CLLocationManagerDelegate {
//MARK: - Constants and Variables
let motionManager = CMMotionManager()
let locationManager = CLLocationManager()
var segIndex = 0
//MARK: - Outlets, views, actions
@IBOutlet weak var panelOptimalAz: UILabel!
@IBOutlet weak var panelOptimalTilt: UILabel!
@IBOutlet weak var panelCurrentAz: UILabel!
@IBOutlet weak var panelCurrentTilt: UILabel!
@IBOutlet weak var segmentedControl: UISegmentedControl!
//MARK: - Action of the Segmented Button.
@IBAction func indexChanged(_ sender: Any) {
segIndex = segmentedControl.selectedSegmentIndex
switch segIndex {
case 0:
print("Current Tab")
panelOptimalAz.text = "Tracking the Sun"
panelCurrentTilt.text = myDeviceMotion()
case 1:
print("3 months Tab")
panelCurrentTilt.text = String(myDeviceMotion())
case 2:
print("6 months Tab")
panelCurrentTilt.text = String(myDeviceMotion())
case 3:
print("Year tab")
panelCurrentTilt.text = String(myDeviceMotion())
default:
panelOptimalAz.text = "No Optimal Azimuth given"
panelCurrentAz.text = "No Current Azimuth given"
panelCurrentTilt.text = "No Current Tilt given"
panelOptimalTilt.text = "No Optimal Tilt given"
}
}
//MARK: - viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
// Azimuth
if (CLLocationManager.headingAvailable()) {
locationManager.headingFilter = 1
locationManager.startUpdatingHeading()
}
}
//MARK: - Motion methods
func myDeviceMotion() -> String{
var currentTilt:String = "0.0º"
if motionManager.isDeviceMotionAvailable {
motionManager.deviceMotionUpdateInterval = 0.1
motionManager.startDeviceMotionUpdates(to: OperationQueue()) {(motion, error) -> Void in
if let attitude = motion?.attitude {
DispatchQueue.main.async{
self.panelCurrentTilt.text = "\(String(format:"%.0f", attitude.pitch * 180 / Double.pi))º"
currentTilt = "\(String(format:"%.0f", attitude.pitch * 180 / Double.pi))º"
}
}
}
print("Device motion started")
}else {
print("Device motion unavailable")
}
return currentTilt
}
//MARK: - True heading and panel's heading
func locationManager(_ manager: CLLocationManager, didUpdateHeading heading: CLHeading) {
let trueHeading = heading.trueHeading
self.panelCurrentAz.text = "\(String(format: "%.0f", trueHeading))º"
//If latitude >= 0, then panel's azimuth = 180º, else, it is 0º
var panelHeading = 0.0
if GlobalData.latit >= 0.0{
self.panelOptimalAz.text = "180º"
panelHeading = trueHeading - 180.0
if panelHeading < 0{
panelHeading += 360.0
self.panelCurrentAz.text = "\(String(format: "%.0f", panelHeading))º"
} else {
panelHeading += 0.0
self.panelCurrentAz.text = "\(String(format: "%.0f", panelHeading))º"
}
}else{
self.panelOptimalAz.text = "0º"
panelHeading = trueHeading + 180.0
if panelHeading > 359.0{
panelHeading -= 360.0
self.panelCurrentAz.text = "\(String(format: "%.0f", panelHeading))º"
} else {
panelHeading += 0.0
self.panelCurrentAz.text = "\(String(format: "%.0f", panelHeading))º"
}
}
}
}
提前感谢您的宝贵时间和建议。
你好。
回顾...
OptimalAz
标签应该说 "Tracking the Sun" 如果 当前选择的段是 "Current",所以在 didUpdateHeading
中添加一个 if ()
以仅在选择其他段时更新该标签。
在 viewDidLoad()
中启动运动管理器(连同位置管理器)...它将继续 运行 - 并继续更新标签 - 因此不需要 myDeviceMotion()
功能
在 viewDidLoad()
结束时,触发 indexChanged()
初始化标签(以及任何其他需要的任务/变量),就像用户点击 "Current" 片段一样。
试一试(我想我在代码中添加了足够的注释来解释任何更改):
import UIKit
import CoreMotion
import CoreLocation
class PVOrientationViewController: UIViewController, CLLocationManagerDelegate {
//MARK: - Constants and Variables
let motionManager = CMMotionManager()
let locationManager = CLLocationManager()
var segIndex = 0
//MARK: - Outlets, views, actions
@IBOutlet weak var panelOptimalAz: UILabel!
@IBOutlet weak var panelOptimalTilt: UILabel!
@IBOutlet weak var panelCurrentAz: UILabel!
@IBOutlet weak var panelCurrentTilt: UILabel!
@IBOutlet weak var segmentedControl: UISegmentedControl!
//MARK: - Action of the Segmented Button.
@IBAction func indexChanged(_ sender: Any) {
segIndex = segmentedControl.selectedSegmentIndex
switch segIndex {
case 0:
print("Current Tab")
panelOptimalAz.text = "Tracking the Sun"
case 1:
print("3 months Tab")
// do something related to 3 months
case 2:
print("6 months Tab")
// do something related to 6 months
case 3:
print("Year tab")
// do something related to Year
default:
panelOptimalAz.text = "No Optimal Azimuth given"
panelCurrentAz.text = "No Current Azimuth given"
panelCurrentTilt.text = "No Current Tilt given"
panelOptimalTilt.text = "No Optimal Tilt given"
}
}
//MARK: - viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
// Azimuth
if (CLLocationManager.headingAvailable()) {
locationManager.headingFilter = 1
locationManager.startUpdatingHeading()
}
// start the motion manager here, since we want it running all the time
if motionManager.isDeviceMotionAvailable {
motionManager.deviceMotionUpdateInterval = 0.1
motionManager.startDeviceMotionUpdates(to: OperationQueue()) {(motion, error) -> Void in
if let attitude = motion?.attitude {
DispatchQueue.main.async{
self.panelCurrentTilt.text = "\(String(format:"%.0f", attitude.pitch * 180 / Double.pi))º"
}
}
}
print("Device motion started")
}else {
print("Device motion unavailable")
}
// call segment changed to update on start (as if user tapped seg 0)
self.indexChanged(segmentedControl)
}
//MARK: - Motion methods
// no need for this
// func myDeviceMotion() -> String{
//
// var currentTilt:String = "0.0º"
//
// return currentTilt
//
// }
//MARK: - True heading and panel's heading
func locationManager(_ manager: CLLocationManager, didUpdateHeading heading: CLHeading) {
let trueHeading = heading.trueHeading
//If latitude >= 0, then panel's azimuth = 180º, else, it is 0º
var panelHeading = 0.0
// I don't have your GlobalData object, so
// just hard-coding 1.0 here...
// if GlobalData.latit >= 0.0{
if 1.0 >= 0.0 {
// only update Optimal Az label if "Current" seg is NOT selected
if self.segmentedControl.selectedSegmentIndex != 0 {
self.panelOptimalAz.text = "180º"
}
panelHeading = trueHeading - 180.0
if panelHeading < 0{
panelHeading += 360.0
}
self.panelCurrentAz.text = "\(String(format: "%.0f", panelHeading))º"
}else{
// only update Optimal Az label if "Current" seg is NOT selected
if self.segmentedControl.selectedSegmentIndex != 0 {
self.panelOptimalAz.text = "0º"
}
panelHeading = trueHeading + 180.0
if panelHeading > 359.0{
panelHeading -= 360.0
}
self.panelCurrentAz.text = "\(String(format: "%.0f", panelHeading))º"
}
}
}
我在执行分段控件时遇到了一些问题。 我来找你(更有经验的人)是为了得到一些关于我应该做什么来解决这个问题的建议。我来了:
对于"current"选项卡,"Panel's optimal azimuth"和"Panel's optimal tilt angle"应该是"tracking the sun"(我稍后会添加的代码),换句话说:这2个字段必须实时更新(同样,我稍后会做的代码)。 "Panel's current azimuth" 和 "Panels current tilt angle" 基本上根据 phone 的位置而变化(我使用 coreMotion 和 coreLocation 来获取它们)。
问题是这样的(解释后添加图片):
对于"current"选项卡,"panel's optimal azimuth"和"Panel's optimal tilt angle"的字段必须随时间变化。 "Panel's current tilt angle" 必须从头开始显示 面板 (phone's) 倾斜但它不这样做(仅当您 select 另一个选项卡时才这样做)。
"Panel's Optimal Tilt Angle" 必须有一个固定的(但不同的)值 3、6 个月和 "Year" 选项卡。 "Panel's Optimal Azimuth" 与 3、6 个月和 "year" 选项卡相同(该代码我稍后也会添加)。然而,当我 select "Current" 选项卡时,我遇到了问题,在这里,"Panel's optimal Azimuth" 获得值 "tracking the sun",并且 当我选择另一个选项卡时,该值应该保持为“180º”。只有当 phone 仍在表面上时才会发生这种情况,只要我移动 phone,该字段中的值就会变为 180º。当我从其他选项卡转到 "current" 选项卡时会发生相反的情况(而不是显示 "tracking the sun" 它显示“180º”,同样,当 phone 移动时会出现此值,但是如果phone 静止,"tracking the sun" 显示)。
基本上,唯一正常工作的字段是分段控件中所有 4 个选项卡中的 "Panel's current Azimuth"。
请参考图片以获得更好的想法。
What I get in the initial view
What I want in the initial view
What I get if the phone is moving (this is correct for the 3, 6 months and year tabs)
What I get if the phone is still, if I chose the "current" tab while the phone was still and then I selected another tab
Same as previos image
所以,我的问题是:我该怎么做才能防止这种情况发生?我尝试在与分段控件对应的@IBAction 中使用switch-case 语句,但显然它不起作用。我在这 与您分享我在项目中使用的代码:
import UIKit
import CoreMotion
import CoreLocation
class PVOrientationViewController: UIViewController, CLLocationManagerDelegate {
//MARK: - Constants and Variables
let motionManager = CMMotionManager()
let locationManager = CLLocationManager()
var segIndex = 0
//MARK: - Outlets, views, actions
@IBOutlet weak var panelOptimalAz: UILabel!
@IBOutlet weak var panelOptimalTilt: UILabel!
@IBOutlet weak var panelCurrentAz: UILabel!
@IBOutlet weak var panelCurrentTilt: UILabel!
@IBOutlet weak var segmentedControl: UISegmentedControl!
//MARK: - Action of the Segmented Button.
@IBAction func indexChanged(_ sender: Any) {
segIndex = segmentedControl.selectedSegmentIndex
switch segIndex {
case 0:
print("Current Tab")
panelOptimalAz.text = "Tracking the Sun"
panelCurrentTilt.text = myDeviceMotion()
case 1:
print("3 months Tab")
panelCurrentTilt.text = String(myDeviceMotion())
case 2:
print("6 months Tab")
panelCurrentTilt.text = String(myDeviceMotion())
case 3:
print("Year tab")
panelCurrentTilt.text = String(myDeviceMotion())
default:
panelOptimalAz.text = "No Optimal Azimuth given"
panelCurrentAz.text = "No Current Azimuth given"
panelCurrentTilt.text = "No Current Tilt given"
panelOptimalTilt.text = "No Optimal Tilt given"
}
}
//MARK: - viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
// Azimuth
if (CLLocationManager.headingAvailable()) {
locationManager.headingFilter = 1
locationManager.startUpdatingHeading()
}
}
//MARK: - Motion methods
func myDeviceMotion() -> String{
var currentTilt:String = "0.0º"
if motionManager.isDeviceMotionAvailable {
motionManager.deviceMotionUpdateInterval = 0.1
motionManager.startDeviceMotionUpdates(to: OperationQueue()) {(motion, error) -> Void in
if let attitude = motion?.attitude {
DispatchQueue.main.async{
self.panelCurrentTilt.text = "\(String(format:"%.0f", attitude.pitch * 180 / Double.pi))º"
currentTilt = "\(String(format:"%.0f", attitude.pitch * 180 / Double.pi))º"
}
}
}
print("Device motion started")
}else {
print("Device motion unavailable")
}
return currentTilt
}
//MARK: - True heading and panel's heading
func locationManager(_ manager: CLLocationManager, didUpdateHeading heading: CLHeading) {
let trueHeading = heading.trueHeading
self.panelCurrentAz.text = "\(String(format: "%.0f", trueHeading))º"
//If latitude >= 0, then panel's azimuth = 180º, else, it is 0º
var panelHeading = 0.0
if GlobalData.latit >= 0.0{
self.panelOptimalAz.text = "180º"
panelHeading = trueHeading - 180.0
if panelHeading < 0{
panelHeading += 360.0
self.panelCurrentAz.text = "\(String(format: "%.0f", panelHeading))º"
} else {
panelHeading += 0.0
self.panelCurrentAz.text = "\(String(format: "%.0f", panelHeading))º"
}
}else{
self.panelOptimalAz.text = "0º"
panelHeading = trueHeading + 180.0
if panelHeading > 359.0{
panelHeading -= 360.0
self.panelCurrentAz.text = "\(String(format: "%.0f", panelHeading))º"
} else {
panelHeading += 0.0
self.panelCurrentAz.text = "\(String(format: "%.0f", panelHeading))º"
}
}
}
}
提前感谢您的宝贵时间和建议。
你好。
回顾...
OptimalAz
标签应该说 "Tracking the Sun" 如果 当前选择的段是 "Current",所以在 didUpdateHeading
中添加一个 if ()
以仅在选择其他段时更新该标签。
在 viewDidLoad()
中启动运动管理器(连同位置管理器)...它将继续 运行 - 并继续更新标签 - 因此不需要 myDeviceMotion()
功能
在 viewDidLoad()
结束时,触发 indexChanged()
初始化标签(以及任何其他需要的任务/变量),就像用户点击 "Current" 片段一样。
试一试(我想我在代码中添加了足够的注释来解释任何更改):
import UIKit
import CoreMotion
import CoreLocation
class PVOrientationViewController: UIViewController, CLLocationManagerDelegate {
//MARK: - Constants and Variables
let motionManager = CMMotionManager()
let locationManager = CLLocationManager()
var segIndex = 0
//MARK: - Outlets, views, actions
@IBOutlet weak var panelOptimalAz: UILabel!
@IBOutlet weak var panelOptimalTilt: UILabel!
@IBOutlet weak var panelCurrentAz: UILabel!
@IBOutlet weak var panelCurrentTilt: UILabel!
@IBOutlet weak var segmentedControl: UISegmentedControl!
//MARK: - Action of the Segmented Button.
@IBAction func indexChanged(_ sender: Any) {
segIndex = segmentedControl.selectedSegmentIndex
switch segIndex {
case 0:
print("Current Tab")
panelOptimalAz.text = "Tracking the Sun"
case 1:
print("3 months Tab")
// do something related to 3 months
case 2:
print("6 months Tab")
// do something related to 6 months
case 3:
print("Year tab")
// do something related to Year
default:
panelOptimalAz.text = "No Optimal Azimuth given"
panelCurrentAz.text = "No Current Azimuth given"
panelCurrentTilt.text = "No Current Tilt given"
panelOptimalTilt.text = "No Optimal Tilt given"
}
}
//MARK: - viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
// Azimuth
if (CLLocationManager.headingAvailable()) {
locationManager.headingFilter = 1
locationManager.startUpdatingHeading()
}
// start the motion manager here, since we want it running all the time
if motionManager.isDeviceMotionAvailable {
motionManager.deviceMotionUpdateInterval = 0.1
motionManager.startDeviceMotionUpdates(to: OperationQueue()) {(motion, error) -> Void in
if let attitude = motion?.attitude {
DispatchQueue.main.async{
self.panelCurrentTilt.text = "\(String(format:"%.0f", attitude.pitch * 180 / Double.pi))º"
}
}
}
print("Device motion started")
}else {
print("Device motion unavailable")
}
// call segment changed to update on start (as if user tapped seg 0)
self.indexChanged(segmentedControl)
}
//MARK: - Motion methods
// no need for this
// func myDeviceMotion() -> String{
//
// var currentTilt:String = "0.0º"
//
// return currentTilt
//
// }
//MARK: - True heading and panel's heading
func locationManager(_ manager: CLLocationManager, didUpdateHeading heading: CLHeading) {
let trueHeading = heading.trueHeading
//If latitude >= 0, then panel's azimuth = 180º, else, it is 0º
var panelHeading = 0.0
// I don't have your GlobalData object, so
// just hard-coding 1.0 here...
// if GlobalData.latit >= 0.0{
if 1.0 >= 0.0 {
// only update Optimal Az label if "Current" seg is NOT selected
if self.segmentedControl.selectedSegmentIndex != 0 {
self.panelOptimalAz.text = "180º"
}
panelHeading = trueHeading - 180.0
if panelHeading < 0{
panelHeading += 360.0
}
self.panelCurrentAz.text = "\(String(format: "%.0f", panelHeading))º"
}else{
// only update Optimal Az label if "Current" seg is NOT selected
if self.segmentedControl.selectedSegmentIndex != 0 {
self.panelOptimalAz.text = "0º"
}
panelHeading = trueHeading + 180.0
if panelHeading > 359.0{
panelHeading -= 360.0
}
self.panelCurrentAz.text = "\(String(format: "%.0f", panelHeading))º"
}
}
}