Arhn - архитектура программирования

Анимация перехода похожа на открытие приложения в iOS 7: размер кадра контроллера просмотра не изменяется.

Я хочу создать анимацию перехода, аналогичную открытию приложения в iOS 7. Теперь я рассматриваю этот подход: Реализация без перехода, но столкнулся с проблемой: при реализации в пользовательском переходе код не может изменить размер кадра контроллера представления, который является основной частью анимации. Как я вижу, он применяет позицию контроллера просмотра, но не может изменить его размер. Правильно ли я понимаю, что свойство viewcontroller.view.frame не может быть анимировано и должно оставаться постоянным и равным размеру экрана устройства? Я уже реализовал что-то подобное с CGAffineTransformMakeScale, но это немного странно, поэтому я ищу лучшее решение. Ниже я вставляю код, который использую для перехода.

#import "ZoomSegue.h"
#import "MiniMapViewController.h"
#import "InteractiveMapViewController.h"

@implementation ZoomSegue

- (void)perform {
    InteractiveMapViewController *sourceViewController = self.sourceViewController;
    MiniMapViewController *destinationViewController = self.destinationViewController;

    destinationViewController.view.alpha = 0.0f;
    destinationViewController.view.hidden = NO;


    //Just to check, lets make view really small. Position it to the center we get from the segue.
    destinationViewController.view.frame = CGRectMake(_originatingPoint.x, _originatingPoint.y, 60.0f, 60.0f);

    [sourceViewController.view addSubview:destinationViewController.view];


    float animationDuration = 1.5f;

    [UIView animateWithDuration:animationDuration/2.0f animations:^{
        destinationViewController.view.alpha = 1.0f;
    }];



    [UIView animateWithDuration:animationDuration animations:^{


        //Just to check, lets make view very big. It does not work, although, the view goes to the upper left corner, so position works, but not the size
        CGRect x  = CGRectMake(0.0f, 0.0f, 9590.0f, 91366.0f);

        destinationViewController.view.frame = x;
    }];
}
@end

Ответы:


1

Я не знаю, правы ли вы, но в любом случае лучший способ сделать это — использовать представление моментального снимка. Этот код помещает небольшой снимок в центр экрана, а затем расширяет его до полного размера,

- (void)perform {
    UIView *sourceView = ((UIViewController *)self.sourceViewController).view;
    UIView *destinationView = [((UIViewController *)self.destinationViewController).view snapshotViewAfterScreenUpdates:YES];
    destinationView.frame = CGRectMake(0, 0, 5, 5);
    destinationView.center = CGPointMake(sourceView.center.x, sourceView.center.y);
    [sourceView addSubview:destinationView];

    [UIView animateWithDuration:1
                     animations:^{
                         destinationView.frame = sourceView.frame;
                     }
                     completion:^(BOOL finished) {
                         [[self sourceViewController] presentViewController:[self destinationViewController] animated:NO completion:nil];
                     }];

}

После редактирования:

Вот перевод кода по предоставленной вами ссылке, который преобразует эту анимацию в переход,

-(void)perform {
    CGFloat duration = .25;
    UIViewController *source = self.sourceViewController;
    UIView *bg = [source.view snapshotViewAfterScreenUpdates:YES];
    bg.frame = UIScreen.mainScreen.bounds;
    UIViewController *dest = self.destinationViewController;
    UIView *icon = [dest.view snapshotViewAfterScreenUpdates:YES];
    icon.frame = self.iconFrame;
    icon.alpha = 0.0f;
    [source.view addSubview:bg];
    [source.view addSubview:icon];
    [UIView animateWithDuration:duration animations:^{
        icon.alpha = 1.0f;
    }];
    [UIView animateWithDuration:duration*2 animations:^{ 
        icon.frame = UIScreen.mainScreen.bounds;
        bg.frame = [self zoomedRect];
    } completion:^(BOOL finished) {
        [source presentViewController:dest animated:NO completion:nil];
        [bg removeFromSuperview];
        [icon removeFromSuperview];
    }];

}



- (CGRect)zoomedRect {
    float screenWidth = UIScreen.mainScreen.bounds.size.width;
    float screenHeight = UIScreen.mainScreen.bounds.size.height;

    float size = screenWidth / self.iconFrame.size.width;
    float x = screenWidth/2 - (CGRectGetMidX(self.iconFrame) * size);
    float y = screenHeight/2 - (CGRectGetMidY(self.iconFrame) * size);

    return CGRectMake(x, y, screenWidth * size, screenHeight * size);
}

