11 мар. 2014 г.

Objective-C подтверждение адресса электронной почты

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

Этот метод использует класс NSRegularExpression. Описание по этому классу можно посмотреть в документации Apple.

- (BOOL) validEmail:(NSString*) emailString {
    if([emailString length]==0) {
        return NO;
    } 

    NSString *regExPattern = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSRegularExpression *regEx = [[NSRegularExpression alloc] initWithPattern:regExPattern options:NSRegularExpressionCaseInsensitive error:nil];
    NSUInteger regExMatches = [regEx numberOfMatchesInString:emailString options:0 range:NSMakeRange(0, [emailString length])];
    NSLog(@"%i", regExMatches);

    if (regExMatches == 0) {
        return NO;
    } else {
        return YES;
    }
}

Конвертация NSString-даты в удобно читаемую дату

Идея состоит в том чтобы полученную дату (например: 11/03/2014) перевести в более удобно читаемый, более человечный формат (например: вторник 11 марта 2014г.). Значит будем работать с NSDateFormatter.

-(NSString *) getHumanDate: (NSString *) strDate {
    
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"dd/MM/yyyy"];
    NSDate *date = [dateFormat dateFromString:strDate];
    [dateFormat release];

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"EEEE',' dd ' ' MMMM ' ' yyyy"];
    NSLocale *loc = [[NSLocale alloc] initWithLocaleIdentifier:@"uk_UA"]; // ru_RU
    [formatter setLocale:loc ] ;
    return [formatter stringFromDate:date];
}
 
 

Аватарка с закругленными углами в iOS приложении

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

Все, что нужно сделать, это настроить CALayer отвечающий за вид изображения, представляющего аватар:

self.avatarImageView.layer.cornerRadius = 150.0f;
self.avatarImageView.layer.borderWidth = 2.0f;
self.avatarImageView.layer.borderColor = [UIColor blackColor].CGColor;
self.avatarImageView.clipsToBounds = YES;

Предположим, что у нас есть квадратное изображение размером 300 × 300, в противном случае мы не сможем получить идеальный круг. Мы добавим черную рамку, и зададим clipsToBounds равным YES. И что в итоге имеем - большое скругленное изображение.

10 мар. 2014 г.

NSSlider "ползунок"

Объект NSSlider отображает диапазон значений для чего-то (какого-нибудь контрола) в приложении. Ползунки могут быть вертикальными или горизонтальными полосами или круговыми циферблатами.

Создадим форму и расположим на ней некоторые контролы интерфейса:

Добавим:
- Label;
- Slider.

В Label установим текст со значением 50 (можно любое другое или вообще никакого текста на изменять, далее будет понятно почему). Добавим слайдер, выровняем, и сделаем наши связи со соледующими оутлетами:

IBOutlet NSTextField *sliderTextLabel;
IBOutlet NSSlider *slider;

Также добавим экшен на наш слайдер, который будет срабатывать при изменении ползунка слайдера:

- (IBAction)sliderChange:(id)sender;

В метод applicationDidFinishLaunching добавим следующий код инициализации нашего слайдера и нашего лейбла:

[slider setIntValue:50];
[sliderTextLabel setIntValue:[slider intValue]];

Можно установить любое значение слайдеру при инициализации. Дальше в нашем экшене-методе sliderChange напишем такие строчки кода:

[sliderTextLabel setIntValue:[slider intValue]];

При изменении местоположения ползунка будет меняться значение нашего лэйбла. Но есть один нюанс. Значение в лэйбле устанавливается (текущего значения слайдера) только тогда когда Вы остановили перемещение ползунка. Но нам бы хотелось пойти дальше и сделать более правильно, т.е. чтобы значение лэйбла менялось в реальном времени во время перемещения ползунка слайдера. Для этого нужно в Дизайнере форм пометить слайдер и в Инспекторе аттрибутов в секции Control выставить чекбокс Continuous. Вот и все.

NSPopupButton выпадающий список

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

Создадим форму, на которой расположим наши контролы интерфейса:

- PopUpButton;
- TextField;
- Button;
- Label.

Сделаем связи наших контролов с нашими аутлетами и экшенами:

IBOutlet NSTextField *textLabel; // к Label
IBOutlet NSTextField *textField; // к TextField
IBOutlet NSPopUpButton *popUpButton; // к popUpButton


- (IBAction)addItemToPopUpButton:(id)sender; // к кнопке "Добавить"
- (IBAction)itemPopUpButtonDidSelected:(id)sender; // к popUpButton

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


