Создание круга прогресса как WKInterfaceImage в приложении Watch

Я пытаюсь создать круг прогресса для версии моего приложения для Apple Watch. Я знаю, что мы не можем использовать UIViews (что значительно упростит задачу!), поэтому я ищу альтернативы.

В принципе, я хотел бы создать один из этих прототипов:

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

Я надеялся добавить фоновые слои в виде обычного WKInterfaceImage, а затем стрелку/линию прогресса вверху в виде WKInterfaceImage, который вращается по кругу в зависимости от рассчитанного процента.

У меня рассчитан процент, поэтому в основном я ищу помощь с математическим кодом для вращения стрелки.

Кто-нибудь знает, возможно ли это, и может ли кто-нибудь помочь мне, если да? Я не пытаюсь обновить круг во время работы приложения; его просто нужно обновить при запуске приложения Watch, чтобы оно соответствовало версии iOS.

Спасибо!


person user3746428    schedule 22.11.2014    source источник
comment
Какая у тебя проблема с математикой? Полный круг имеет 360 градусов, поэтому градусы для 19% рассчитываются как degrees = 360.0 * 19.0 / 100.0.   -  person zisoft    schedule 22.11.2014
comment
Я больше имел в виду, попытаюсь ли я повернуть изображение по кругу, если оно не находится в центре круга. Но я полагаю, что было бы проще центрировать его по кругу, чтобы я мог просто использовать предложенный вами расчет.   -  person user3746428    schedule 22.11.2014


Ответы (6)


Начиная с watchOS 3 можно использовать SpriteKit.

SKShapeNode может рисовать фигуры, поэтому можно создавать радиальные кольца.

  1. Добавьте WKInterfaceSKScene к контроллеру интерфейса в раскадровке и подключите его через розетку.
  2. Настройте его в бодрствующем методе контроллера интерфейса.

    override func awake(withContext context: Any?) {
       super.awake(withContext: context)
       scene = SKScene(size: CGSize(width: 100, height: 100))
       scene.scaleMode = .aspectFit
       interfaceScene.presentScene(scene)
    }
    
  3. Создайте узел формы и добавьте его на сцену.

    let fraction: CGFloat = 0.75
    let path = UIBezierPath(arcCenter: .zero,
                             radius: 50,
                             startAngle: 0,
                             endAngle: 2 * .pi * fraction,
                             clockwise: true).cgPath
    
    let shapeNode = SKShapeNode(path: path)
    shapeNode.strokeColor = .blue
    shapeNode.fillColor = .clear
    shapeNode.lineWidth = 4
    shapeNode.lineCap = .round
    shapeNode.position = CGPoint(x: scene.size.width / 2, y: scene.size.height / 2)
    scene.addChild(shapeNode)
    

Пример

person AKM    schedule 01.08.2017
comment
Не забудьте импортировать SpriteKit - person JoeGalind; 29.12.2018
comment
Я обнаружил, что даже на Apple Watch Series 4 для отображения SKScene требуется секунда или две. Это раздражающая задержка, из-за которой я, к сожалению, не хочу использовать эту технику, хотя я бы предпочел сделать это таким образом, чем последовательность изображений для анимации. - person Tap Forms; 02.03.2019
comment
О, и просто чтобы уточнить, это только первый раз, когда большая задержка в работе. Я предполагаю, что часы загружают структуру SpriteKit. - person Tap Forms; 02.03.2019

Другое решение — создать 100 картинок, для каждой цифры у вас есть рамка. Таким образом, вы можете показать анимацию, используя метод startAnimatingWithImagesInRange:duration:repeatCount.

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

Генератор радиальных гистограмм

Эта ссылка должна помочь вам настроить фреймы: http://hmaidasani.github.io/RadialChartImageGenerator/

Также у вас есть те же образцы по ссылке git. Для 100 кадров с одним дуговым кадром вы получаете около 1,8 МБ на диске.

person Duduman Bogdan Vlad    schedule 19.02.2015

Большая часть того, что доступно на iOS, отсутствует (пока) в WatchKit. В частности, некоторые вещи, которые вы хотите сделать, почти невозможны. (Проблеск надежды через мгновение). В частности, вы не можете вращать изображение. Точнее, вы можете повернуть изображение, но вы должны сделать это на телефоне, а затем передать это изображение на часы во время выполнения. Кроме того, вы не можете легко скомпоновать изображения, однако есть способ сделать это.

