Скрыть / показать iPhone Iris / Анимация затвора - PullRequest
10 голосов
/ 29 июня 2010

Я не могу скрыть анимацию открытия затвора камеры iphone для моего приложения.Я использую UIImagePickerController для доступа к камере iphone и использую свои собственные оверлейные контроллеры.Есть ли способ удалить начальную анимацию затвора (также известную как Iris) при запуске камеры.Спасибо

[РЕДАКТИРОВАТЬ]

Для тех, кто хочет узнать, как изменить анимацию диафрагмы камеры.

Следующая функция вызывается до запуска анимации диафрагмы камеры.

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    // Here is were I make the camera preview fit the entire screen. 
    // This might violate the "don't change the view hierarchy"-rule. 
    // So I am not sure if it is valid for App Store commitment.
    // However, the NSLogs are used to
    // figure out which subview is the actual Camera Preview which turns out 
    // to be the PLPreviewView. (uncomment to se the printouts).
    // Change it's size to fit the entire screen (and scale it accordingly
    // to avoid distorted image

    NSLog(@"WillShowViewController called...");

    NSLog(@"VC:view:subviews\n %@\n\n", [[viewController view] subviews]);

    NSLog(@"VC:view:PLCameraView:subviews\n %@\n\n", [[[[viewController view] subviews] objectAtIndex: 0] subviews]);

    NSLog(@"VC:view:PLCameraView:PLPreviewView:subviews\n %@\n\n", [[[[[[viewController view] subviews] objectAtIndex: 0] subviews] objectAtIndex: 0] subviews]);
    NSLog(@"VC:view:PLCameraView:PLCropOverLay:subviews\n %@\n\n", [[[[[[viewController view] subviews] objectAtIndex: 0] subviews] objectAtIndex: 1] subviews]);
    NSLog(@"VC:view:PLCameraView:UIImageView:subviews\n %@\n\n", [[[[[[viewController view] subviews] objectAtIndex: 0] subviews] objectAtIndex: 2] subviews]);

}

В вышеприведенной функции вы можете пройти через каждый слой, используя обычный синтаксис NSMuatableArray, такой как objectAtIndex

, надеюсь, это может вам помочь.

Анкур

Ответы [ 7 ]

5 голосов
/ 15 июля 2010

Используя этот ответ в качестве отправной точки, я наконец-то решил эту проблему:

ПРИМЕЧАНИЕ. Это явно не соответствует 3.3.1.

  1. Прослушайте UINavigationControllerDidShowViewControllerNotification на вашем UIImagePickerController и PLCameraViewIrisAnimationDidEndNotification в глобальном масштабе.

  2. Проследите иерархию представления (начиная сглавная UIWindow) ищу PLCameraView.Сохраните индекс вида относительно основного UIWindow, так как он понадобится вам позже.

  3. Удалите PLCameraView из его superView.При желании вставьте свой собственный вид с глобальным индексом 0.

  4. Когда анимация радужной оболочки закончится, удалите свой вид и снова добавьте PLCameraView в исходный индекс.

1 голос
/ 08 ноября 2012

Натолкнулся на подобное: я хотел, чтобы спуск затвора появлялся, когда я делаю снимок, вызванный кнопкой в ​​self.cameraOverlayView UIImagePickerController. Пришел на эту страницу, провел дополнительное исследование и пришел к этому решению.

Справка:

@interface MyController : UIImagePickerController
...    
- (id) init {
...
    self.cameraOverlayView = _my_overlay_;
    self.showsCameraControls = NO;
...
}
... 
- (void) onMyShutterButton {
    [self takePicture]; 
        // You want the shutter animation to happen now.
        // .. but it does not.
}

Решение:

// Some constants for the iris view and selector
NSString* kIrisViewClassName = @"PLCameraIrisAnimationView";
SEL kIrisSelector = NSSelectorFromString(@"animateIrisOpen");

@implementation MyController {
...
    UIView* iris_;
}
- (void) viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // Find the iris view in the siblings of your overlay view
    for (UIView* view in self.cameraOverlayView.superview.subviews) {
        if ([kIrisViewClassName isEqualToString:[[view class] description]]) {
            // It will be hidden by 'self.showsCameraControls = NO'.
            view.hidden = false;   
            // Extra precautions - as this is undocumented.  
            if ([view respondsToSelector:kIrisSelector]) {
                iris_ = view;
            }
            break;
        }
    }
}
- (void) animateIrisOpen {
    if (iris_) {
        [iris_ performSelector:kIrisSelector];
    }
}
...
- (void) onMyShutterButton {
    [self takePicture]; 
    [self animateIrisOpen];   // Voila - the shutter happens
}
0 голосов
/ 12 сентября 2013

Чтобы пояснить ответ Каталина (что было здорово, между прочим), я обнаружил, что если вы немного измените метод animateIrisOpen, презентация будет намного лучше ... но заметна.

- (void) animateIrisOpen {
    if (iris_) {
        iris_.hidden = NO;
        [iris_ performSelector:kIrisSelector];
    }
}
0 голосов
/ 05 мая 2011

