문제

I'm trying to programatically calculate the height of the top and bottom tool bars in the UIImagePickerController view.

Basically, I'm referring to the black regions that contain the camera controls at the top and the round shutter button at the bottom. Is there a way to do this?

Sample image below

도움이 되었습니까?

해결책

You can do it with the picture ratio. Best photo quality is 3:4, so if it's on this setting, apple adjusts the view so it displays the entire photo while maintaining the aspect ratio. I'm pretty sure you can use that to calculate the height like this:

CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
// at current screenwidth, 'previewHeight' is the height necessary to maintain the aspect ratio
CGFloat previewHeight = screenWidth + (screenWidth / 3);
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
CGFloat totalBlack = screenHeight - previewHeight;
CGFloat heightOfBlackTopAndBottom = totalBlack / 2;
NSLog(@"Height is: %f", heightOfBlackTopAndBottom);

It could probably be more optimized, but I think this is more clear for demonstration of what is happening. Also be aware of potential differences in landscape mode.

다른 팁

I've been facing the same problem, as I had to add an overlay on top of UIImagePickerController. And I've solved the issue by iterating subviews of UIImagePickerController's view, until I get the one I needed. Here an example:

- (void)updateOverlayPosition:(UIView *)superView {
    for (UIView *subview in superView.subviews) {
        //CMKTopBar is the class of top view
        if ([subview isKindOfClass:NSClassFromString(@"CMKTopBar")]) {
            self.defaultRect = CGRectMake(0,
                                          subview.frame.size.height,
                                          sizeOfYourOverlay,
                                          sizeOfYourOverlay);

            self.overLayView.frame = self.defaultRect;
        } else if ([subview isKindOfClass:NSClassFromString(@"PLCropOverlayBottomBar")]) {
            //after picture is taken, bottom bar vill appear with picture preview
            static const CGFloat diff = 2;

            self.alterRect = CGRectMake(0,
                                        [UIScreen mainScreen].bounds.size.height - sizeOfYourOverlay - subview.frame.size.height + diff,
                                        sizeOfYourOverlay,
                                        sizeOfYourOverlay);
        } else {
            [self updateOverlayPosition:subview];
        }
    }
}

You can also get all view's class name with View Hierarchy tool http://cloud.obodev.com/3h2m3x351G0Q

Important moment! Before itereting subviews, of UIImagePickerController's view, make sure it was already presented

- (void)showPicker {
    __weak typeof(self) weakSelf = self;

    [self presentViewController:self.pickerController
                       animated:YES
                     completion:^{
        __strong typeof(weakSelf) strongSelf = weakSelf;
        [strongSelf updateOverlayPosition:strongSelf.pickerController.view];
    }];
}

If you want to get the height of each (top and bottom) bar separately (not sum of the heights):

Swift 3 code:

class YourImagePickerController: UIImagePickerController {
    override func viewDidLayoutSubviews() {
        if let bottomBarView = self.view.findFirstSubview("CAMBottomBar"){
            print("bottom bar height: \(bottomBarView.frame.height)")
        }
    }
}

extension UIView {
    func findFirstSubview(_ className:String) -> UIView? {
        super.viewDidLayoutSubviews()
        for subview in self.subviewsRecursive() {
            if subview.className() == className {
                return subview
            }
        }
        return nil
    }

    func subviewsRecursive() -> [UIView] {
        return subviews + subviews.flatMap { $0.subviewsRecursive() }
    }
}

extension NSObject {
    func className() -> String {
        return String(describing: type(of: self))
    }
}

The name of the top bar class is CAMTopBar

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top