├── Package.swift ├── ScreenCorners.podspec ├── Sources └── ScreenCorners │ └── UIScreen+ScreenCorners.swift ├── LICENSE ├── .gitignore └── README.md /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.1 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "ScreenCorners", 7 | platforms: [ 8 | .iOS(.v12), 9 | ], 10 | products: [ 11 | .library(name: "ScreenCorners", targets: ["ScreenCorners"]), 12 | ], 13 | targets: [ 14 | .target(name: "ScreenCorners"), 15 | ] 16 | ) 17 | -------------------------------------------------------------------------------- /ScreenCorners.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'ScreenCorners' 3 | spec.version = '1.0.1' 4 | spec.license = { :type => 'MIT' } 5 | spec.homepage = 'https://github.com/kylebshr/ScreenCorners' 6 | spec.authors = { 'Kyle Bashour' => 'kylebshr@me.com' } 7 | spec.summary = 'Screen corner radius for iOS devices.' 8 | spec.source = { :git => 'https://github.com/kylebshr/ScreenCorners.git', :tag => 'v1.0.1' } 9 | 10 | spec.swift_version = '5.1' 11 | spec.ios.deployment_target = '12.1' 12 | 13 | spec.source_files = 'Sources/ScreenCorners/*.swift' 14 | spec.ios.framework = 'UIKit' 15 | end 16 | -------------------------------------------------------------------------------- /Sources/ScreenCorners/UIScreen+ScreenCorners.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIScreen+ScreenCorners.swift 3 | // 4 | // 5 | // Created by Kyle Bashour on 10/24/20. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIScreen { 11 | private static let cornerRadiusKey: String = { 12 | let components = ["Radius", "Corner", "display", "_"] 13 | return components.reversed().joined() 14 | }() 15 | 16 | /// The corner radius of the display. Uses a private property of `UIScreen`, 17 | /// and may report 0 if the API changes. 18 | public var displayCornerRadius: CGFloat { 19 | guard let cornerRadius = self.value(forKey: Self.cornerRadiusKey) as? CGFloat else { 20 | assertionFailure("Failed to detect screen corner radius") 21 | return 0 22 | } 23 | 24 | return cornerRadius 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Kyle Bashour 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | Packages/ 41 | Package.pins 42 | Package.resolved 43 | *.xcodeproj 44 | 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ScreenCorners 2 | 3 | Check the corner radius of an iPhone / iPad display. 4 | 5 | ### Implementation 6 | 7 | Adds a `displayCornerRadius` property to `UIScreen`, which reads the private `_displayCornerRadius`. The selector somewhat obscured, which usually means it will get past app review. However, use at your own risk! 8 | 9 | #### Why didn't you hardcode the values instead? 10 | 11 | I didn't want to use model identifiers (i.e., `iPhone10,2`) and miss an international variant, or have to update it when new devices launch. 12 | 13 | It's also tricky to use screen resolutions, as multiple devices share the same resolution and scale with different corner radii. Display Zoom messes with this too, and ultimately it just seems like a bad idea to assume anything about the device based on the display resolution. 14 | 15 | ### How to use 16 | 17 | iOS device displays use a continious corner curve, which means the corners are not true circles. In iOS 13+ you can use `CALayer.cornerCurve` to specify a continuous corner curve. You might create a view subclass like this: 18 | 19 | ```swift 20 | class DisplayCornerMatchingView: UIView { 21 | override func layoutSubviews() 22 | super.layoutSubviews() 23 | layer.cornerCurve = .continuous 24 | layer.cornerRadius = window?.screen.displayCornerRadius ?? 0 25 | } 26 | } 27 | ``` 28 | 29 | Or perhaps you want to animate from a different corner radius to the screen one. Either way, be sure to set `layer.cornerCurve = .continuous` on the view. 30 | 31 | ### Values reported 32 | 33 | The following values were reported for various devices with rounded corners: 34 | 35 | | Device | Value (pts) | 36 | |--|--| 37 | | iPhone X, Xs, Xs Max, 11 Pro, 11 Pro Max | 39.0 | 38 | | iPhone Xr, 11 | 41.5 | 39 | | iPhone 12 mini, 13 mini | 44.0 | 40 | | iPhone 12, 12 Pro, 13 Pro, 14, 16e | 47.33 | 41 | | iPhone 12 Pro Max, 13 Pro Max, 14 Plus | 53.33 | 42 | | iPhone 14 Pro, 14 Pro Max, 15, 15 Plus, 15 Pro, 15 Pro Max, 16, 16 Plus | 55.0 | 43 | | iPhone 16 Pro, 16 Pro Max, 17, 17 Pro, 17 Pro Max, Air | 62.0 | 44 | | iPad Air / iPad Pro 11-inch / 12.9-inch | 18.0 | 45 | --------------------------------------------------------------------------------