Комментарии 23
Позволю себе заметить, что в такой реализации о повороте экрана можно забыть: всё поедет. Поэтому нужно добавить необходимые констрейнты, а к тому же добавлять mainView не в окно, т.е.:
Тогда события смены ориентации будут приходить в mainView исправно. Кстати, весьма удобно вынести инициализацию UI в storyboard/xib и в синглтоне держать только указатель на view controller.
По статье в целом — неплохой туториал, много кому может пригодиться ;)
// вместо
[window addSubview:mainView];
// надо
UIView *view = [[window subviews] lastObject];
[view addSubview:mainView];
Тогда события смены ориентации будут приходить в mainView исправно. Кстати, весьма удобно вынести инициализацию UI в storyboard/xib и в синглтоне держать только указатель на view controller.
По статье в целом — неплохой туториал, много кому может пригодиться ;)
+3
Нет самого главного, свойства progress.
Если говорить про отрисовку, то вариантов масса. Я бы скорее всего отрисовал через CAShapeLayer, но если и использовать картинки, то здесь очевидно что можно использовать паттерн, который легко масштабирется и может быть любой длинны (UIColor colorWithPatternImage).
Если говорить об анимации, то не совсем понятно зачем столько блоков анимации фейдинга, когда с одними и теми же таймингами. И нет отмены анимаци, если необходимо перезапустить анимацию с другими параметрами, это когда дело дойдёт до конкретного использования данного класса.
И раз уж каждый раз создаются вьюшки после removeFromSuperview надо очищать переменную, которая ссылается на эту вьюшку.
Про стиль написания кода можно многое сказать, но всё же пару заметок:
— не надо использовать префикс k для констант и именование лучше делать по формуле ИмяКлассИмяКонстанты;
— не надо использовать define для констант, вместо этого: extern NSString *const BSBeautifulProgressBarManagerShowProgressBarNotification;
— приватные переменные _всегда_ реализовывать через свойства приватной категории;
— всегда использовать фигурные скобки в if, а то знаете что бывает (return return);
— флоат числа определять как флоат: 0.5f
Цель статьи какая?
Если говорить про отрисовку, то вариантов масса. Я бы скорее всего отрисовал через CAShapeLayer, но если и использовать картинки, то здесь очевидно что можно использовать паттерн, который легко масштабирется и может быть любой длинны (UIColor colorWithPatternImage).
Если говорить об анимации, то не совсем понятно зачем столько блоков анимации фейдинга, когда с одними и теми же таймингами. И нет отмены анимаци, если необходимо перезапустить анимацию с другими параметрами, это когда дело дойдёт до конкретного использования данного класса.
И раз уж каждый раз создаются вьюшки после removeFromSuperview надо очищать переменную, которая ссылается на эту вьюшку.
Про стиль написания кода можно многое сказать, но всё же пару заметок:
— не надо использовать префикс k для констант и именование лучше делать по формуле ИмяКлассИмяКонстанты;
— не надо использовать define для констант, вместо этого: extern NSString *const BSBeautifulProgressBarManagerShowProgressBarNotification;
— приватные переменные _всегда_ реализовывать через свойства приватной категории;
— всегда использовать фигурные скобки в if, а то знаете что бывает (return return);
— флоат числа определять как флоат: 0.5f
Цель статьи какая?
+4
1. Цель статьи — показать, что под капотом реально существующего проекта, да и некоторые вещи объяснить новичкам.
2. Про стиль написания кода можно очень (очень!) долго вести холивары, прошу от этого воздержаться.
3. Можно сделать очень многое и сильно улучшить этот код :) Спасибо за комментарии! Уверен, они помогут кому-нибудь улучшить наш подход.
2. Про стиль написания кода можно очень (очень!) долго вести холивары, прошу от этого воздержаться.
3. Можно сделать очень многое и сильно улучшить этот код :) Спасибо за комментарии! Уверен, они помогут кому-нибудь улучшить наш подход.
+1
Не стоит вопринимать слово стиль буквально, это уже давно намного больше чем просто выравние кода, хотя это тоже важно.
+1
Слушайте, ну как это может быть этот код реального проекта, когда это просто болванка, которая по нотификешену показывает 15 секундную анимацию?
+2
А как по Вашему работает progress bar при отправке imessage или sms? Обратите внимание, логика та же самая :)
0
Логика прогресс бара как раз не в том, чтобы показывать фейк 15 секунд, в результате которого пользователь может ничего не получить, а наоборот подтверить что работа идёт и он отображает данный прогресс. Для отправки SMS/iMessage используется несколько состояний прогресс бара:
1. Задачу менеджер отправки сообщений принял, определил в очередь и проверяет доступность сети/интернета.
2. Если связь есть, то в зависимость от типа связи соответствующие тайминги на прогресс отправки, но это не 100% прогресс бара.
3. Когда сообщение отправлено или связи нет включается финальная анимация завершения работы.
1. Задачу менеджер отправки сообщений принял, определил в очередь и проверяет доступность сети/интернета.
2. Если связь есть, то в зависимость от типа связи соответствующие тайминги на прогресс отправки, но это не 100% прогресс бара.
3. Когда сообщение отправлено или связи нет включается финальная анимация завершения работы.
+3
Т.е. когда мы через плохое соединение отправляем imessage и прогресс пробегает за 5 секунд, а потом еще секунд 20 висит почти в конце, это не фейк? Да, он не доходит до конца, но он не отображает реальный процесс отправки данных.
0
Думаю вы сами ответили на свой вопрос. В данной статье (предположим с плохим соединением) прогресс бар через 15 секунд покажет что задача выполнена 100%, но при этом экран полностью заблокирован. Такое приложение пользователи сочтут глюкавым и тормознутым. Вообще, не хорошо блокировать экран, когда можно выпонять задачу в параллельном потоке.
0
Сожалею, но Вы ошибаетесь. Чтобы закрыть прогресс бар, нужно вызвать у него метод hideProgressBar, и только тогда он добежит быстро до конца (если еще не добежал) и закроется. Если мы отправляем сообщение с плохим соединением, то прогресс бар закроется по окончанию отправки или по таймауту сети. Основная задача этого прогресс бара (так же как и при отправке смс) показать пользователю, что процесс отправки пошел, ему вовсе не нужно показывать реальное количество отправленных данных.
Блокировать экран не хорошо, с этим не поспоришь, это нужно просто дорабатывать/переделывать.
Блокировать экран не хорошо, с этим не поспоришь, это нужно просто дорабатывать/переделывать.
0
Кратенько напишу, что делает код выше:
1. Подписка на 2 нотификации: показать/скрыть прогресс бар, кстати нотификации абсолютно бесполезные, если мы говорим о синглтоне, в любом месте можно дёрнуть соотвествующий метод.
2. Показываем прогресс бар (showProgressBar)
2.1. Добавление затемнения и анимация 0.3 сек
2.2. Добавление белой плашки прогресс бара и анимация 0.3 сек
2.3. Добавление серого зипа к белой плашки
2.4. Добавление контейнера оранжего зипа и картинки оранжевого зипа (ох сколько вьюшек, хотя надо было использовать просто backgroundColor) и сразу же (!) анимация на 15 секунд.
3. Скрываем, если пришла нотификация
3.1 Анимация скрытия вьюшек за 0.3 сек (альфа и белая плашка вертикально)
И никаких быстренько потом добежать до конца нет.
1. Подписка на 2 нотификации: показать/скрыть прогресс бар, кстати нотификации абсолютно бесполезные, если мы говорим о синглтоне, в любом месте можно дёрнуть соотвествующий метод.
2. Показываем прогресс бар (showProgressBar)
2.1. Добавление затемнения и анимация 0.3 сек
2.2. Добавление белой плашки прогресс бара и анимация 0.3 сек
2.3. Добавление серого зипа к белой плашки
2.4. Добавление контейнера оранжего зипа и картинки оранжевого зипа (ох сколько вьюшек, хотя надо было использовать просто backgroundColor) и сразу же (!) анимация на 15 секунд.
3. Скрываем, если пришла нотификация
3.1 Анимация скрытия вьюшек за 0.3 сек (альфа и белая плашка вертикально)
И никаких быстренько потом добежать до конца нет.
0
Я понял о чем Вы говорите, да, нужно сделать чтобы прогресс не добегал до 100%, а останавливался на 90% примерно и ждал hideProgressBar, сейчас и правда выглядит не до конца понятно.
+1
Да, это — код социальной сети, написанной за 72 часа в рамках хакатона :)
+1
Чем вам константы не угодили? Это общепринятый подход к их именованию в ObjC.
+3
Год-два назад сам также именовал и всё ещё с ними работаю. Я всё понимаю, исторически сложилось. Но всё же это не в стиле Objective-C. В новых фрейворках iOS и в популярных open-source проектах видно что всё больше уходят от k префикса. А в итоге по работе скажу, что стало намного удобнее, когда сразу по имени класса начинаешь ввод и поиск константы. Если часто используете Open Quickly… (⇧⌘+O) то быстро можно привыкнуть к поиску констант без k.
-2
не надо использовать префикс k для констант и именование лучше делать по формуле ИмяКлассИмяКонстанты;
Я бы небыл столь категоричен в плане именования, в разных командах принято по разному и в этом ничего плохого нет.
не надо использовать define для констант, вместо этого: extern NSString *const BSBeautifulProgressBarManagerShowProgressBarNotification;
Да, вот с этим не поспоришь, так делать лучше
приватные переменные _всегда_ реализовывать через свойства приватной категории;
Здесь тоже нельзя быть категоричным, минус предложенного вами варианта — фейковая инкапсуляция, к такой проперти можно обратиться из вне. К переменной класса же(Помеченной как private) это сделать не на столько просто.
всегда использовать фигурные скобки в if, а то знаете что бывает (return return);
Это да, хорошая практика
флоат числа определять как флоат: 0.5f
Здесь тоже соглашусь
+1
1. k префикс и константа — я не настолько категоричен к префиксу k сколько к именованию константы. Например kShouldShowBeautifulProgressBar: не хорошо называть константы, которые начинаются как ShouldShow… Во первых это похоже больше на булеву переменную. Во вторых это внешняя константа, а в этом пространстве имён огромное количество других констант и в objective-c так называемый namespacing строится от 2-х, 3-х и т.д. буквенного префикса соответствующего проекта/модуля для соответствующих классов, протоколов, констант и т.д. Константы от класса соответственно строятся от имени класса и смысловой нагрузки константы. Поэтому и получаем такую длинную константу примерно такую:
Правило для именования констант, енумов и блоков простое: чем больше область видимости, тем больше контекстной/родительской состовляющей, т.е. если константа в области видимости всего класса или даже внешняя, то добавляем имя класса как префикс. Константы внутри метода достаточно просто по имени. Почти тоже самое для имён переменных и методов. Обратный пример, если переменная живёт в области видимости 2-3-х строк, тогда её можно назвать очень кратко:
Про k префикс это всё же рекомендация, будет проще и удобнее, поверьте. Но это по большей части рекомендация именно для objective-c.
2. Приватные переменные. Здесь мнительность совсем лишняя, что вообще-то можно всех обмануть и получить доступ к свойству. А важно это работа с ARC, KVO и многопоточностью. На WWDC неоднократно повторяют об использовании именно свойств через приватную категорию вместо приватных переменных.
BSBeautifulProgressBarManagerShowProgressBarNotification
.Правило для именования констант, енумов и блоков простое: чем больше область видимости, тем больше контекстной/родительской состовляющей, т.е. если константа в области видимости всего класса или даже внешняя, то добавляем имя класса как префикс. Константы внутри метода достаточно просто по имени. Почти тоже самое для имён переменных и методов. Обратный пример, если переменная живёт в области видимости 2-3-х строк, тогда её можно назвать очень кратко:
i, frame, view, hidden
и т.д.Про k префикс это всё же рекомендация, будет проще и удобнее, поверьте. Но это по большей части рекомендация именно для objective-c.
2. Приватные переменные. Здесь мнительность совсем лишняя, что вообще-то можно всех обмануть и получить доступ к свойству. А важно это работа с ARC, KVO и многопоточностью. На WWDC неоднократно повторяют об использовании именно свойств через приватную категорию вместо приватных переменных.
+1
это, про название переменных, вместо isShown использовать «visible» или «hidden»
+1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Делаем красивый Progress Bar в iOS приложении