Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bottomLayoutGuide to support iPhone 10 home button #38

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Example/QRCodeReaderViewControllerExample/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
<true/>
<key>NSCameraUsageDescription</key>
<string>The camera is needed to scan QRCode</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
Expand Down
48 changes: 48 additions & 0 deletions Example/QRCodeReaderViewControllerExample/LaunchScreen.storyboard
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Copyright © 2017 Yannick Loriot. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="obG-Y5-kRd">
<rect key="frame" x="0.0" y="626.5" width="375" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="QRCodeReaderViewControllerExample" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
<rect key="frame" x="0.0" y="202" width="375" height="43"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="obG-Y5-kRd" secondAttribute="centerX" id="5cz-MP-9tL"/>
<constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="GJd-Yh-RWb" secondAttribute="centerX" id="Q3B-4B-g5h"/>
<constraint firstItem="obG-Y5-kRd" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" constant="20" symbolic="YES" id="SfN-ll-jLj"/>
<constraint firstAttribute="bottom" secondItem="obG-Y5-kRd" secondAttribute="bottom" constant="20" id="Y44-ml-fuU"/>
<constraint firstItem="GJd-Yh-RWb" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="bottom" multiplier="1/3" constant="1" id="moa-c2-u7t"/>
<constraint firstItem="GJd-Yh-RWb" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" constant="20" symbolic="YES" id="x7j-FC-K8j"/>
</constraints>
<viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
64 changes: 34 additions & 30 deletions QRCodeReaderViewController/QRCodeReaderViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ @implementation QRCodeReaderViewController
- (void)dealloc
{
[self stopScanning];

[[NSNotificationCenter defaultCenter] removeObserver:self];
}

Expand All @@ -70,7 +70,7 @@ - (id)initWithMetadataObjectTypes:(NSArray *)metadataObjectTypes
- (id)initWithCancelButtonTitle:(NSString *)cancelTitle metadataObjectTypes:(NSArray *)metadataObjectTypes
{
QRCodeReader *reader = [QRCodeReader readerWithMetadataObjectTypes:metadataObjectTypes];

return [self initWithCancelButtonTitle:cancelTitle codeReader:reader];
}

Expand All @@ -92,25 +92,25 @@ - (id)initWithCancelButtonTitle:(nullable NSString *)cancelTitle codeReader:(non
self.startScanningAtLoad = startScanningAtLoad;
self.showSwitchCameraButton = showSwitchCameraButton;
self.showTorchButton = showTorchButton;

if (cancelTitle == nil) {
cancelTitle = NSLocalizedString(@"Cancel", @"Cancel");
}

[self setupUIComponentsWithCancelButtonTitle:cancelTitle];
[self setupAutoLayoutConstraints];

[_cameraView.layer insertSublayer:_codeReader.previewLayer atIndex:0];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];

__weak __typeof__(self) weakSelf = self;

[codeReader setCompletionWithBlock:^(NSString *resultAsString) {
if (weakSelf.completionBlock != nil) {
weakSelf.completionBlock(resultAsString);
}

if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(reader:didScanResult:)]) {
[weakSelf.delegate reader:weakSelf didScanResult:resultAsString];
}
Expand Down Expand Up @@ -152,7 +152,7 @@ + (instancetype)readerWithCancelButtonTitle:(NSString *)cancelTitle codeReader:(
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];

if (_startScanningAtLoad) {
[self startScanning];
}
Expand All @@ -161,14 +161,14 @@ - (void)viewWillAppear:(BOOL)animated
- (void)viewWillDisappear:(BOOL)animated
{
[self stopScanning];

[super viewWillDisappear:animated];
}

- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];

_codeReader.previewLayer.frame = self.view.bounds;
}

