ios-05_1-uikit

45
iOS Internship 2014 UIKit (part I)

Upload: noveo

Post on 15-Jan-2015

241 views

Category:

Software


0 download

DESCRIPTION

Noveo iOS school. Lecture 5.

TRANSCRIPT

Page 1: iOS-05_1-UIKit

iOS Internship 2014UIKit (part I)

Page 2: iOS-05_1-UIKit

UIKitframework

лекция 5

UIApplication, UIWindow UIView, UILabel, UIButton

UIViewControllerUINavigationController

Interface Builderautolayouts

interface orientationsview animations

Page 3: iOS-05_1-UIKit

UIKit Framework

● Всё что видит пользователь:○ текст○ кнопки○ картинки○ списки○ …

● Обработка действий пользователя:○ нажатия○ жесты○ набор текста○ сворачивание/разворачивание приложения○ …

● Абстракции для работы с перечисленным○ цвет, шрифт, …○ устройство, экран, окно○ NIB, layouts, …○ …

UIKit

Page 4: iOS-05_1-UIKit

UIKit Framework

● Объект-синглтон [UIApplication sharedApplication]

● Владеет окном

● Управляет статус-баром

● Управляет работой приложения в background-режиме

● Рассылает уведомления о смене состояния приложения

● Осуществляет переход в другие приложение (открывает URL)

● Имеет делегата

UIApplication

Page 5: iOS-05_1-UIKit

UIKit Framework

UIApplication *app = [UIApplication sharedApplication];

//...

[app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];

//...

NSURL *url = [NSURL URLWithString:@"http://google.com"];if ([app canOpenURL:url]) {

[app openURL:url];}

UIApplication

Page 6: iOS-05_1-UIKit

UIKit Framework

● Фактически в каждом приложении есть класс отвечающий этому протоколу

● Фактически это место, с которого начинается исполнение прикладного кода

● Обрабатывает события жизненного цикла приложения:

○ запуск

○ сворачивание/разворачивание

○ переход в активное/неактивное состояние (например звонок)

○ переход в background-режим (приложение свёрнуто, но наш код выполняется)

○ завершение работы приложения

● Получает локальные и push-уведомления

UIApplicationDelegate

Page 7: iOS-05_1-UIKit

UIKit Framework

UIApplicationDelegate@interface AppDelegate : UIResponder <UIApplicationDelegate>@property (strong, nonatomic) UIWindow *window;@end @implementation AppDelegate- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

CGRect windowFrame = [UIScreen mainScreen].bounds;self.window = [[UIWindow alloc] initWithFrame:windowFrame];

ViewController *viewController = [[ViewController alloc] init];self.window.rootViewController = viewController;

[self.window makeKeyAndVisible];return YES;

}@end

Page 8: iOS-05_1-UIKit

UIKit Framework

Один экран*:[UIScreen mainScreen]

Одно окно*:[[UIApplication sharedApplication].delegate window]

* на самом деле — не совсем…

UIScreen, UIWindow

Page 9: iOS-05_1-UIKit

UIKit Framework

● Базовый класс для всего, что видит пользователь

● Сама по себе UIView — просто прямоугольник

● Умеет отрисовывать себя и перехватывать события внутри прямоугольника

● Объекты UIView (и классов-наследников) выстраиваются в дерево:

○ UIView содержит 0 или несколько вложенных объектов — subview

○ UIView имеет 0 или 1 объект-контейнер — superview

● UIView верхнего уровня лежит в окне (UIWindow)

UIView

Page 10: iOS-05_1-UIKit

UIKit Framework

UIViewUIView *greenView = [[UIView alloc] init];

greenView.frame = (CGRect) {200, 100, 60, 40};

greenView.backgroundColor = [UIColor greenColor];

[self.view addSubview:greenView];

UIView *redView = [[UIView alloc] init];

redView.frame = self.view.bounds;

redView.backgroundColor = [UIColor redColor];

[self.view insertSubview:redView atIndex:0];

Page 11: iOS-05_1-UIKit

UIKit Framework

UIView *greenView = [[UIView alloc] init];

