Разработка приложений для iOS




          Лекция 3

 Интерфейсы,
 продолжение

                            Глеб Тарасов
Сложные
контроллеры
UINavigationController
ViewController *c = [[ViewController alloc]
                             initWithNibName:@"ViewController"
                                       bundle:nil];

UINavigationController *nc =
           [[UINavigationController alloc]
              initWithRootViewController:c];
- (IBAction)buttonTapped
{
    UIViewController *c =
          [[SubViewController alloc]
               initWithNibName:@"SubViewController"
                        bundle:nil];

    [self.navigationController pushViewController:c
                                         animated:YES];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:
(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil
                  bundle:nibBundleOrNil];
    if (self)
    {
        self.title = @"ViewController";
    }
    return self;
}
UITabBarController
ViewController *c = [[ViewController alloc]
                          initWithNibName:@"ViewController"
                                   bundle:nil];

SubViewController *s = [[SubViewController alloc]
                       initWithNibName:@"SubViewController"
                                bundle:nil];

UITabBarController *tc = [[UITabBarController alloc] init];

tc.viewControllers = [NSArray arrayWithObjects:c, s, nil];
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:
(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil
                  bundle:nibBundleOrNil];
    if (self)
    {
        self.title = @"ViewController";
        self.tabBarItem.image = [UIImage
                                    imageNamed:@"1.png"];
    }
    return self;
}
UIPageViewController
Модальный контроллер

ViewController *v = [[ViewController alloc] init];
[self presentModalViewController:v animated:YES];




[self dismissModalViewControllerAnimated:YES];
StoryBoard
(демонстрация)
Модальные View
UIAlertView

UIAlertView *a = [[UIAlertView alloc] initWithTitle:@"test"
                                            message:@"message"
                                           delegate:nil
                                  cancelButtonTitle:@"OK"
                                  otherButtonTitles:nil];
[a show];
UIAlertView

- (void)viewDidLoad
{
    UIAlertView *a = [[UIAlertView alloc]
                      initWithTitle:@"test"
                            message:@"message"
                           delegate:self
                  cancelButtonTitle:@"OK"
                  otherButtonTitles:@"1", @"2", nil];
    [a show];
}

- (void)alertView:(UIAlertView *)alertView
        clickedButtonAtIndex:(NSInteger)buttonIndex
{
    NSLog(@"%d", buttonIndex);
}
UIActionSheet
UIActionSheet
- (void)viewDidLoad
{
    UIActionSheet *s = [[UIActionSheet alloc] initWithTitle:@"test"
                                                   delegate:self
                                          cancelButtonTitle:@"Cancel"
                                     destructiveButtonTitle:@"Delete"
                                          otherButtonTitles:@"One", @"Two", nil];
    [s showInView:self.view];
}

- (void)actionSheet:(UIActionSheet *)actionSheet
        clickedButtonAtIndex:(NSInteger)buttonIndex
{
    NSLog(@"button %d", buttonIndex);
}
Варианты
интерфейсов
http://mobile-patterns.com
Tabs
Dashboard
UITableView + UINavigationController




                   Гид Покупок: Продукты
Widget




 Клуб Любителей Аудиокниг
Нестандартные интерфейсы




                       News360
Распознавание жестов
UIGestureRecognizer

UIView:
- (void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
UITapGestureRecognizer
UITapGestureRecognizer *t = [[UITapGestureRecognizer alloc]
                             initWithTarget:self
                             action:@selector(tapped)];
t.numberOfTapsRequired = 1;
t.numberOfTouchesRequired = 1;
[self.view addGestureRecognizer:t];
UIPanGestureRecognizer
UIPanGestureRecognizer *p = [[UIPanGestureRecognizer alloc]
                                   initWithTarget:self
                                   action:@selector(pan:)];
[self.view addGestureRecognizer:p];




- (void)pan:(UIPanGestureRecognizer *)sender
{
    CGPoint t = [sender translationInView:self.view];
    CGPoint v = [sender velocityInView:self.view];
    NSLog(@"%@", NSStringFromCGPoint(t));
    NSLog(@"%@", NSStringFromCGPoint(v));
}
UIPinchGestureRecognizer
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]
                                   initWithTarget:self
                                   action:@selector(pinch:)];
[self.view addGestureRecognizer:pinch];




  - (void)pinch:(UIPinchGestureRecognizer *)sender
  {
      CGFloat scale = sender.scale;
      NSLog(@"%g", scale);
  }
UIRotationGestureRecognizer
UIRotationGestureRecognizer *r = [[UIRotationGestureRecognizer alloc]
                                   initWithTarget:self
                                   action:@selector(rotate:)];
[self.view addGestureRecognizer:r];




  - (void)rotate:(UIRotationGestureRecognizer *)sender
  {
      CGFloat r = sender.rotation;
      NSLog(@"%g", r);
  }
UISwipeGestureRecognizer *s = [[UISwipeGestureRecognizer alloc]
                                     initWithTarget:self
                                     action:@selector(pan:)];
  s.direction = UISwipeGestureRecognizerDirectionLeft;
  [self.view addGestureRecognizer:s];