Expand All @@ -192,10 +192,10 @@ - (void)stopScanning {
- (void)orientationChanged:(NSNotification *)notification
{
[_cameraView setNeedsDisplay];

if (_codeReader.previewLayer.connection.isVideoOrientationSupported) {
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];

_codeReader.previewLayer.connection.videoOrientation = [QRCodeReader videoOrientationFromInterfaceOrientation:
orientation];
}
Expand All @@ -216,31 +216,31 @@ - (void)setupUIComponentsWithCancelButtonTitle:(NSString *)cancelButtonTitle
_cameraView.translatesAutoresizingMaskIntoConstraints = NO;
_cameraView.clipsToBounds = YES;
[self.view addSubview:_cameraView];

[_codeReader.previewLayer setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];

if ([_codeReader.previewLayer.connection isVideoOrientationSupported]) {
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];

_codeReader.previewLayer.connection.videoOrientation = [QRCodeReader videoOrientationFromInterfaceOrientation:orientation];
}

if (_showSwitchCameraButton && [_codeReader hasFrontDevice]) {
_switchCameraButton = [[QRCameraSwitchButton alloc] init];

[_switchCameraButton setTranslatesAutoresizingMaskIntoConstraints:false];
[_switchCameraButton addTarget:self action:@selector(switchCameraAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_switchCameraButton];
}

if (_showTorchButton && [_codeReader isTorchAvailable]) {
_toggleTorchButton = [[QRToggleTorchButton alloc] init];

[_toggleTorchButton setTranslatesAutoresizingMaskIntoConstraints:false];
[_toggleTorchButton addTarget:self action:@selector(toggleTorchAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_toggleTorchButton];
}

self.cancelButton = [[UIButton alloc] init];
_cancelButton.translatesAutoresizingMaskIntoConstraints = NO;
[_cancelButton setTitle:cancelButtonTitle forState:UIControlStateNormal];
Expand All @@ -251,29 +251,33 @@ - (void)setupUIComponentsWithCancelButtonTitle:(NSString *)cancelButtonTitle

- (void)setupAutoLayoutConstraints
{
NSDictionary *views = NSDictionaryOfVariableBindings(_cameraView, _cancelButton);

id bottomLayoutGuide = self.bottomLayoutGuide;
NSDictionary *views = NSDictionaryOfVariableBindings(_cameraView, _cancelButton, bottomLayoutGuide);

// add bottomLayoutGuide for not overlaying the "home button" of the iphone x
NSString *constraintString = [NSString stringWithFormat:@"V:|[_cameraView][_cancelButton(40)]-[bottomLayoutGuide]"];
[self.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_cameraView][_cancelButton(40)]|" options:0 metrics:nil views:views]];
[NSLayoutConstraint constraintsWithVisualFormat:constraintString options:0 metrics:nil views:views]];

[self.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_cameraView]|" options:0 metrics:nil views:views]];
[self.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_cancelButton]-|" options:0 metrics:nil views:views]];

id topLayoutGuide = self.topLayoutGuide;

if (_switchCameraButton) {
NSDictionary *switchViews = NSDictionaryOfVariableBindings(_switchCameraButton, topLayoutGuide);

[self.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topLayoutGuide]-[_switchCameraButton(50)]" options:0 metrics:nil views:switchViews]];
[self.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:@"H:[_switchCameraButton(70)]|" options:0 metrics:nil views:switchViews]];
}

if (_toggleTorchButton) {
NSDictionary *torchViews = NSDictionaryOfVariableBindings(_toggleTorchButton, topLayoutGuide);

[self.view addConstraints:
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topLayoutGuide]-[_toggleTorchButton(50)]" options:0 metrics:nil views:torchViews]];
[self.view addConstraints:
Expand All @@ -291,11 +295,11 @@ - (void)switchDeviceInput
- (void)cancelAction:(UIButton *)button
{
[_codeReader stopScanning];

if (_completionBlock) {
_completionBlock(nil);
}

if (_delegate && [_delegate respondsToSelector:@selector(readerDidCancel:)]) {
[_delegate readerDidCancel:self];
}
Expand Down