WKCrownSequencer не работает после возврата к главному контроллеру интерфейса

У меня есть WKCrownSequencer, который запускает действие в моем контроллере интерфейса, и в первый раз все работает нормально. Когда я возвращаюсь к корневому контроллеру интерфейса независимо от метода (pop или reloadRootcontrollers), цифровая корона больше не работает ни в первом контроллере интерфейса, ни во втором. StartInterfaceController - это rootInterfaceController, а MidWorkoutInterfaceController - заданный.

import WatchKit
import Foundation


class StartInterfaceController: 
WKInterfaceController,CLLocationManagerDelegate {

override func awake(withContext context: Any?) {
    super.awake(withContext: context)

    // Configure interface objects here.
}

override func willActivate() {
    // This method is called when watch view controller is about to be visible to user
    super.willActivate()
}

@IBAction func start() {

    WKInterfaceController.reloadRootControllers(
        withNames: ["midWorkout"], contexts: []
    )
}

Второй интерфейс контроллера находится ниже.

import WatchKit
import Foundation
class MidWorkoutInterfaceController: WKInterfaceController, WKCrownDelegate {

    override func awake(withContext context: Any?) {
        super.awake(withContext: context)
        print("viewdidAwake")
        print("ViewWillActivate")
        crownSequencer.delegate = self

        crownSequencer.focus()
        WKInterfaceDevice.current().play(.success)


        currentPhase = 0

        let workoutType = UserDefaults.standard.object(forKey: "CurrentType") as? [String] ?? [ "Swimming", "T1"]
        orderOfEventsSetter = workoutType
        updateCurrentPhase()
    }
    override func willActivate() {
        // This method is called when watch view controller is about to be visible to user
        super.willActivate()
        crownSequencer.focus()
    }

    var clockTimer: Timer!
    func workoutStarted(){
        clockTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] timer  in
            self?.totalTimeOutlet.setText( String(describing: -1 * Int(self!.startDate!.timeIntervalSinceNow)))
            self?.splitTimeOutlet.setText( String(describing: -1 * Int(self!.currentStartDate!.timeIntervalSinceNow)))
        }   
    }

    override func didDeactivate() {
        // This method is called when watch view controller is no longer visible
        super.didDeactivate()
    }


    var startDate: Date?
    var currentStartDate: Date?
    //Outlets

    @IBOutlet var currentPhaseOutlet: WKInterfaceLabel!
    @IBOutlet var totalTimeOutlet: WKInterfaceLabel!
    @IBOutlet var splitTimeOutlet: WKInterfaceLabel!
    @IBOutlet var currentPaceOutlet: WKInterfaceLabel!
    @IBOutlet var totalDistanceOutlet: WKInterfaceLabel!

    var orderOfEventsSetter: Array<String>{
        get{
            return orderOfEvents
        }
        set{
            var tempArray = ["GPS Locking In"]
            for phase in newValue {
                tempArray.append(phase)
            }
            orderOfEvents = tempArray
        }
    }

    private var orderOfEvents: [String] = []
    var currentPhase = 0 {
        didSet{
            if !orderOfEvents.isEmpty {
                updateCurrentPhase()
            }
        }
    }
    func updateCurrentPhase(){
        currentPhaseOutlet.setText(orderOfEvents[currentPhase])
    }

    //timing for location requests

    //Corelocation Section

    //CoreMotion Section

    ///crown control
    var currentDialRotation = 0.0
    let dialRotationRange =  Range(uncheckedBounds: (lower: -Double.pi / 4, upper: Double.pi / 4))
    let constantForTimer: TimeInterval = 0.1
    var justTransitioned = false

    func crownDidRotate(_ crownSequencer: WKCrownSequencer?, rotationalDelta: Double) {
        currentDialRotation += rotationalDelta
        if !dialRotationRange.contains(currentDialRotation){

            currentDialRotation = 0.0
            justTransitioned = true
            makeTransition()

            //make so two transitions cannot happen right after each other

        }
        print(currentDialRotation)
    }
    func crownDidBecomeIdle(_ crownSequencer: WKCrownSequencer?) {
        print(String(describing: orderOfEvents[currentPhase]))
        print("crown stopped")
    }

    func makeTransition(){

        print(currentPhase)
        print(orderOfEvents.count)
        if (currentPhase) == orderOfEvents.count - 1 {
            endWorkout()
        }
        else if (currentPhase == 0){
            WKInterfaceDevice.current().play(.start)
            let dateFormat = DateFormatter()
            dateFormat.dateFormat = "mm/dd/yyyy"
            startDate = Date()
            currentStartDate = Date()
            workoutStarted()
            currentPhase += 1
        }
        else{
            WKInterfaceDevice.current().play(.start)
            print("transitioning to " + String(describing: orderOfEvents[currentPhase + 1]))

            currentStartDate = Date()

            stopTimers()
            currentPhase += 1
        }
    }

    @IBAction func endWorkoutButton() {
        endWorkout()
    }
    func endWorkout(){
        stopTimers()
        clockTimer.invalidate()
        alerts()
    }

    func alerts(){
        let saveAction = WKAlertAction(title: "Save",
                                       style: WKAlertActionStyle.default) {

                                        self.goToStartScreen()
        }

        let discardAction = WKAlertAction(title: "Discard Workout",
                                          style: WKAlertActionStyle.cancel) {

                                            self.goToStartScreen()
        }
        presentAlert(withTitle: "Workout Complete",
                     message: "Would you like to save the workout?",
                     preferredStyle: WKAlertControllerStyle.alert,
                     actions: [saveAction, discardAction])
    }

    func goToStartScreen(){
        crownSequencer.resignFocus()

        self.popToRootController()
    }

    func stopTimers(){
        if orderOfEvents[currentPhase] == "Running"{
        }
        if orderOfEvents[currentPhase] == "Biking"{
        }
        if currentPhase == orderOfEvents.count {
            clockTimer.invalidate()
        }
    }
}

0 ответов

Согласно документу Apple здесь:

"... Только один объект в вашем интерфейсе может иметь фокус в любой момент времени, поэтому, если ваш интерфейс также содержит объекты выбора или имеет прокручиваемые сцены, вы должны соответствующим образом координировать изменения в фокусе. Например, вызов метода фокуса секвенсора вызывает любое средство выбора объекты или контроллеры интерфейса для снятия фокуса. Когда пользователь нажимает на объект средства выбора, текущий активный секвенсор снимает фокус, и выбранный объект средства выбора получает фокус... "

И вы потеряете фокус в любой момент непредсказуемо...

"... Если пользователь касается объекта выбора или прокручиваемой сцены в вашем интерфейсе, система автоматически удаляет фокус с любого активного секвенсора короны..."

Другие вопросы по тегам