greenView.frame = (CGRect) {200, 100, 60, 40};

greenView.backgroundColor = [UIColor greenColor];

[self.view addSubview:greenView];

UIView *redView = [[UIView alloc] init];

redView.frame = self.view.bounds;

redView.backgroundColor = [UIColor redColor];

[self.view insertSubview:redView atIndex:0];

UIViewx

y

0, 0

60x40200

100

Page 12: iOS-05_1-UIKit

UIKit Framework

UIView *greenView = [[UIView alloc] init];

greenView.frame = (CGRect) {200, 100, 60, 40};

greenView.backgroundColor = [UIColor greenColor];

[self.view addSubview:greenView];

UIView *redView = [[UIView alloc] init];

redView.frame = self.view.bounds;

redView.backgroundColor = [UIColor redColor];

[self.view insertSubview:redView atIndex:0];

UIViewx

y

0, 0

60x40200

100

Page 13: iOS-05_1-UIKit

UIKit Framework

?

UIView *greenView = [[UIView alloc] init];

greenView.frame = (CGRect) {200, 100, 60, 40};

greenView.backgroundColor = [UIColor greenColor];

[self.view addSubview:greenView];

UIView *redView = [[UIView alloc] init];

redView.frame = greenView.bounds;

redView.backgroundColor = [UIColor redColor];

[self.view insertSubview:redView atIndex:0];

UIViewx

y

0, 0

60x40200

100

Page 14: iOS-05_1-UIKit

UIKit Framework

UIView *greenView = [[UIView alloc] init];

greenView.frame = (CGRect) {200, 100, 60, 40};

greenView.backgroundColor = [UIColor greenColor];

[self.view addSubview:greenView];

UIView *redView = [[UIView alloc] init];

redView.frame = greenView.bounds; //{0, 0, 60, 40}

redView.backgroundColor = [UIColor redColor];

[self.view insertSubview:redView atIndex:0];

UIViewx

y

0, 0

60x40200

10060x40

Page 15: iOS-05_1-UIKit

UIKit Framework

UIView *view = [[UIView alloc] initWithFrame:self.view.bounds];view.hidden = NO;view.alpha = 0.8;view.backgroundColor = [UIColor redColor];view.userInteractionEnabled = YES;view.tag = 42;

//...

for (UIView *subview in view.subviews) {//...

}UIView *superview = view.superview;

UIView

Page 16: iOS-05_1-UIKit

UIKit Framework

UILabel *label = [[UILabel alloc] init];label.frame = (CGRect) {0, 0, self.view.bounds.size.width, 30};label.font = [UIFont systemFontOfSize:20];label.backgroundColor = [UIColor clearColor];label.textColor = [UIColor blackColor];label.textAlignment = NSTextAlignmentLeft;label.numberOfLines = 1;label.adjustsFontSizeToFitWidth = YES;label.minimumScaleFactor = 0.8;[self.view addSubview:label];

label.text = @"Hello, world!";

UILabel

Page 17: iOS-05_1-UIKit

UIKit Framework

UIImage — картинка в памяти● загружается из файла / ресурсов / бинарных данных в памяти● сохраняется в JPG и PNG● поддерживает растягивание фонов / рамок (аналог 9-patch)● можно получить размер, ориентацию● автоматически выбирает retina / non-retina версию ресурса (@2x)UIImageView — картинка на экране● показывает UIImage● масштабирует до нужного размера (кадрирует / добавляет поля /

растягивает / сжимает)● поддерживает циклическую анимацию

UIImage, UIImageView

Page 18: iOS-05_1-UIKit

UIKit Framework

UIImage *image = [UIImage imageNamed:@"my_image.png"];UIImageView *imageView = [[UIImageView alloc] initWithImage:image];imageView.frame = self.view.bounds;imageView.contentMode = UIViewContentModeScaleAspectFit;[self.view addSubview:imageView];

//...

UIImage *image_2 = [UIImage imageNamed:@"my_image_2.png"];imageView.image = image_2;

UIImage, UIImageView

Page 19: iOS-05_1-UIKit

