diff --git a/Sources/BarcodeScannerController.swift b/Sources/BarcodeScannerController.swift index f00d228..5d71b5b 100644 --- a/Sources/BarcodeScannerController.swift +++ b/Sources/BarcodeScannerController.swift @@ -29,8 +29,8 @@ public protocol BarcodeScannerDismissalDelegate: class { */ open class BarcodeScannerController: UIViewController { - /// Video capture device. - lazy var captureDevice: AVCaptureDevice = AVCaptureDevice.default(for: AVMediaType.video)! + /// Video capture device. This may be nil when running in Simulator. + lazy var captureDevice: AVCaptureDevice! = AVCaptureDevice.default(for: AVMediaType.video) /// Capture session. lazy var captureSession: AVCaptureSession = AVCaptureSession() @@ -124,13 +124,13 @@ open class BarcodeScannerController: UIViewController { }) } } - + public var barCodeFocusViewType: FocusViewType = .animated /// The current torch mode on the capture device. var torchMode: TorchMode = .off { didSet { - guard captureDevice.hasFlash else { return } + guard let captureDevice = captureDevice, captureDevice.hasFlash else { return } do { try captureDevice.lockForConfiguration() @@ -264,6 +264,10 @@ open class BarcodeScannerController: UIViewController { Sets up capture input, output and session. */ func setupSession() { + guard let captureDevice = captureDevice else { + return + } + do { let input = try AVCaptureDeviceInput(device: captureDevice) captureSession.addInput(input) @@ -320,8 +324,27 @@ open class BarcodeScannerController: UIViewController { // MARK: - Layout func setupFrame() { - headerView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 64) - flashButton.frame = CGRect(x: view.frame.width - 50, y: 73, width: 37, height: 37) + let flashButtonSize: CGFloat = 37 + let isLandscape = view.frame.width > view.frame.height + + var rightSafeAreaInset: CGFloat = 0 + var topSafeAreaInset: CGFloat = 0 + if #available(iOS 11.0, *) { + rightSafeAreaInset = view.safeAreaInsets.right + topSafeAreaInset = view.safeAreaInsets.top + } + + var navbarSize: CGFloat = 0 + if (isLandscape) { + navbarSize = 32 + } + else { + // On iPhone X devices, extend the size of the top nav bar + navbarSize = topSafeAreaInset > 0 ? 88 : 64 + } + + headerView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: navbarSize) + flashButton.frame = CGRect(x: view.frame.width - 50 - rightSafeAreaInset, y: navbarSize + 10 + (flashButtonSize / 2), width: flashButtonSize, height: flashButtonSize) infoView.frame = infoFrame if let videoPreviewLayer = videoPreviewLayer { diff --git a/Sources/HeaderView.swift b/Sources/HeaderView.swift index 05236b0..b597c8f 100644 --- a/Sources/HeaderView.swift +++ b/Sources/HeaderView.swift @@ -61,16 +61,24 @@ class HeaderView: UIView { override func layoutSubviews() { super.layoutSubviews() - let padding: CGFloat = 8 + var leftSafeAreaPadding: CGFloat = 0 + var topSafeAreaPadding: CGFloat = 0 + if #available(iOS 11, *) { + leftSafeAreaPadding = safeAreaInsets.left + topSafeAreaPadding = safeAreaInsets.top + } + + let leadingPadding: CGFloat = 15 + leftSafeAreaPadding + let topPadding: CGFloat = 8 + topSafeAreaPadding let labelHeight: CGFloat = 40 - + button.sizeToFit() - button.frame.origin = CGPoint(x: 15, - y: ((frame.height - button.frame.height) / 2) + padding) + button.frame.origin = CGPoint(x: leadingPadding, + y: ((frame.height - button.frame.height) / 2) + topPadding) label.frame = CGRect( - x: 0, y: ((frame.height - labelHeight) / 2) + padding, + x: 0, y: ((frame.height - labelHeight) / 2) + topPadding, width: frame.width, height: labelHeight) } diff --git a/Sources/InfoView.swift b/Sources/InfoView.swift index 373542f..f159b4c 100644 --- a/Sources/InfoView.swift +++ b/Sources/InfoView.swift @@ -85,6 +85,14 @@ class InfoView: UIVisualEffectView { */ override func layoutSubviews() { super.layoutSubviews() + + var leftSafeAreaPadding: CGFloat = 0 + var rightSafeAreaPadding: CGFloat = 0 + + if #available(iOS 11.0, *) { + leftSafeAreaPadding = safeAreaInsets.left + rightSafeAreaPadding = safeAreaInsets.right + } let padding: CGFloat = 10 let labelHeight: CGFloat = 40 @@ -93,7 +101,7 @@ class InfoView: UIVisualEffectView { if status.state != .processing && status.state != .notFound { imageView.frame = CGRect( - x: padding, + x: padding + leftSafeAreaPadding, y: (frame.height - imageSize.height) / 2, width: imageSize.width, height: imageSize.height) @@ -101,7 +109,7 @@ class InfoView: UIVisualEffectView { label.frame = CGRect( x: imageView.frame.maxX + padding, y: 0, - width: frame.width - imageView.frame.maxX - 2 * padding, + width: frame.width - imageView.frame.maxX - 2 * padding - rightSafeAreaPadding, height: frame.height) } else { imageView.frame = CGRect(