Ещё немного Objective-С. Введение в iOS.
Разработка приложений для iOS
Лекция 2
Глеб Тарасов#msumobi2
Вспоминаем
Как вызвать метод startProcess без параметров у объекта в переменной «queue»?
Как вызвать метод startProcess без параметров у объекта в переменной «queue»?
[queue startProcess];
Как вызвать метод startProcessWithTimeout с
параметром 10?
Как вызвать метод startProcessWithTimeout с
параметром 10?
[queue startProcessWithTimeout:10];
Как вызвать метод startProcessWithTimeout
andSize с параметрами 10 и 100?
Как вызвать метод startProcessWithTimeout
andSize с параметрами 10 и 100?
[queue startProcessWithTimeout:10 andSize:100];
Продолжение Objective-С
ЧислаCGFloat a = 0.5;NSInteger b = -1;NSUInteger q = 10;
ЧислаCGFloat a = 0.5;NSInteger b = -1;NSUInteger q = 10;
ЧислаCGFloat a = 0.5;NSInteger b = -1;NSUInteger q = 10;
СтруктурыCGPoint p;p.x = 10;p.y = 20;p = CGPointMake(10, 20);
CGSize s;s.width = 100;s.height = 100;s = CGSizeMake(100, 100);
CGRect r;r.size = s;r.origin = p;r = CGRectMake(10, 20, 100, 100);
Стандартные классы
Строки
NSString NSMutableString
NSString *a = @"abc";NSString *b = [a stringByReplacingOccurrencesOfString:@"a" withString:@"b"];NSLog(@"b: %@", b);
NSMutableString *m = [b mutableCopy];NSRange r;r.length = m.length;r.location = 0;[m replaceOccurrencesOfString:@"c" withString:@"b" options:0 range:r];NSLog(@"m: %@", m);
Списки
NSArray NSMutableArray
NSArray *a = @[@"a", @"b", @"c"];NSString *first = a[0];NSString *last = a[[a count] - 1];
NSMutableArray *b = [a mutableCopy];[b addObject:@"r"];[b replaceObjectAtIndex:1 withObject:@"q"];[b removeObjectAtIndex:2];
Обычные упорядоченные массивы
Словари
NSDictionary NSMutableDictionary
NSDictionary *dict = @ { @"key1" : @"a", @"key2" : @"b" };NSString *first = dict[@"key1"];
NSMutableDictionary *m = [dict mutableCopy];m[@"key3"] = @"c";
Хранение пар «ключ-значение».Быстрый поиск значения по ключу
Перечисление (enumeration)
NSArray *arr = @[@"a", @"b", @"c"];
for (NSString *a in arr) { NSLog(@"%@", a);}
NSDictionary *dict = @{ @"key1" : @"a", @"key2" : @"b" };
for (NSString *key in dict){ NSString *value = dict[key]; NSLog(@"%@ - %@", key, value);}
ЧислаNSNumber
NSNumber *a = @(3);int b = [a intValue];
NSNumber *c = @(2.5f);float d = [c floatValue];
NSNumber *e = @(3.567);double f = [e doubleValue];
if ([a isEqualToNumber:c]) NSLog(@"equals");
Бинарные данные
NSData NSMutableData
NSData *data = [[NSData alloc] initWithContentsOfFile:@"data.txt"];NSInteger length = [data length];[data writeToFile:@"result.txt" atomically:YES]; NSMutableData *m = [data mutableCopy];[m appendData:data];
Хранение картинок, текстовых данных в бинарном виде и т.д.
NSNull
NSMutableArray *a = [[NSMutableArray alloc] init];[a addObject:[NSNull null]];
NSObject *q = [a lastObject];if (q == [NSNull null]){ //bla bla}
сохранять «пусто» в массивы и словари
NSValue
CGPoint p = CGPointMake(10, 20);CGRect r = CGRectMake(10, 20, 30, 40);NSValue *v1 = [NSValue valueWithCGPoint:p];NSValue *v2 = [NSValue valueWithCGRect:r];
NSArray *arr = [NSArray arrayWithObjects:v1, v2, nil];CGRect r2 = [[arr lastObject] CGRectValue];
преобразовывать структуры и другие «не объекты» в объекты
Dot notation
Rectangle *r = [[Rectangle alloc] init];
[r setWidth:10];
CGFloat w = [r width];
Dot notation
Rectangle *r = [[Rectangle alloc] init];
[r setWidth:10];
CGFloat w = [r width];
Rectangle *r = [[Rectangle alloc] init];
r.width = 10;
CGFloat w2 = r.width;
Dot notationКласс Rectangle
- float width (число)- float height (число)- Location location (структура)
Rectangle *r = [[Rectangle alloc] init];[r setWidth:10];[r setHeight:20];
Location l;l.x = 1;l.y = 2;
[r setLocation:l];
NSLog(@"%g, %g, (%g, %g)", [r width], [r height], [r location].x, [r location].y);
Dot notation
Rectangle *r = [[Rectangle alloc] init];r.width = 10;r.height = 20;Location l = {1, 2};r.location = l;
NSLog(@"%g, %g, (%g, %g)", r.width, r.height, r.location.x, r.location.y);
Классы
User.h
User.h@interface User
@end
User.h@interface User
@end
: NSObject
User.h@interface User
@end
#import <Foundation/Foundation.h>
: NSObject
User.h@interface User
@end
#import <Foundation/Foundation.h>
- (void)deleteProfile;
: NSObject
User.h@interface User
@end
- (void)postCommentWithText:(NSString *)text;
- (void)postCommentWithTopic:(NSString *)topic andText:(NSString *)text;
#import <Foundation/Foundation.h>
- (void)deleteProfile;
: NSObject
User.h@interface User
@end
- (void)postCommentWithText:(NSString *)text;
- (void)postCommentWithTopic:(NSString *)topic andText:(NSString *)text;
#import <Foundation/Foundation.h>
@property(nonatomic, strong) NSString *name;
@property(nonatomic) NSInteger age;
- (void)deleteProfile;
: NSObject
User.h@interface User
@end
- (void)postCommentWithText:(NSString *)text;
- (void)postCommentWithTopic:(NSString *)topic andText:(NSString *)text;
#import <Foundation/Foundation.h>
@property(nonatomic, strong) NSString *name;
@property(nonatomic) NSInteger age;
- (void)deleteProfile;
- (void)setAge:(NSInteger)age;- (NSInteger)age;
: NSObject
User.m
User.m#import "User.h"
@implementation User
@end
User.m#import "User.h"
@implementation User
@end
- (void)setAge:(NSInteger)age{ _age = age; NSLog(@"Установили возраст %d", age);}
User.m#import "User.h"
@implementation User
@end
- (void)deleteProfile{ // удаляем из базы NSString *name = [self name]; NSLog(@"Пользователь %@ удален", name);}
- (void)postCommentWithText:(NSString *)text{ [self postCommentWithTopic:@"" andText:text];}
- (void)postCommentWithTopic:(NSString *)topic andText:(NSString *)text{ NSLog(@"Пользователь %@ (возраст: %d) с темой %@", self.name, self.age, topic);}
- (void)setAge:(NSInteger)age{ _age = age; NSLog(@"Установили возраст %d", age);}
Admin.h
Admin.h#import "User.h"
@interface Admin : User
- (void)deleteComment:(NSInteger)key;
@end
Admin.h#import "User.h"
@interface Admin : User
- (void)deleteComment:(NSInteger)key;
@end
Admin.m
Admin.h#import "User.h"
@interface Admin : User
- (void)deleteComment:(NSInteger)key;
@end
Admin.m#import "Admin.h"
@implementation Admin
- (void)deleteComment:(NSInteger)key{ //удаляем из базы NSLog(@"Комментарий с ключом %d удален", key); // оставляем комментарий, об удалении [self postCommentWithTopic:@"От админа" andText:@"Удалил коммент за хамство"];}
@end
Инициализация объектов
Инициализация объектов
User *user = [[User alloc] init];
Инициализация объектов
User *user = [[User alloc] init];
user.age = 34;[user setName:@"Вася Пупкин"];
Инициализация объектов
NSString *comment = @"Вот такой вот комментарий";
[user postCommentWithText:comment]; [user deleteProfile];
User *user2 = [[User alloc] initWithName:@"Вася Пупкин"];
User *user = [[User alloc] init];
user.age = 34;[user setName:@"Вася Пупкин"];
Собственный инициализатор
Собственный инициализатор
- (id)initWithName:(NSString *)name{ self = [super init]; if (self) { self.name = name; } return self;}
Собственный инициализатор
- (id)initWithName:(NSString *)name{ self = [super init]; if (self) { self.name = name; } return self;}
- (id)init{ return [self initWithName:@"Имя по умолчанию"];}
Методы класса
Методы классаВ файле Admin.h:
Методы класса
+ (Admin *)createAdmin;
В файле Admin.h:
Методы класса
+ (Admin *)createAdmin;
В файле Admin.h:
В файле Admin.m:
Методы класса
+ (Admin *)createAdmin;
+ (Admin *)createAdmin{ Admin *admin = [[Admin alloc] initWithName:@"Админ Админович"]; admin.age = 34; return admin;}
В файле Admin.h:
В файле Admin.m:
Методы класса
+ (Admin *)createAdmin;
+ (Admin *)createAdmin{ Admin *admin = [[Admin alloc] initWithName:@"Админ Админович"]; admin.age = 34; return admin;}
В файле Admin.h:
В файле Admin.m:
Использование:
Методы класса
+ (Admin *)createAdmin;
+ (Admin *)createAdmin{ Admin *admin = [[Admin alloc] initWithName:@"Админ Админович"]; admin.age = 34; return admin;}
В файле Admin.h:
В файле Admin.m:
Использование:
Admin *admin = [Admin createAdmin]; [admin deleteComment:10];
Переменные клаcса (ivar-ы)
Переменные клаcса (ivar-ы)@interface User : NSObject{ NSString *_name;}
- (void)setName:(NSString *)name;- (NSString *)name;
@end
Переменные клаcса (ivar-ы)@interface User : NSObject{ NSString *_name;}
- (void)setName:(NSString *)name;- (NSString *)name;
@end
@implementation User
- (void)setName:(NSString *)name{ _name = name; }
- (NSString *)name{ return _name;}
@end
Протоколы
Протоколы@protocol SendMessageProtocol <NSObject>
- (void)sendMessage:(NSString *)message;
@end
Протоколы@protocol SendMessageProtocol <NSObject>
- (void)sendMessage:(NSString *)message;
@end
@interface User : NSObject<SendMessageProtocol>
@end
Протоколы@protocol SendMessageProtocol <NSObject>
- (void)sendMessage:(NSString *)message;
@end
@interface User : NSObject<SendMessageProtocol>
@end
@implementation User
- (void)sendMessage:(NSString *)message{ // send message}
@end
Протоколы@protocol SendMessageProtocol <NSObject>
- (void)sendMessage:(NSString *)message;
@end
@interface User : NSObject<SendMessageProtocol>
@end
@implementation User
- (void)sendMessage:(NSString *)message{ // send message}
@end
id<SendMessageProtocol> sender = [[User alloc] init];[sender sendMessage:@"message"];
КатегорииCommentCell.m
Категории
@interface CommentCell()
@property (strong, nonatomic) UILabel *commentLabel;
@end
@implementation CommentCell
- (void)updateWithText:(NSString *)text{ self.commentLabel.text = text;}
@end
CommentCell.m
Objective-C style guide• Локальные переменные: myLocalVariable
• Свойства: myProperty
• Классы: MyClass
• Методы: doSomethingWith:
• Внутренние переменные: • _myLocal
• myLocal_
• myLocal
iOS
MVC
Controller
ModelView
View
UIView@property(nonatomic) CGRect frame;@property(nonatomic) CGRect bounds;@property(nonatomic) CGPoint center;
@property(nonatomic,readonly) UIView *superview;@property(nonatomic,readonly,copy) NSArray *subviews;
- (void)removeFromSuperview;- (void)addSubview:(UIView *)view;- (void)bringSubviewToFront:(UIView *)view;- (void)sendSubviewToBack:(UIView *)view;
@property(nonatomic,copy) UIColor *backgroundColor;@property(nonatomic) CGFloat alpha;@property(nonatomic,getter=isHidden) BOOL hidden;
Иерархия UIView
Стандартные контролы
Controller
UIViewController// The getter first invokes [self loadView] if the view hasn't been set yet. // Subclasses must call super if they override the setter or getter.@property(nonatomic,retain) UIView *view;
// This is where subclasses should create their custom view hierarchy // if they aren't using a nib. // Should never be called directly.- (void)loadView;
- (void)viewWillUnload __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0);// Called after the view has been loaded. For view controllers created in code, // this is after -loadView. For view controllers unarchived from a nib, // this is after the view is set.- (void)viewDidLoad;
// Called after the view controller's view is released and set to nil. // For example, a memory warning which causes the view to be purged. // Not invoked as a result of -dealloc.- (void)viewDidUnload __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (BOOL)isViewLoaded __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
@implementation ViewController
- (void)viewDidLoad{ [super viewDidLoad]; CGRect rect = CGRectMake(20, 20, 100, 100); UILabel *l = [[UILabel alloc] initWithFrame:rect]; l.text = @"text"; [self.view addSubview:l];}
- (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; NSLog(@"появился");}
- (void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; NSLog(@"пропал");}
@end
@interface ViewController : UIViewController
@end
Наполнение View
В коде Interface Builder
- (void)viewDidLoad{ [super viewDidLoad]; CGRect rect = CGRectMake(20, 20, 100, 100); UILabel *l = [[UILabel alloc] initWithFrame:rect]; l.text = @"text"; [self.view addSubview:l];}
Interface Builder(демонстрация)
События
target, action
- (void)viewDidLoad{ [super viewDidLoad];
[self.button addTarget:self action:@selector(buttonClicked) forControlEvents:UIControlEventTouchUpInside];}
- (void)buttonClicked{ NSLog(@"buttonClicked");}
delegate
- (void)viewDidLoad{ [super viewDidLoad]; self.tableView.delegate = self;}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ NSLog(@"select row");}
@interface ViewController : UIViewController<UITableViewDelegate>
Отрывок UIScrollViewDelegate
@protocol UIScrollViewDelegate<NSObject>
@optional
// any offset changes- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
// any zoom scale changes- (void)scrollViewDidZoom:(UIScrollView *)scrollView __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_2);
// called on start of dragging // (may require some time and or distance to move)- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;
...
notificationsNSNotificationCenter *center = [NSNotificationCenter defaultCenter];[center postNotificationName:@"UserChanged" object:nil];
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(userChanged) name:@"UserChanged" object:nil];
- (void)userChanged{ NSLog(@"Событие произошло");}
Событие случилось:
Ловим событие:
Демонстрация IBAction, delegate, IBOutlet
MVC
Controller
ModelView
MVC
Controller
ModelView
outlets
MVC
Controller
ModelView
outlets
MVC
Controller
ModelView
delegates
outlets
MVC
Controller
ModelView
delegates
outletstarget,action
MVC
Controller
ModelView
delegates
outletstarget,action
MVC
Controller
ModelView
delegates
outlets
notificationstarget,action
AppDelegate@protocol UIApplicationDelegate<NSObject>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
}
- (void)applicationDidBecomeActive:(UIApplication *)application{
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
}
AppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; UIViewController *vc = [[UIViewController alloc] init]; self.window.rootViewController = vc; [self.window makeKeyAndVisible];}
Практика:Экран просмотра события
- класс Event:- title- subtitle- distance- description- image
- класс EventViewController- updateWithEvent: