Есть ли индикатор активности в WatchKit для Apple Watch?

Есть ли индикатор активности (или что-то подобное) в WatchKit для Apple Watch? Как вы все даете отзывы пользователей о какой-то более продолжительной фоновой активности?


person stk    schedule 06.03.2015    source источник
comment
Честно говоря, после прочтения документации и руководств Apple, если вам нужен индикатор активности или индикатор выполнения, то все, что вы пытаетесь сделать, не подходит для Apple Watch. Apple прямо говорит, что разработчики могут ожидать, что взаимодействие с приложениями для часов будет происходить за секунды [не минуты]. Взаимодействия быстрые. Пользователь не должен ждать больше секунды, пока что-то загрузится.   -  person Sam Spencer    schedule 08.03.2015
comment
В теории это звучит хорошо, но при получении данных по сети вы не можете гарантировать, что все будет готово за 1 секунду. Интерфейс WatchKit ничего не делает, когда я загружаю свой JSON с помощью Alamofire. Пользователь видит только черный экран часов и думает, что приложение сломано. Что бы вы сделали, чтобы исправить это?   -  person stk    schedule 08.03.2015
comment
Проверьте мой ответ для более подробной информации об этом. Надеемся, что в следующей версии WATCH вы сможете выполнять эти задачи прямо на устройстве.   -  person Sam Spencer    schedule 08.03.2015
comment
Вы также можете сделать что-то подобное, но, как многие предлагали, лучше этого не делать. youtube.com/watch?feature=player_embedded&v=_8YVt7V1mAA   -  person Jay Mayu    schedule 24.08.2016


Ответы (8)


Изменить: Этот ответ изначально был опубликован до появления моделей Apple Watch с возможностью подключения к сотовой сети и Wi-Fi, поэтому он больше не может применяться к более новым моделям устройства. (учитывая значительное повышение производительности).


В этой ветке на форумах разработчиков Apple есть авторитетный ответ от инженера Apple о почему вам не следует выполнять сетевые операции с Apple Watch.

Есть две серьезные причины не выполнять сетевые операции из вашего приложения/расширения для часов:

  1. #P4# <блочная цитата> #P5#
  2. #P6# <блочная цитата> #P7# #P8#

Что, как говорится. Если вам действительно нужен UIActivityIndicator, rdar://19363748 (я не думаю, что этот индикатор еще не был открыт), разработчики уже подали запросы на официальную поддержку.

Вы можете создать серию изображений в выбранном вами стиле индикатора активности, а затем анимировать их с помощью startAnimatingWithImagesInRange:duration:repeatCount: API. См. приложение Apple Lister для примера анимации wkinterfaceimage.

Кроме того, здесь можно найти Учебник WatchKit Animation и включают графику "spinner".

person Sam Spencer    schedule 08.03.2015
comment
+1, потому что 2) совершенно новое для меня. Ну, я прочитал ветку, и они говорят о CloudKit. Инженер Apple также добавляет ключевое слово «сложная сеть». Я не думаю, что JSON через HTTP — это сложная сеть. Но в любом случае, я вижу смысл и должен позволить этому усвоиться. - person stk; 08.03.2015
comment
Apple-guy говорит, что вы должны выполнять любой сетевой запрос, запуская основное приложение в фоновом режиме, то есть не выполняя фактический сетевой код в своем приложении-расширении. Это связано с тем, что расширение watchkit (может) работать только тогда, когда приложение открыто на часах. С учетом сказанного это не означает, что приложение watchkit не может инициировать запрос, который происходит асинхронно где-то еще — счетчик — это один из способов показать, что что-то происходит, если разработчик хочет проиллюстрировать это таким образом. - person jake_hetfield; 15.04.2015
comment
На часах есть индикатор активности. Мое приложение выполняет асинхронные фоновые сетевые операции из сопутствующего приложения, и, если сеть работает медленно, это может занять некоторое время. Неважно, где происходит сетевая активность, было бы неплохо иметь возможность показать пользователю, что она происходит. На часах уже есть индикатор, поэтому было бы пустой тратой драгоценных (ограниченных) ресурсов загружать в часы последовательность изображений для чего-то, что уже существует в их бортовой системе, и это также представляло бы более последовательный опыт для пользователя. - person Bill Weinman; 21.04.2015
comment
Спасибо за ссылку на гифку со спиннером - person Almas Adilbek; 26.06.2015

Просто чтобы добавить к опциям, я создал проект JBWatchActivityIndicator на GitHub, который позволяет вам создавать свои собственные последовательности изображений: https://github.com/mikeswanson/JBWatchActivityIndicator

Он также включает в себя анимацию индикатора активности в стиле Apple, если вы не хотите создавать свои собственные.

person Mike Swanson    schedule 08.05.2015

Я создал простой индикатор активности для Apple Watch, доступный здесь https://github.com/tijoinc/WatchActivityIndicator

person Tim Johnsen    schedule 25.09.2015

В WatchKit Framework нет метода отображения ActivityIndicator. Однако вы можете подготовить некоторое круглое изображение и легко создать бесконечную анимацию самостоятельно. Подготовьте изображения и назовите их так frame-0, frame-1, frame-2...frame-n

а затем в вашем коде:

    [self.yourInterfaceImage setImageNamed:@"firstFrame-"]; //setting first frame
    [self.yourInterfaceImage startAnimatingWithImagesInRange:[self.model imageRange]
                                               duration:0.4
                                            repeatCount:0];
    // [self.model imageRange] will return NSRange from 0 to n
    // repeatCount == 0 means infinity. Of course you can set some limit, like 100.

