Точно помню, что где-то видел такой пример, где в таблице показываются все доступные шрифты в iOS. Искать было лень, а написать пример отображения всех шрифтов заняло думаю меньше времени, чем написание этого поста.
Пример можно скачать.
Работает все просто. У класса UIFont есть методы familyNames: и fontNamesForFamilyName:. Первый возвращает массив имен семейств шрифтов в системе, а второй массив имен шрифтов по семейству шрифта.
11 декабря 2010 г.
6 декабря 2010 г.
SVN добавление файла в репозиторий с "@" в имени
Столкнулся с проблемой добавления файла в svn репозиторий:
решается просто, нужно добавить как завершающий символ в названии файла "@":
- $ svn add ./file\@2x.png
- svn: warning: 'file' not found
решается просто, нужно добавить как завершающий символ в названии файла "@":
- $ svn add ./file\@2x.png@
- A (bin) file@2x.png
3 декабря 2010 г.
2 декабря 2010 г.
Поддержка Retina-display в приложении
С выходом iPhone 4 программистам нужно в своих программах добавлять поддержку нового разрешения экрана Retina. Для поддержки этого разрешения в вашем приложении необходимо выполнить следующие условия:
- Перерисовать все изображения которые вы используете в качестве ресурсов
- Добавить иконку приложения в высоком разрешении
- Если вы используете векторную графику фраемворков Core Graphics или UIKit, то можете улучшить детализацию, смотри “Updating Your Custom Drawing Code”
- Если вы используете Core Animation, то возможно вам понадобится изменить параметры маштабирования перед отрисовкой слоев “Accounting for Scale Factors in Core Animation Layers.”
- Если вы используете Open GL ES для рисования, то для отрисовки в высоком разрешении вам понадобится маштабирование вашего слоя, как описано в “Drawing High-Resolution Content Using OpenGL ES.”
- Если вы создаете изображения программно, то понадобится изменить код создания изображения, как описано в “Creating High-Resolution Bitmap Images Programmatically.”
Для начала опишу первые два способа.
Допустим у вас уже есть изображения оптимизированные под стандартное разрешение и под retina-display. Как же нам из программы узнать какое изображение загрузить? Ответ прост: программисту можно не знать на каком устройстве запущенно приложение. iOS может может сама выбрать нужное изображение в зависимости от устройства, на котором запущенна программа. Изображение только нужно назвать в соответствии с форматом:
- для стандартного резрешения iPhone/iPod Touch файл ресурса изображения должен иметь вид: <ImageName><device_modifier>.<filename_extension>
- для высокого (retina) разрешения: <ImageName>@2x<device_modifier>.<filename_extension>
где, ImageName - имя изображения, filename_extension - расширение, device_modifier - необязательный параметр, который указывает тип устройства для которого сделан ресурс (может быть "~iphone" и "~ipad").
Так например, если у вас ресурс для стандартного разрешения iPhone называется "image.png", то для iPhone 4 должен быть ресурс под названием "image@2x.png", если iOS его не находит, то берется ресурс для стандартного разрешения ("image.png").
так, читаем ресурс:
кстати, с прошивки iOS 4.0, расширение ресурса (".png") можно не указывать, но я советую оставлять для совместимости с iPhoneOS 3.x.
Теперь о иконках приложения
С версии iOS 3.2 в файле Info.plist приложения появилась возможность задавать массив файлов иконок приложения в параметре CFBundleIconFiles (не путайте с CFBundleIconFile). В этом массиве можно перечислить список файлов иконок с разным разрешением, и система сама подберет оптимальную иконку для устройства на котором запущено приложение.
Список разрешений иконок приложения:
По материалам "Supporting High-Resolution Screens"
- Перерисовать все изображения которые вы используете в качестве ресурсов
- Добавить иконку приложения в высоком разрешении
- Если вы используете векторную графику фраемворков Core Graphics или UIKit, то можете улучшить детализацию, смотри “Updating Your Custom Drawing Code”
- Если вы используете Core Animation, то возможно вам понадобится изменить параметры маштабирования перед отрисовкой слоев “Accounting for Scale Factors in Core Animation Layers.”
- Если вы используете Open GL ES для рисования, то для отрисовки в высоком разрешении вам понадобится маштабирование вашего слоя, как описано в “Drawing High-Resolution Content Using OpenGL ES.”
- Если вы создаете изображения программно, то понадобится изменить код создания изображения, как описано в “Creating High-Resolution Bitmap Images Programmatically.”
Для начала опишу первые два способа.
Допустим у вас уже есть изображения оптимизированные под стандартное разрешение и под retina-display. Как же нам из программы узнать какое изображение загрузить? Ответ прост: программисту можно не знать на каком устройстве запущенно приложение. iOS может может сама выбрать нужное изображение в зависимости от устройства, на котором запущенна программа. Изображение только нужно назвать в соответствии с форматом:
- для стандартного резрешения iPhone/iPod Touch файл ресурса изображения должен иметь вид: <ImageName><device_modifier>.<filename_extension>
- для высокого (retina) разрешения: <ImageName>@2x<device_modifier>.<filename_extension>
где, ImageName - имя изображения, filename_extension - расширение, device_modifier - необязательный параметр, который указывает тип устройства для которого сделан ресурс (может быть "~iphone" и "~ipad").
Так например, если у вас ресурс для стандартного разрешения iPhone называется "image.png", то для iPhone 4 должен быть ресурс под названием "image@2x.png", если iOS его не находит, то берется ресурс для стандартного разрешения ("image.png").
так, читаем ресурс:
- UIImage* anImage = [UIImage imageNamed:@"image.png"];
кстати, с прошивки iOS 4.0, расширение ресурса (".png") можно не указывать, но я советую оставлять для совместимости с iPhoneOS 3.x.
Теперь о иконках приложения
С версии iOS 3.2 в файле Info.plist приложения появилась возможность задавать массив файлов иконок приложения в параметре CFBundleIconFiles (не путайте с CFBundleIconFile). В этом массиве можно перечислить список файлов иконок с разным разрешением, и система сама подберет оптимальную иконку для устройства на котором запущено приложение.
Список разрешений иконок приложения:
| 57х57 | иконка для iPhone и iPod Touch стандартного разрешения экрана |
| 114х114 (@2x) | иконка для iPhone и iPod Touch с retina экраном |
| 72х72 | iPad иконка |
| 29х29 | иконка для iPhone и iPod Touch стандартного разрешения экрана, которая отображается в приложении Settings и при поиске |
| 58х58 (@2x) | иконка для iPhone и iPod Touch с retina экраном, которая отображается в приложении Settings и при поиске |
| 50х50 | iPad иконка приложения в результатах поиска |
По материалам "Supporting High-Resolution Screens"
28 ноября 2010 г.
Кастомные заголовки и подписи в секциях UITableView
Иногда необходимо что б в заголовке секции таблицы UITableView отображался не только текст, но и картинка, или может даже кнопка. Компонента UITableView позволяет не только задавать текстовую строку как заголовок к каждой секции но и устанавливать свое UIView как элемент заголовка.
UITableView поддерживает отсылку событий по двум протоколам UITableViewDataSource и UITableViewDelegate. Первый отвечает за получение данных которые отображаются в компоненте, второй за их внешний вид. В протоколе UITableViewDataSource есть методы – tableView:titleForHeaderInSection: и – tableView:titleForFooterInSection: которые должны возвращать строки заголовка и подписи для каждой секции в таблице. Но в протоколе UITableViewDelegate можно реализовать методы – tableView:viewForHeaderInSection: и – tableView:heightForHeaderInSection: для установки вашего вью на заголовок секции (методы – tableView:viewForFooterInSection: и – tableView:heightForFooterInSection: для подписи секции)
Реализуем простой пример использования (скачать можно отсюда)
У нас есть UIViewController на котором находится UITableView. Создаем вью которое будем использовать как заголовок секции таблицы.
тут headerView - имеет тип UIView, его то мы и будем отображать в таблице.
А теперь опишем функции отображение этого вью как заголовка первой секции таблицы:
В первой функции мы возвращаем вью которое должно отображаться в таблице, во второй - высоту этого вью.
Так-же в компоненте UITableView можно использовать свойства tableHeaderView и tableFooterView для задания вью как заголовка и подписи всей таблицы.
UITableView поддерживает отсылку событий по двум протоколам UITableViewDataSource и UITableViewDelegate. Первый отвечает за получение данных которые отображаются в компоненте, второй за их внешний вид. В протоколе UITableViewDataSource есть методы – tableView:titleForHeaderInSection: и – tableView:titleForFooterInSection: которые должны возвращать строки заголовка и подписи для каждой секции в таблице. Но в протоколе UITableViewDelegate можно реализовать методы – tableView:viewForHeaderInSection: и – tableView:heightForHeaderInSection: для установки вашего вью на заголовок секции (методы – tableView:viewForFooterInSection: и – tableView:heightForFooterInSection: для подписи секции)
Реализуем простой пример использования (скачать можно отсюда)
У нас есть UIViewController на котором находится UITableView. Создаем вью которое будем использовать как заголовок секции таблицы.
- CGRect rct;
- headerView = [[UIView alloc] initWithFrame:CGRectZero];
- UIImage *img = [UIImage imageNamed:@"apple.png"];
- UIImageView *tmpImgView = [[UIImageView alloc] initWithImage:img];
- rct = CGRectMake(screenRect.size.width*.05, 0.0, img.size.width, img.size.height);
- tmpImgView.frame = rct;
- [headerView addSubview:tmpImgView];
- rct.origin.x = 0.0;
- rct.size = CGSizeMake(screenRect.size.width, rct.size.height);
- headerView.frame = rct;
- [tmpImgView release];
тут headerView - имеет тип UIView, его то мы и будем отображать в таблице.
А теперь опишем функции отображение этого вью как заголовка первой секции таблицы:
- - (UIView *) tableView:(UITableView *) tableView viewForHeaderInSection:(NSInteger) section
- {
- if (section==0)
- {
- return headerView;
- }
- return nil;
- }
- - (CGFloat) tableView:(UITableView *) tableView heightForHeaderInSection:(NSInteger) section
- {
- if (section==0)
- {
- return headerView.frame.size.height;
- }
- return 0.0;
- }
В первой функции мы возвращаем вью которое должно отображаться в таблице, во второй - высоту этого вью.
Так-же в компоненте UITableView можно использовать свойства tableHeaderView и tableFooterView для задания вью как заголовка и подписи всей таблицы.
20 ноября 2010 г.
Изменение шрифта в компоненте UISegmentedControl
Если вам не хватает стандартных стилей компоненты UISegmentedControl, то изменение шрифта надписей, это то место, которое не описано в iOS Reference Library. Код для изменения шрифта в компоненте UISegmentedControl взят с форума www.iphonedevsdk.com:
параметром этой функции и есть экземпляр обьекта UISegmentedControl.
- void changeUISegmentFont(UIView* aView)
- {
- NSString* typeName = [[aView class] className];
- if ([typeName compare:@"UISegmentLabel" options:NSLiteralSearch] == NSOrderedSame)
- {
- UILabel* label = (UILabel*)aView;
- [label setTextAlignment:UITextAlignmentCenter];
- [label setFont:[UIFont boldSystemFontOfSize:14]];
- }
- NSArray* subs = [aView subviews];
- NSEnumerator* iter = [subs objectEnumerator];
- UIView* subView;
- while (subView = [iter nextObject])
- {
- changeUISegmentFont(subView);
- }
- }
параметром этой функции и есть экземпляр обьекта UISegmentedControl.
16 ноября 2010 г.
Пишем бота для twitter на python
Нашел все-таки время разобраться с OAuth авторизацией. Этот позволяет социальным сервисам интегрироваться между собой обеспечивая безопасный метод обмена информацией. Для интересующихся еще ссылка.
Приступим к написанию бота. Первое, что необходимо сделать - зарегистрировать приложение на сервисе twitter. В результате получаем Consumer key и Consumer secret.