UIKit Framework

UIImage *buttonBGImageN = [UIImage imageNamed:@"button.png"];UIImage *buttonBGImageS = [UIImage imageNamed:@"button_pressed.png"];

UIButton *button = [[UIButton alloc] init];button.frame = (CGRect) {0, 0, 120, 40};button.backgroundColor = [UIColor lightGrayColor];[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[button setTitle:@"Tap me!" forState:UIControlStateNormal];[button setBackgroundImage:buttonBGImageN forState:UIControlStateNormal];[button setBackgroundImage:buttonBGImageS forState:UIControlStateSelected];

[self.view addSubview:button];

UIButton как UIView

Page 20: iOS-05_1-UIKit

UIKit Framework

{UIButton *button = /*...*/;//...[button addTarget:self

action:@selector(buttonTap:) forControlEvents:UIControlEventTouchUpInside];} - (void)buttonTap:(UIButton *)sender{

//...}

UIButton как UIControl

Page 21: iOS-05_1-UIKit

UIKit Framework

[x addTarget:target action:action forControlEvents:events];

UIButton *x

[

<target, action, events>,

<target, action, events>,

<target, action, events>,

...

]

UIControl

Page 22: iOS-05_1-UIKit

UIKit Framework

self.label = [[UILabel alloc] initWithFrame:labelFrame];[self.view addSubview:self.label];

self.input = [[UITextField alloc] initWithFrame:inputFrame];[self.view addSubview:self.input];[self.input addTarget:self action:@selector(textChanged:) forControlEvents:UIControlEventEditingChanged]; //...

- (void)textChanged:(UITextField *)sender{

self.label.text = sender.text;}

UITextField

Page 23: iOS-05_1-UIKit

UIKit Framework

UIView — логическая организация элементов, прямоугольники, полоски

UILabel — вывод текста

UITextField, UITextView — редактирование текста

UIWebView — показ HTML

UIImageView — показ картинок

UIButton — кнопка

UISwitch, UISlider, UIStepper — выключатель, регулятор, ступенчатый регулятор

UIToolbar, UITabBar, UINavigationBar — панели

UIActivityIndicatorView — спиннер

UITableView, UITableViewCell — список

UICollectionView, UICollectionViewCell — коллекция

UIScrollView — область прокрутки

UIPickerView — выбор варианта

UIView

Page 24: iOS-05_1-UIKit

UIKit Framework

Прозрачный: [UIColor clearColor]

RGB: [UIColor colorWithRed:r/255.0f

green:g/255.0f

blue:b/255.0f

alpha:a/255.0f]

HSV: [UIColor colorWithHue:h/255.0f

saturation:s/255.0f

brightness:v/255.0f

alpha:a/255.0f]

BW: [UIColor colorWithWhite:w/255.0f

alpha:a/255.0f]

UIColor

Page 25: iOS-05_1-UIKit

UIKit Framework

Список семейств шрифтов: [UIFont familyNames]

● Courier● Georgia● Helvetica● Helvetica Neue● Verdana● ...

Список вариантов начертаний: [UIFont fontNamesForFamilyName:@"Helvetica"]

● Helvetica-Oblique● Helvetica-Light● Helvetica-Bold● Helvetica● Helvetica-BoldOblique● Helvetica-LightOblique

Шрифт по имени: [UIFont fontWithName:@"Helvetica-Bold" size:20]

Стандартный шрифт: [UIFont systemFontOfSize:[UIFont systemFontSize]]

UIFont

Page 26: iOS-05_1-UIKit

UIKit Framework

MVC… WTF?

UIViewController

Page 27: iOS-05_1-UIKit

UIKit Framework

● Связывает модель с представлением.

● Управляет жизненным циклом View.

● Обрабатывает события (действия пользователя).

● Обеспечивает логическую организацию функционала(например разбивка по экранам).

● Свойство view — верхнеуровневая UIView конроллера.

● Основной способ использования UIViewController — наследование. Поведение задаём в переопределённых методах.

UIViewController

Page 28: iOS-05_1-UIKit

UIKit Framework

– initWithNibName:bundle:

– viewDidLoad

– viewWillAppear:

– viewDidAppear:

– viewWillDisappear:

– viewDidDisappear:

– viewWillLayoutSubviews

– viewDidLayoutSubviews

UIViewController– preferredStatusBarStyle

– prefersStatusBarHidden

– shouldAutorotate

– supportedInterfaceOrientations

...

Page 29: iOS-05_1-UIKit

UIKit Framework

– initWithNibName:bundle: — designated initializer

– viewDidLoad — self.view загружена

– viewWillAppear: — перед началом анимации перехода на контроллер

– viewDidAppear: — после завершения анимации перехода на контроллер

– viewWillDisappear: — перед началом анимации перехода с контроллера

– viewDidDisappear: — после завершения анимации перехода с контроллера

– viewDidLayoutSubviews — после (потенциального) изменения лейаута self.view

UIViewController

Page 30: iOS-05_1-UIKit

UIKit Framework

UIViewController

@interface DashboardVC()@property (strong, nonatomic) UILabel *speedLabel;@end @implementation DashboardVC- (void)viewDidLoad{

[super viewDidLoad];self.speedLabel = [[UILabel alloc] initWithFrame:self.view.bounds];[self.view addSubview:self.speedLabel];self.speedLabel.text = stringFromSpeedValue(self.speed);

} -(void)setSpeed:(float)speed{

_speed = speed;self.speedLabel.text = stringFromSpeedValue(self.speed);

}

@interface DashboardVC : UIViewController@property (assign, nonatomic) float speed;@end

DashboardVC.h

DashboardVC.m

Page 31: iOS-05_1-UIKit

UIKit Framework

UIViewController@interface AppDelegate : UIResponder <UIApplicationDelegate>@property (strong, nonatomic) UIWindow *window;@end @implementation AppDelegate

- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

DashboardVC *dashboardVC = [[DashboardVC alloc] init];

self.window.rootViewController = dashboardVC;[self.window makeKeyAndVisible];

return YES;}@end