Ответ Джошвы полностью скрывает весь вид камеры на время анимации радужной оболочки. Для моих целей мне нужен был видимый вид с камеры, просто без анимации диафрагмы. Я смог сделать это с небольшой настройкой его метода. Как уже отмечали другие, это может или не может быть разрешено в магазине приложений, так как мы работаем с иерархией представлений, а также слушаем недокументированные уведомления.

Требуется 3 ивара:

UIImagePickerController *imagePickerController;
UIView *plCameraIrisAnimationView;  // view that animates the opening/closing of the iris
UIImageView *cameraIrisImageView;  // static image of the closed iris

Скрыть скрытое изображение радужной оболочки и удалить вид анимации. Я попытался просто скрыть вид анимации, но анимация все еще была видна:

- (void)receivedNavigationControllerDidShowViewControllerNotification:(NSNotification *)notification {
    UIView *view = imagePickerController.view;
    [plCameraIrisAnimationView release];
    plCameraIrisAnimationView = nil;
    cameraIrisImageView = nil;
    while (view.subviews.count && (view = [view.subviews objectAtIndex:0])) {
        if ([[[view class] description] isEqualToString:@"PLCameraView"]) {
            for (UIView *subview in view.subviews) {
                if ([subview isKindOfClass:[UIImageView class]]) {
                    cameraIrisImageView = (UIImageView *)subview;
                }
                else if ([[[subview class] description] isEqualToString:@"PLCropOverlay"]) {
                    for (UIView *subsubview in subview.subviews) {
                        if ([[[subsubview class] description] isEqualToString:@"PLCameraIrisAnimationView"]) {
                            plCameraIrisAnimationView = [subsubview retain];
                        }
                    }
                }
            }
        }
    }
    cameraIrisImageView.hidden = YES;
    [plCameraIrisAnimationView removeFromSuperview];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UINavigationControllerDidShowViewControllerNotification" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedPLCameraViewIrisAnimationDidEndNotification:) name:@"PLCameraViewIrisAnimationDidEndNotification" object:nil];
}

Когда анимация закончится, раскройте изображение радужной оболочки и снова добавьте вид анимации:

- (void)receivedPLCameraViewIrisAnimationDidEndNotification:(NSNotification *)notification {
    cameraIrisImageView.hidden = NO;

    UIView *view = imagePickerController.view;
    while (view.subviews.count && (view = [view.subviews objectAtIndex:0])) {
        if ([[[view class] description] isEqualToString:@"PLCameraView"]) {
            for (UIView *subview in view.subviews) {
                if ([[[subview class] description] isEqualToString:@"PLCropOverlay"]) {
                    [subview insertSubview:plCameraIrisAnimationView atIndex:1];
                    [plCameraIrisAnimationView release];
                    plCameraIrisAnimationView = nil;
                    break;
                }
            }
        }
    }

    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"PLCameraViewIrisAnimationDidEndNotification" object:nil];
}
0 голосов
/ 23 июля 2010

Следующая функция вызывается до запуска анимации диафрагмы камеры.

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    // Here is were I make the camera preview fit the entire screen. 
    // This might violate the "don't change the view hierarchy"-rule. 
    // So I am not sure if it is valid for App Store commitment.
    // However, the NSLogs are used to
    // figure out which subview is the actual Camera Preview which turns out 
    // to be the PLPreviewView. (uncomment to se the printouts).
    // Change it's size to fit the entire screen (and scale it accordingly
    // to avoid distorted image

    NSLog(@"WillShowViewController called...");

    NSLog(@"VC:view:subviews\n %@\n\n", [[viewController view] subviews]);

    NSLog(@"VC:view:PLCameraView:subviews\n %@\n\n", [[[[viewController view] subviews] objectAtIndex: 0] subviews]);

    NSLog(@"VC:view:PLCameraView:PLPreviewView:subviews\n %@\n\n", [[[[[[viewController view] subviews] objectAtIndex: 0] subviews] objectAtIndex: 0] subviews]);
    NSLog(@"VC:view:PLCameraView:PLCropOverLay:subviews\n %@\n\n", [[[[[[viewController view] subviews] objectAtIndex: 0] subviews] objectAtIndex: 1] subviews]);
    NSLog(@"VC:view:PLCameraView:UIImageView:subviews\n %@\n\n", [[[[[[viewController view] subviews] objectAtIndex: 0] subviews] objectAtIndex: 2] subviews]);

}

В вышеприведенной функции вы можете проходить через каждый слой, используя обычный синтаксис NSMuatableArray, например objectAtIndex

может помочь вам.

С уважением,

Анкур

0 голосов
/ 21 июля 2010

Извините, что ответил так поздно.Я нашел решение для этой скважины, поэкспериментировал с иерархией представлений камеры и добавил свой собственный слой поверх всего.Там произошла анимация, и как только затвор был открыт, самый верхний слой был удален.Если кому-то понадобится дополнительная помощь по коду, сообщите мне, я предоставлю точные шаги и синтаксис.

-Ankur

0 голосов
/ 13 июля 2010

Я немного обдумал это, но отправлял различные комбинации методов жизненного цикла представления в средство выбора изображений.(viewWillAppear, viewDidAppear и т. д.) Но я не помню, какие из них в итоге заработали.

...