0

我在实现分段控件时遇到了一些问题。我来找你(更有经验的人)就我应该做些什么来解决这个问题获得一些建议。我来啦:

对于“当前”选项卡,“面板的最佳方位角”和“面板的最佳倾斜角度”应该是“跟踪太阳”(我稍后会添加的代码),换句话说:这两个字段必须实时更新(再次,那个代码我稍后会做)。“面板当前方位角”和“面板当前倾斜角度”基本上会根据手机的位置而变化(我使用 coreMotion 和 coreLocation 来获取它们)。

问题是这样的(解释后添加的图像):

对于“当前”选项卡,“面板最佳方位角”和“面板最佳倾斜角度”字段必须随时间变化。“面板的当前倾斜角度”必须从一开始就显示面板(手机)的倾斜,它不这样做(只有在您选择另一个选项卡时才会这样做)。

“面板的最佳倾斜角度”对于 3、6 个月和“年”选项卡必须具有固定(但不同)的值。“面板的最佳方位角”对于 3、6 个月和“年”选项卡是相同的(我稍后也会添加该代码)。然而,当我选择“当前”选项卡时,我遇到了问题,在这里,“面板的最佳方位角”获得了“跟踪太阳”的值,当我选择另一个选项卡时,当它应该显示“180º”时,该值仍然存在。这只发生在手机仍在表面上时,只要我移动手机,该字段中的值就会变为 180º。当我从其他选项卡转到“当前”选项卡时会发生相反的情况(而不是显示“跟踪太阳”它显示“180º”,再次,当手机移动时会出现此值,

基本上,唯一正常工作的字段是分段控件中所有 4 个选项卡中的“面板的当前方位角”。

请参阅图像以获得更好的想法。

我在初始视图中得到的

我在初始视图中想要什么

如果手机在移动,我会得到什么(这对于 3、6 个月和年份标签是正确的)

如果手机静止,我会得到什么,如果我在手机静止时选择了“当前”选项卡,然后我选择了另一个选项卡

与上一张图片相同

所以,我的问题是:我能做些什么来防止这种情况发生?我尝试在与分段控件相对应的@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))º"

        }

    }

}

}

提前感谢您的时间和建议。

问候。

4

1 回答 1

0

重述...

OptimalAz如果当前选定的段是“当前”,则标签应显示“跟踪太阳” ,因此添加一个if ()indidUpdateHeading以仅在选择其他段时更新该标签。

启动运动管理器viewDidLoad()(与位置管理器一起)......它将继续运行 - 并继续更新标签 - 所以不需要myDeviceMotion()功能。

在结束时viewDidLoad(),触发indexChanged()初始化标签(以及任何其他需要的任务/变量),就好像用户点击了“当前”段一样。

试一试(我想我在代码中添加了足够的注释来解释任何更改):

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))º"

        }

    }

}
于 2019-03-07T14:02:18.447 回答