Page 32: iOS-05_1-UIKit

UIKit Framework

UINavigationController"back" button

navigation bar

push

pop

VC 1 VC 2

Page 33: iOS-05_1-UIKit

UIKit Framework

UINavigationController@interface AppDelegate : UIResponder <UIApplicationDelegate>@property (strong, nonatomic) UIWindow *window;@end @implementation AppDelegate- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

DashboardVC *dashboardVC = [[DashboardVC alloc] init];

UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:dashboardVC];

self.window.rootViewController = nc;[self.window makeKeyAndVisible];

return YES;}@end

Page 34: iOS-05_1-UIKit

UIKit Framework

@interface DashboardVC()//...@property (strong, nonatomic) UIButton *settingsButton;@end @implementation DashboardVC- (void)viewDidLoad{

[super viewDidLoad];//...self.settingsButton = [[UIButton alloc] initWithFrame:(CGRect){40, 40, 40, 40}];self.settingsButton.backgroundColor = [UIColor blueColor];[self.view addSubview:self.settingsButton];[self.settingsButton addTarget:self action:@selector(settingsButtonTap:) forControlEvents:UIControlEventTouchUpInside];

} -(void)settingsButtonTap:(UIButton *)sender{

SettingsVC *settingsVC = [[SettingsVC alloc] init];[self.navigationController pushViewController:settingsVC animated:YES];

}@end

UINavigationController

Page 35: iOS-05_1-UIKit

UIKit Framework

@implementation DashboardVC //... - (void)viewDidAppear:(BOOL)animated{

[super viewDidAppear:animated];

[UIView animateWithDuration:0.3 animations:^{self.settingsButton.alpha = 1;

}];} - (void)buttonTap:(UIButton *)sender{

[UIView animateWithDuration:0.3 animations:^{self.settingsButton.alpha = 0;

} completion:^(BOOL finished) {self.settingsButton.hidden = YES;self.settingsButton.userInteractionEnabled = NO;

}];} @end

UIView animation

Page 36: iOS-05_1-UIKit