Теперь разберем сам скрипт. Он написан на основе библиотеки oauth-python-twitter2, задача: фолловить и анфолловить случайных пользователей. Скрипт можно скачать здесь.
самое интересное в скрипте, метод auth. В файле /tmp/twitter.tmp я храню токен авторизации пользователя. Если этот токен не существует или не принимается пользователем, то вывожу на экран урл авторизации и жду пока пользователь авторизуеться в твиттере и введет PIN в приложение. По этому пину и получаем токен авторизации который и сохраняем в файл /tmp/twitter.tmp до следующего запуска скрипта.
Методы follow вызывает метод search твиттера и фолловит найденых пользователей. Метод unfollow берет список фолловеров и отписываеться от некоторых из них.
Приступим к написанию бота. Первое, что необходимо сделать - зарегистрировать приложение на сервисе twitter. В результате получаем Consumer key и Consumer secret.

Теперь разберем сам скрипт. Он написан на основе библиотеки oauth-python-twitter2, задача: фолловить и анфолловить случайных пользователей. Скрипт можно скачать здесь.
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- from oauth import oauth
- from oauthtwitter import OAuthApi
- import sys
- import os
- twitter = None
- consumerKey = ''
- consumerSecret = ''
- def auth():
- authToken = None
- authSecret = None
- if os.path.exists('/tmp/twitter.tmp'):
- f = open('/tmp/twitter.tmp', 'r')
- authToken = f.readline().strip()
- authSecret = f.readline().strip()
- print "oauth_token: " + authToken
- print "oauth_token_secret: " + authSecret
- f.close()
- needAuth = True
- if authToken!=None and authSecret!=None:
- twitter = OAuthApi(consumerKey, consumerSecret, authToken, authSecret)
- if twitter.autorized():
- needAuth = False
- if needAuth:
- twitter = OAuthApi(consumerKey, consumerSecret)
- temp_credentials = twitter.getRequestToken()
- print temp_credentials
- print twitter.getAuthorizationURL(temp_credentials)
- oauth_verifier = raw_input('What is the PIN? ')
- access_token = twitter.getAccessToken(temp_credentials, oauth_verifier)
- print access_token
- print("oauth_token: " + access_token['oauth_token'])
- print("oauth_token_secret: " + access_token['oauth_token_secret'])
- f = open('/tmp/twitter.tmp', 'w')
- f.write('%s\n%s'%(access_token['oauth_token'], access_token['oauth_token_secret']))
- f.close()
- twitter = OAuthApi(consumerKey, consumerSecret, access_token['oauth_token'], access_token['oauth_token_secret'])
- return twitter
- def unfollow():
- friends = twitter.GetFriendsIDs()
- for i in range(min(len(friends),30)):
- twitter.UnfollowUser(friends[i])
- def follow(query):
- users = twitter.searchByQuery(query)
- count = min(30, len(users))
- for user in users:
- print user['id']
- twitter.FollowUser(user['id'])
- if __name__=='__main__':
- if len(sys.argv)<2:
- print "Usage: %s <mode>"%sys.argv[0]
- print "Mode:"
- print " follow - find and follow by twitter users"
- print " unfollow - unfollow twitter users"
- print ""
- sys.exit(0)
- if sys.argv[1]=='unfollow':
- twitter = auth()
- unfollow()
- elif sys.argv[1]=='follow':
- twitter = auth()
- follow('twitter')
самое интересное в скрипте, метод auth. В файле /tmp/twitter.tmp я храню токен авторизации пользователя. Если этот токен не существует или не принимается пользователем, то вывожу на экран урл авторизации и жду пока пользователь авторизуеться в твиттере и введет PIN в приложение. По этому пину и получаем токен авторизации который и сохраняем в файл /tmp/twitter.tmp до следующего запуска скрипта.
Методы follow вызывает метод search твиттера и фолловит найденых пользователей. Метод unfollow берет список фолловеров и отписываеться от некоторых из них.
2 ноября 2010 г.
Ссылка на AppStore reviews приложения из приложения
В магазине приложений AppStore сделано так, что боольшинство оценок которыми оценивают ваше приложение появляется при удалении приложения с устройсва. А пользователь удаляет приложение если оно ему не понравилось, т.е. большинство оценок приложению достаются низкие.
Можно попробовать решить сделав переход из вашего приложения на страничку написания ревью к вашему приложению. Как это Вы реализуете: ссылкой в "О программе" или алертом при каждом запуске приложения с просьбой оценить приложение - не важно. Я здесь привожу лишь код сотавления урл-аддреса и открытие его:
В результате переходим в приложение AppStore на сраничку Write review приложения (не забудьте поменять id в коде)

