Как динамически изменить значения в метках в SegmentedControl?Swift 4, iOS - PullRequest
0 голосов
/ 07 марта 2019

У меня есть некоторые проблемы с реализацией сегментированного элемента управления.Я прихожу к вам (более опытным людям), чтобы получить совет о том, что мне следует сделать, чтобы это исправить.А вот и я:

Для вкладки «Текущий» «Оптимальный азимут панели» и «Оптимальный угол наклона панели» должны быть «отслеживание солнца» (код, который я добавлю позже), другими словами:эти 2 поля должны обновляться в режиме реального времени (опять же, этот код я сделаю позже).«Текущий азимут панели» и «Текущий угол наклона панелей» в основном меняются в зависимости от положения телефона (я использую coreMotion и coreLocation, чтобы получить их).

Проблема заключается в следующем (изображения, добавленные после пояснения):

Для вкладки «текущий» поля «оптимальный азимут панели» и «оптимальный угол наклона панели» должны изменяться со временем.«Текущий угол наклона панели» должен отображаться с самого начала наклона панели (телефона), и он этого не делает (это происходит только при выборе другой вкладки).

Оптимальный угол наклона панели должен иметь фиксированное (но разное) значение для вкладок 3, 6 месяцев и года.Оптимальный азимут панели одинаков для вкладок 3, 6 месяцев и года (этот код я добавлю позже).Тем не менее, у меня возникают проблемы, когда я выбираю вкладку «Текущий», здесь «Оптимальный азимут панели» получает значение «отслеживание солнца», а когда я выбираю другую вкладку, это значение остается, когда оно должно сказать «180º».Это происходит только в том случае, если телефон все еще находится на поверхности, и как только я перемещаю его, в этом поле значение изменяется на 180º.Когда я перехожу с других вкладок на «текущую» вкладку, происходит обратное (вместо того, чтобы показывать «отслеживание солнца», оно показывает «180º», опять же, это значение появляется, когда телефон движется, но если телефон все еще работает), отслеживание"солнце").

По сути, единственное поле, которое правильно работает, это "Текущий азимут панели" на всех 4 вкладках сегментированного элемента управления.

Пожалуйста, обратитесь к изображениям, чтобы получитьлучшая идея.

Что я получу в начальном виде

Что я хочу в начальном виде

Что я получу, если телефон движется (это правильно для вкладок 3, 6 месяцев и года)

Что я получу, если телефон все еще работает, если я выбрал "текущий""вкладка, когда телефон был неподвижен, а затем я выбрал другую вкладку

То же, что и предыдущее изображение

Итак, у меня вопрос: что я могусделать, чтобы этого не допустить?Я попытался использовать оператор switch-case внутри @IBAction, соответствующего сегментированному элементу управления, но очевидно, что он не работает.Здесь я поделюсь с вами кодом, который я использовал для своего проекта:

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

        }

    }

}

}

Заранее спасибо за ваше время и ваш совет.

Привет.

1 Ответ

0 голосов
/ 07 марта 2019

резюмируя ...

OptimalAz на этикетке должно быть написано «Отслеживание Солнца» , если текущий выбранный сегмент - «Текущий», поэтому добавьте if () в didUpdateHeading только для обновления этого метка, когда выбраны другие сегменты.

Запустите диспетчер движений в 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))º"

        }

    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...