- (IBAction)addItemToPopUpButton:(id)sender {
    
    if (![[textField stringValueisEqual: @""]) {
        [popUpButton addItemWithTitle: [textField stringValue]];
    }
}

- (IBAction)itemPopUpButtonDidSelected:(id)sender {
    
    [textLabel setStringValue:[popUpButton titleOfSelectedItem]];
}

Наш результат:
Теперь когда мы введем текст в TextField - поле и нажмем кнопку добавить, то наш текст будет добавлен в выпадающий список элемент за элементом. Если мы выберем какой-то элемент из выпадающего списка, то этот текст отобразится в нашем Label.

9 мар. 2014 г.

StatusBar приложение

Простой пример приложения которое имеет свое меню в статус баре OS X.

Создадим новый проект в Xcode. Перейдем в Interface Builder и добавим до нашего созданного окна "меню" (Выберем в списке контролов интерфейса Menu и положим где-то рядом с окном.
Отредактируем элементы списка меню:

- Показать окно;
- Выход.

В AppDelegate.h добавим следующие строки:

IBOutlet NSMenu *statusBarMenu;
NSStatusItem *statusBarItem;

- (IBAction)showWindow:(id)sender;
- (IBAction)quitApp:(id)sender;

Соединим наш оутлет NSMenu с нашим добавленным меню. Наши экшены соотвествующими элементами меню.

В AppDelegate.m в методе awakeFromNib напишем следующий код:

statusBarItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
[statusBarItem setMenu:statusBarMenu];
[statusBarItem setTitle:@"МоеМеню"];
[statusBarItem setHighlightMode:YES];

В экшене showWindow пишем следующее:

[NSApp activateIgnoringOtherApps:YES];
[_window makeKeyAndOrderFront:nil];

Код будет показывать нам наше скрытое приложение, будь оно свернуто или закрыто.

В экшене quitApp пишем:

[NSApp terminate:nil];

Ну вот и все.
Также можно добавить иконку к нашему меню. Если убрать setTitle, то у нас будет вместо надписи в статус баре только иконка. Иконка должна быть соотвествующих размеров как для обычных экранов так и для ретина-экранов.


8 мар. 2014 г.

Установить бэйдж на иконку приложения с помощью Objective-C

Для быстрой установки бэйджа на иконку своего приложения можно с помощью метода NSDockTitle.

[[NSApp dockTile] setBadgeLabel:@"МойБэйдж"];

Это покажет красный бэйдж на иконке Вашего приложения. Но нужно помнить одну вещь. Сообщение будет показано полностью если текст сообщения не будет длиннее чем ширина иконки приложения.

Здесь видно что текст отображается полностью и нигде не обрезан.



А вот тут уже другая история. Середина текста выковыряна, т.к. текст больше чем сама ширина иконки.

Не убиваемое приложение на OS X

Небольшая, невинная шалость, которую Вы можете сделать своему другу на его Маке. Инструменты которые нам понадобятся:

- Текстовый редактор;
- Терминал.

Предполагаю что у Вас уже есть некоторые знания по запуску приложений из терминала (launchd) и использованию launchctl инструмента. Все что нужно для не убиваемого приложения (будь то какое-нибудь фоновое приложение) это определить его в качестве сервиса / процесса ( службы) и запустить (получится что если вы его убьете (kill), то система автоматически его снова запустит). launchd используется для администрирования службы на OS X. У него есть инструмент launchctl который запускает / останавливает сервис / процессы (службу). Также - каждая служба определяется с помощью plist - файла. Давайте создадим такой файл:

<plist version="1.0">
 <dict>
    <key>Label</key>
    <string>com.apple.SafariService</string>
    <key>ProgramArguments</key>
    <array>
      <string>/Applications/Safari.app/Contents/MacOS/Safari</string>
    </array>
    <key>OnDemand</key>
  <false/>
 </dict>
</plist>

Дальше все просто. Мы его обзываем как com.apple.SafariService и делаем его как исполняемое  (даем права на выполнение/запуск) дополнение Safari. Опция OnDemand говорит, что он должен всегда работать. Сохраняем XML как файл с именем com.apple.SafariServicе.plist и помещаем его в папку ~/Library/LaunchAgents. Теперь для "не убиваемой части" - откройте терминал и введите следующую команду:

$ launchctl load ~/Library/LaunchAgents/com.apple.SafariService.plist

Это запустит Safari, если он не работает. Также - это будет перезапускать Safari как только вы попытаетесь выйти из него. То же самое касается kill - как только вы отправите службе сообщение SIGTERM - ОС будет перезапускать приложение. Вот и все. Удачного издевательства!