Надеюсь это поможет.

person lvp    schedule 07.03.2015
comment
По сути, я ищу стандартный циркулирующий ActivityIndicator, который WatchKit использует при запуске нового ViewController. Если кто-то сможет доставить именно это как код копирования + вставки, он получит мой принятый ответ. :) - person stk; 08.03.2015
comment
Взгляните на мой ответ, это именно то, что мне нужно. +1 за половину ответа. - person stk; 08.03.2015
comment
Но если я упомяну то же имя, что и firstFrame- в setImageNamed. Это дает мне сообщение об ошибке, говорящее о невозможности найти имя изображения. Требуются ли для этого какие-либо изменения в конфигурации?? - person Hussain Shabbir; 06.04.2015

Я сделал его похожим на индикатор watchOS с помощью swiftUI.

введите здесь описание изображения

import SwiftUI

struct ActivityIndicatorView: View {

    // MARK: - Value
    // MARK: Public
    @Binding var isAnimating: Bool


    // MARK: Private
    private let radius: CGFloat = 24.0
    private let count = 18
    private let interval: TimeInterval = 0.1

    private let point = { (index: Int, count: Int, radius: CGFloat, frame: CGRect) -> CGPoint in
        let angle   = 2.0 * .pi / Double(count) * Double(index)
        let circleX = radius * cos(CGFloat(angle))
        let circleY = radius * sin(CGFloat(angle))

       return CGPoint(x: circleX + frame.midX, y: circleY + frame.midY)
   }

   private let timer = Timer.publish(every: 1.8, on: .main, in: .common).autoconnect()     // every(1.8) = count(18) / interval(0.1)

   @State private var scale: CGFloat  = 0
   @State private var opacity: Double = 0

   // MARK: - View
   var body: some View {
       GeometryReader { geometry in
            ForEach(0..<self.count) { index in
                Circle()
                    .fill(Color.white)
                    .frame(width: 3.0, height: 3.0)
                    .animation(nil)
                    .opacity(self.opacity)
                    .scaleEffect(self.scale)
                    .position(self.point(index, self.count, self.radius, geometry.frame(in: .local)))
                    .animation(
                        Animation.easeOut(duration: 1.0)
                            .repeatCount(1, autoreverses: true)
                            .delay(TimeInterval(index) * self.interval)
                     )
             }
             .onReceive(self.timer) { output in
                self.update()
             }
        }
        .rotationEffect(.degrees(10.0))
        .opacity(isAnimating == false ? 0 : 1.0)
        .onAppear {
            self.update()
        }
    }



    // MARK: - Function
    // MARK: Private
    private func update() {
        scale   = 0 < scale ? 0 : 1.0
        opacity = 0 < opacity ? 0 : 1.0

        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            self.scale   = 0
            self.opacity = 0
        }
    }
}

#if DEBUG
struct ActivityIndicatorView_Previews: PreviewProvider {

    static var previews: some View {
        let view = ActivityIndicatorView(isAnimating: .constant(true))

        return Group {
             view
                 .previewDevice("Apple Watch Series 5 - 44mm")

             view
                 .previewDevice("Apple Watch Series 4 - 40mm")

             view
                 .previewDevice("Apple Watch Series 3 - 42mm")

             view
                 .previewDevice("Apple Watch Series 3 - 38mm")
         }
     }
 }
 #endif
person Den    schedule 11.06.2020

На мой взгляд, попытка создать свой собственный Spinner использует чрезмерные ресурсы. Если бы Apple подумала, что это хорошая идея, они бы предложили ее.

Вместо этого я бы просто получил изображение, для которого вы настраиваете альфа-канал. Используйте логическое значение, чтобы узнать, следует ли добавлять или вычитать альфу.

if (add)
    {
        count=count+5;
        if (count==100)
        {
            add=false;
        }
    }
    else
    {
        count=count-5;
        if (count==0)
        {
            add=true;
        }
    }

    float thealpha=((float)count/100);
    [self.scanb setAlpha:thealpha];

}

person Belboz    schedule 28.08.2015

На случай, если кто-то еще его ищет, у SwiftUI есть встроенное решение: ProgressView()

person Philip    schedule 15.03.2021

Вот простой текстовый индикатор, в котором используется атрибут @State:

struct MyView: View {
    private let loaderSpeed = 0.1 // seconds per state
    private let loaderStates = [
        "•       ",
        " •      ",
        "  •     ",
        "   •    ",
        "    •   ",
        "     •  ",
        "      • ",
        "       •",
        "      • ",
        "     •  ",
        "    •   ",
        "   •    ",
        "  •     ",
        " •      ",
    ]
    @State private var loaderMessage = ""
    @State private var loaderState = 0 {
        didSet {
            if self.loaderState > 0 {
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + self.loaderSpeed) {
                    if self.loaderState > 0 {
                        self.loaderMessage = self.loaderStates[self.loaderState-1]
                        if self.loaderState >= self.loaderStates.count {
                             self.loaderState = 1
                        } else {
                            self.loaderState += 1
                        }
                    }
                }

            }
        }
    }

    var body: some View {
        HStack() {
            Spacer()
            Text("Loading:")
            Text(loaderMessage).onAppear { self.loaderState = 1 }
            Spacer()
        }
    }
}

установить loaderState = 1 для запуска загрузчика

установите loaderState = 0, чтобы остановить загрузчик

person T. Christiansen    schedule 07.02.2020