У меня есть свойство CGRect, iconFrame в файле .h перехода. Я выполнил переход от распознавателя жестов касания, который был прикреплен к значку, который будет развернут. Вам нужно передать кадр этого значка в переход, что я делаю в методе prepareForSegue исходного контроллера представления,

-(void)prepareForSegue:(SpringboardSegue *)segue sender:(UITapGestureRecognizer *)sender {
    segue.iconFrame = sender.view.frame;
}
23.07.2014
  • Спасибо! У меня была такая идея, но сделать какие-то скриншоты и использовать как UIImageView. Сейчас попробую вашу идею. 24.07.2014
  • Он работает почти так, как должен быть. Теперь мне нужно, чтобы sourceView также немного увеличивал масштаб, но не затрагивая его дочерние элементы. Можно ли произвести эти преобразования относительно какой-то статической точки? 24.07.2014
  • @RichardTopchiy, я не думаю, что это возможно, но не могли бы вы немного подробнее объяснить, что вы хотите. 24.07.2014
  • Вы можете увидеть это здесь, на анимации: stackoverflow.com/questions/19486506/ 24.07.2014
  • @RichardTopchiy, не уверен, что вы имеете в виду, говоря, что не влияет на его детей. Мне кажется, что эта анимация выполняется путем добавления небольшого снимка нового представления поверх значка, затем расширения и перемещения снимка исходного представления (у которого есть другой снимок в качестве подвида) таким образом, что маленький снимок заканчивается по центру и на весь экран. 24.07.2014
  • Да, вы правы, но проверьте фон: это другой вид, и он независимо трансформируется в больший масштаб. 24.07.2014
  • @RichardTopchiy, я обновил свой ответ кодом, который преобразует код по ссылке, которую вы дали, в переход. 24.07.2014
  • Спасибо! Пожалуйста, также добавьте что-то вроде [icon removeFromSuperview]; [bg removeFromSuperview]; после этой строки: [source presentViewController:dest animated:NO completion:nil];, потому что, если эти снимки не удаляются из своего супер, они появляются после раскручивания перехода. 24.07.2014
  • @RichardTopchiy, спасибо за это. Я добавил это в свой ответ. 24.07.2014

  • 2

    Я перевел тот же код в SWIFT.

    class CustomOpenSegue: UIStoryboardSegue {
       var iconFrame = CGRect()
    
       override func perform(){
    
        var sourceViewController: UIViewController = self.sourceViewController as UIViewController
        var bg:UIView = sourceViewController.view.snapshotViewAfterScreenUpdates(true)
        bg.frame = UIScreen.mainScreen().bounds
        var destinationViewController: UIViewController = self.destinationViewController as UIViewController
        var icon:UIView = destinationViewController.view.snapshotViewAfterScreenUpdates(true)
        icon.frame = self.iconFrame
        icon.alpha = 0.0
    
        sourceViewController.view.addSubview(icon)
    
    
    
        UIView.animateWithDuration(0.25, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
            icon.alpha = 1.0
        }, completion: nil )
    
        UIView.animateWithDuration(0.5, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
                () -> Void in
                icon.frame = UIScreen.mainScreen().bounds
                bg.frame = self.zoomedRect
    
        }) { (finished) -> Void in
    
            sourceViewController.navigationController?.pushViewController(destinationViewController, animated: false)
            icon.removeFromSuperview()
            bg.removeFromSuperview()
    
    
            }
        }
    
    
        var zoomedRect:CGRect{
            var screenWidth = UIScreen.mainScreen().bounds.size.width
            var screenHeight = UIScreen.mainScreen().bounds.size.height
    
            var size = screenWidth / self.iconFrame.size.width
            var x = screenWidth / 2 - CGRectGetMidX(self.iconFrame) * size
            var y = screenHeight / 2 - CGRectGetMidY(self.iconFrame) * size
    
            return CGRectMake(x, y, screenWidth * size, screenHeight * size)
        }
    }
    

    И вот как вы это называете:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue is CustomOpenSegue{
        let customOpenSegue = segue as CustomOpenSegue
        customOpenSegue.iconFrame = self.mapButtonFrame!
        }
    }
    
    29.04.2015
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..