Одним из способов было бы создать все повернутое составное изображение так, как вы хотите, на телефоне и передать окончательные данные на кнопку, используя [WKInterfaceButton setBackgroundImage:]. К сожалению, вы, скорее всего, обнаружите, что это работает медленно в симуляторе, и, скорее всего, это будет плохо работать на реальных часах. Трудно сказать наверняка, потому что у нас его нет, но это отправляет изображение на лету через Bluetooth. Таким образом, вы не получите плавной анимации или хорошего времени отклика.

Лучший способ — взломать его на часах. Это основано на двух хитростях: во-первых, наложение групп вместе с фоновыми изображениями. Во-вторых, используя -[WKInterfaceImage startAnimatingWithImagesInRange:duration:repeatCount:].

Для первого трюка поместите группу в свой макет, затем поместите в нее другую группу, а затем (возможно) кнопку внутри нее. Затем используйте -[WKInterfaceGroup setBackgroundImage:] и изображения будут объединены вместе. Убедитесь, что вы используете правильную прозрачность и т. д.

Для второго трюка обратитесь к официальной документации — по сути, вам понадобится серия изображений, по одному для каждого возможного значения поворота, как сказал erdekhayser. Теперь это может показаться вопиющим (это так) и, возможно, непрактичным (это не так). Именно так Apple рекомендует создавать спиннеры и тому подобное — по крайней мере, на данный момент. И, да, это может означать создание 360 различных изображений, хотя из-за маленького экрана я советую проходить через каждые 3-5 градусов или около того (никто не сможет заметить разницу).

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

person Adam    schedule 24.11.2014

Никто не выкладывает код??? Вот! наслаждаться:

1) Создайте изображения здесь: http://hmaidasani.github.io/RadialChartImageGenerator/

2) Перетащите средство выбора в свой контроллер просмотра и свяжите его с каким-либо файлом viewController.swift. Установите стиль Picker на «Последовательность» в меню, которое появляется справа.

3) Добавьте этот код в viewController.swift и подключите средство выбора к IBOutlet и IBAction:

import WatchKit
import Foundation

class PickerViewController: WKInterfaceController {

    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)
    }

    @IBOutlet var itemPicker: WKInterfacePicker!

    override func willActivate() {
        super.willActivate()

        let pickerItems: [WKPickerItem] = (0...100).map {
            let pickerItem = WKPickerItem()
            pickerItem.contentImage = WKImage(imageName: "singleArc\($0).png")
            return pickerItem
        }
        itemPicker.setItems(pickerItems)
    }

    @IBAction func pickerSelectedItemChanged(value: Int) {
        NSLog("Sequence Picker: \(value) selected.")
    }

    override func didDeactivate() {
        super.didDeactivate()
    }

}
person Josh    schedule 09.02.2016

Классы WKInterface не могут быть подклассами. Поэтому пользовательский контроль невозможен.

Кроме того, анимация ограничена. Чтобы создать анимацию, вы должны сохранить каждый кадр как изображение. Затем вы можете иметь представление изображения в своем приложении WatchKit, которое циклически перебирает эти изображения.

Сохраните изображения в папке Images.xcassets в целевом объекте просмотра и попробуйте изменить кадр в зависимости от процента завершения действия.

Еще одно замечание: иметь 100 изображений было бы неэффективно, так как каждое приложение WatchKit имеет ограниченное количество места на часах, которое оно может занимать (я думаю, что это 20 МБ, но я не уверен). Может быть, есть изображение для каждых 5%.

person erdekhayser    schedule 22.11.2014
comment
Спасибо за ответ. Я не совсем ясно выразился, но я намеревался повернуть один WKInterfaceImage стрелки на 360 градусов. Итак, если есть способ поворачивать изображения в коде, тогда это должно работать? У меня не было планов анимировать изображение, так что все в порядке. Пока он может поворачиваться в правильное положение при запуске приложения, это то, что я хотел бы, чтобы он делал. Кроме того, я думаю, что предел памяти составляет 20 МБ. - person user3746428; 22.11.2014
comment
@user3746428 user3746428 Вы не можете повернуть WKInterfaceImage. Вы можете повернуть UIImage в расширении и отправить его, или, что еще лучше, предварительно сгенерировать все кадры, сохранить их в комплекте приложений для часов и отправлять обновления. - person Jano; 07.02.2015

Нет, невозможно создать этот пользовательский круг в наборе часов, потому что UIView не работает в комплекте часов.

есть единственное решение вашей проблемы - вы должны поместить 100 изображений каждого кадра... и убедитесь, что размер изображений меньше 20 МБ. потому что размер часового приложения до 20 МБ

person Nikunj Godhani    schedule 13.05.2015