UIKit Framework

Interface orientations@implementation DashboardVC//... - (BOOL)shouldAutorotate{

return YES;} - (NSUInteger)supportedInterfaceOrientations{

return UIInterfaceOrientationMaskAll;} - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{

return UIInterfaceOrientationPortrait;} @end

Page 37: iOS-05_1-UIKit

UIKit Framework

● Autoresizing masks vs. Autolayouts

● Interface Builder

Далее

Page 38: iOS-05_1-UIKit

UIKit Framework

Layout● iPhone + iPad● portrait + landscape● динамический размер контента● ...

Page 39: iOS-05_1-UIKit

UIKit Framework

Layout● Springs & struts (using UIViewAutoresizing)

○ Легко освоить○ Удобно задавать и в IB и из кода○ Легко анимаировать○ Легко кастомизировать○ Не помогает при динамическом контенте

● Autolayout (using NSLayoutConstraint)○ Сложно освоить○ Неудобный редактор в IB и муторно задавать из кода○ Помогает при динамическом контенте○ Медленно работает

Page 40: iOS-05_1-UIKit

UIKit Framework

Manual layoutx

y

@property (nonatomic, strong) UILabel *myLabel; //... - (void)viewDidLoad{

[super viewDidLoad];self.myLabel = [[UILabel alloc] init];[self.view addSubview:self.myLabel];//...

} - (void)viewDidLayoutSubviews{

[super viewDidLayoutSubviews];self.myLabel.frame = CGRectInset(self.view.bounds, 40, 40);

}

20.0, 20.0

280 x 440

Page 41: iOS-05_1-UIKit

UIKit Framework

Spring & strutsx

y

20.0, 20.0@property (nonatomic, strong) UILabel *myLabel; //... - (void)viewDidLoad{

[super viewDidLoad];

self.myLabel = [[UILabel alloc] init];[self.view addSubview:self.myLabel];self.myLabel.frame = CGRectInset(self.view.bounds, 40, 40);self.myLabel.autoresizingMask =

UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;

}

Page 42: iOS-05_1-UIKit

UIKit Framework

- (void)viewDidLoad{

[super viewDidLoad];

self.myLabel = [[UILabel alloc] init];[self.view addSubview:self.myLabel];self.myLabel.translatesAutoresizingMaskIntoConstraints = NO;UIView *label = self.myLabel;UIView *superview = self.view;NSDictionary *views = NSDictionaryOfVariableBindings(superview, label);

[superview addConstraints:[NSLayoutConstraint

constraintsWithVisualFormat:@"H:|-20-[label]-20-|"options:0metrics:nilviews:views]];

[superview addConstraints:[NSLayoutConstraint

constraintsWithVisualFormat:@"V:|-20-[label]-20-|"options:0metrics:nilviews:views]];

}

Autolayoutx

y

20.0

20.0 20.0

20.0

Page 43: iOS-05_1-UIKit

UIKit Framework

● XIB○ визуальное описание иерархии и свойств view

● Storyboard○ XIB + ...

○ несколько экранов в одном файле

○ можно описать переходы между экранами

○ таблицу можно описать вместе с ячейками

Interface Builder

Page 44: iOS-05_1-UIKit

UIKit Framework

● XIBMyVC *myVC =

[[UIViewController alloc]initWithNibName:@"MyVC" bundle:[NSBundle mainBundle]];

● StoryboardUIStoryboard *myStoryboard =

[UIStoryboard toryboardWithName:@"MySB" bundle:[NSBundle mainBundle]];MyVC *myVC =

[myStoryboard instantiateViewControllerWithIdentifier:@"MyVC"];

Interface Builder

Page 45: iOS-05_1-UIKit

UIKit Framework

@interface MyVC ()@property (strong, nonatomic) IBOutlet UIButton *myButton;@property (strong, nonatomic) IBOutletCollection(UILabel) NSArray *myLabels;@end

@implementation MyVC

- (IBAction)myButtonTap:(UIButton *)sender{

for (UILabel *label in self.myLabels) { label.text = nil;

}}

@end

Interface Builder