16 мар. 2014 г.

15 мар. 2014 г.

KVC (Key-Value Coding) Ключ - Значение

Ключ-значение кодирования представляет собой механизм для доступа к свойству объекта косвенно, с помощью строк для идентификации свойств, а не через вызов аксессора или доступ к ним непосредственно через переменных экземпляра. Что это значит. Допустим у Вас есть таблица с множеством колонок, каждое имя колонки можно превратить в ключ и обращаться по ключу вместо индекса колонки, ведь так проще, да и запомнить название колонки проще чем ее индекс.

В данном примере мы не будем работать с таблицами, а реализуем некий класс Books (Книги). Основное что нам требуется для книги это "Автор книги", "Название книги" и "Количество страниц в книге".


Итак добавили новый класс наследованный от NSObject:

Books.h :

#import <Foundation/Foundation.h>

@interface Books : NSObject

@property (strong) NSString *bookAuthor;
@property (strong) NSString *bookName;
@property int pageCount;

@end

Books.m - оставим пустым, т.к. остальное мы реализуем в классе AppDelegate

#import "Books.h"

@implementation Books

@end

В AppDelegate.h создадим массив booksArray со списком книг. Ведь у нас будет не одна книга. Также не забудем подключить наш класс Books.

#import <Cocoa/Cocoa.h>
#import "Books.h"

@interface AppDelegate : NSObject <NSApplicationDelegate> {
    NSMutableArray *booksArray;
}

@property (assign) IBOutlet NSWindow *window;
- (IBAction)printListBooks:(id)sender;

@end

На нашу форму поместим кнопку и сделаем связь кнопки с методом printListBooks.

В AppDelegate.m создадим несколько объектов книг и добавим их в массив который будет хранить список наших книг.

#import "AppDelegate.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    
    booksArray = [[NSMutableArray alloc] init];
    
    // Добавляем наши книги-объекты в массив обычным способом
    
    Books *firstBook = [[Books alloc] init];
    [firstBook setBookAuthor:@"Т.Г. Шевченко"];
    [firstBook setBookName:@"Кобзарь"];
    [firstBook setPageCount:283];
    
    [booksArray insertObject:firstBook atIndex:[booksArray count]];
    
    Books *secondBook = [[Books alloc] init];
    [secondBook setBookAuthor:@"И. Франко"];
    [secondBook setBookName:@"Городские повести"];
    [secondBook setPageCount:478];
    
    [booksArray insertObject:secondBook atIndex:[booksArray count]];
}

Организуем код для кнопки, которая будет выдавать список объектов из массива книг.

- (IBAction)printListBooks:(id)sender {
    
    for (Books *currentBook in booksArray) {
        NSLog(@"Книга: %@, Автор книги: %@, К-во страниц: %i",
              [currentBook bookName],
              [currentBook bookAuthor],
              [currentBook pageCount]);
    }
}
@end

Запустим и получим результат:


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

 // Добавляем наши книги-объекты с помощью ключей (KVC)
    
    Books *threeBook = [[Books alloc] init];
    [threeBook setValue:@"Леся Украинка" forKey:@"bookAuthor"];
    [threeBook setValue:@"Боярыня" forKey:@"bookName"];
    [threeBook setValue:@"184" forKey:@"pageCount"];
    
    [booksArray insertObject:threeBook atIndex:[booksArray count]];

Здесь bookAuthor, bookName, pageCount являются ключами, а Value - значениями для каждого ключа. Запустим наше приложение:


Результат - добавлена третья книга в массив-список книг с помощью KVC.

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. Вот и все.