Спасибо memention за инструкцию.
Можно попробовать решить сделав переход из вашего приложения на страничку написания ревью к вашему приложению. Как это Вы реализуете: ссылкой в "О программе" или алертом при каждом запуске приложения с просьбой оценить приложение - не важно. Я здесь привожу лишь код сотавления урл-аддреса и открытие его:
- NSString *str = @"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa";
- str = [NSString stringWithFormat:@"%@/wa/viewContentsUserReviews?", str];
- str = [NSString stringWithFormat:@"%@type=Purple+Software&id=", str];
- // Здесь добавляем AppleID вашего приложения из iTunesConnect
- str = [NSString stringWithFormat:@"%@348529788", str];
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];
В результате переходим в приложение AppStore на сраничку Write review приложения (не забудьте поменять id в коде)

Спасибо memention за инструкцию.
Добавление файлов в библиотеку iTunes без копирования файлов
Известно, что при добавлении файлов в iTunes приложение копирует файлы в свою библиотеку. Мне не хочется держать по нескольку копий больших видеофайлов на жестком диске.
Решение простое - добавлять в iTunes не сами файлы а ссылки на них. Для этого, перетаскиваем с Finder при нажатой клавише Option нужный файл или папку. Вуаля, в библиотеку добавилась ссылка на файл.
Решение простое - добавлять в iTunes не сами файлы а ссылки на них. Для этого, перетаскиваем с Finder при нажатой клавише Option нужный файл или папку. Вуаля, в библиотеку добавилась ссылка на файл.
1 ноября 2010 г.
Локализация даты/времени
Формат даты/времени не зависит от текущего языка на вашем устройстве. А зависит от региональных настроек:

Для отображения даты/времени я использую UIDatePicker который от региональных настроек устройства отображает дату и время корректно. Если же мне нужна текстовая строка с локализованной датой/временем (для вывода на экран например), то я использую класс NSDateFormatter для получения строки. У обоих классов есть так-же метод setLocale: в котором можно жестко указать в каком региональном формате отображать дату/время.
См. также:
1. Локализация строк в Xcode

Для отображения даты/времени я использую UIDatePicker который от региональных настроек устройства отображает дату и время корректно. Если же мне нужна текстовая строка с локализованной датой/временем (для вывода на экран например), то я использую класс NSDateFormatter для получения строки. У обоих классов есть так-же метод setLocale: в котором можно жестко указать в каком региональном формате отображать дату/время.
См. также:
1. Локализация строк в Xcode
Подписаться на:
Сообщения (Atom)