• UISwipeGestureRecognizer
• UILongPressGestureRecognizer
UILongPressGestureRecognizer *p = [[UISwipeGestureRecognizer alloc]
                                   initWithTarget:self
                                   action:@selector(pan:)];
p.minimumPressDuration = 0.5;
[self.view addGestureRecognizer:p];
UIGestureRecognizerDelegate

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;



- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:
(UIGestureRecognizer *)otherGestureRecognizer;



- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch;
UIGestureRecognizerState

typedef enum {
    UIGestureRecognizerStatePossible,

    UIGestureRecognizerStateBegan,

    UIGestureRecognizerStateChanged,

    UIGestureRecognizerStateEnded,

    UIGestureRecognizerStateCancelled,

    UIGestureRecognizerStateFailed,

    UIGestureRecognizerStateRecognized =
UIGestureRecognizerStateEnded
} UIGestureRecognizerState;
Анимация
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];

self.view.frame = CGRectMake(100, 100, 50, 50);

[UIView commitAnimations];




[UIView beginAnimations:nil context:nil];
self.view.alpha = 0;
[UIView commitAnimations];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationFinished)];

self.view.alpha = 0;

[UIView commitAnimations];




- (void)animationFinished
{
    //...
}
The following properties of the UIView class are
animatable:
@property frame
@property bounds
@property center
@property transform
@property alpha
@property backgroundColor
@property contentStretch
Блоки
void(^b)(void) = ^{
    NSLog(@"test");
};

b();


NSInteger(^c)(CGFloat, NSString *) = ^(CGFloat p, NSString *s){
    NSLog(@"test %g %@", p, s);
    return 10;
};

NSInteger q = c(10.5, @"abc");
Циклы ссылок
typedef void(^BasicBlock)(void);
…
@property(copy, nonatomic) BasicBlock block;
…
self.block = ^{
    [self updateWithQuestion];
};




__weak ViewController *s = self;
self.block = ^{
    [s updateWithQuestion];
};
Захват переменных
 __block NSInteger q = 123;

 BasicBlock b = ^{
     ++q;
     NSLog(@"%d", q);
 };

 b(); // 124
 b(); // 125
Анимация с блоками
[UIView animateWithDuration:0.3 animations:^{
    self.view.alpha = 0;
}];

[UIView animateWithDuration:0.3
                 animations:^{
                     self.view.alpha = 1;
                 }
                 completion:^(BOOL finished) {
                     NSLog(@"animation finished");
                 }];
Удобства с блоками
  [BlockAlertView showTitle:@"Ошибка"
                       text:@"Для изменения личных данных необходимо подключение к интернету."
               cancelButton:@"ОК"
                     action:^{
                         [s.navigationController dismissModalViewControllerAnimated:YES];
  }];




DDXMLElement *style = [[img.attributes where:^BOOL(id element) {
    DDXMLNode *attr = element;
    return [attr.name isEqualToString:@"style"];
}] firstObject];




BlockTapGestureRecognizer *tap = [[BlockTapGestureRecognizer alloc] initWithAction:^{
    [self dismissModalViewControllerAnimated:YES];
}];
[self.view addGestureRecognizer:tap];
Демонстрация
Примеры интерфейсов
из живых приложений
Кастомный navBar
Несколько navBar items
Кастомный tabBar
Произвольный tabBar
Rich text
Вопросы
Что нужно сделать, чтобы
распознать нажатие на UIView?
Что нужно сделать, чтобы
    распознать нажатие на UIView?


    Создать UITapGestureRecognizer,
добавить его через addGestureRecognizer.
Как по нажатию на кнопку анимированно передвинуть
 эту кнопку в другой угол экрана, а в конце анимации
                  изменить ее цвет?
Как по нажатию на кнопку анимированно передвинуть
 эту кнопку в другой угол экрана, а в конце анимации
                  изменить ее цвет?

    С помощью метода UIView animateWithDuration.
         В блоке анимации изменить фрейм,
          в блоке completion изменить цвет.
Как во всем приложении поменять фон у
            UINavigationBar?
Как во всем приложении поменять фон у
                  UINavigationBar?
 Для iOS5 достаточно воспользоваться статическим
       свойством appearance у UINavigationBar.

Для iOS4 надо создать категорию и подменить метод   -

              (void)drawRect:(CGRect)rect
Задание

                                   •   два таба

                                       •   список городов из файла

                                           •   при выборе строки: карта с
                                               указанием на этот город

                                       •   список сайтов из файла

                                           •   при выборе строки: страница
                                               в webView с этим сайтом

На всех экранах:
Кнопка «Инфо», по нажатию alert с вопросом «да/нет». Если да - открывается
modalViewController c текстом «об авторе»
Спасибо
     Глеб Тарасов
     gleb34@gmail.com
     twitter.com/pilot34

Школа-Студия разработки приложений для iOS. 3 лекция. Интерфейсы, прололжение