Skip to content

Instantly share code, notes, and snippets.

@tixster
Last active July 3, 2023 10:04
Show Gist options
  • Select an option

  • Save tixster/9ebc09aea94a3a3552af058051b55605 to your computer and use it in GitHub Desktop.

Select an option

Save tixster/9ebc09aea94a3a3552af058051b55605 to your computer and use it in GitHub Desktop.
import UIKit
class AdaptedConstraint: NSLayoutConstraint {
// MARK: - Properties
var initialConstant: CGFloat?
override func awakeFromNib() {
super.awakeFromNib()
saveConstant()
adaptConstant()
}
}
// MARK: - Adapt constant
extension AdaptedConstraint {
func adaptConstant() {
if let dimension = getDimension(from: firstAttribute) {
self.constant = adapted(dimensionSize: self.constant, to: dimension)
}
}
func getDimension(from attribute: NSLayoutConstraint.Attribute) -> Dimension? {
switch attribute {
case .left, .right, .leading, .trailing, .width, .centerX, .leftMargin,
.rightMargin, .leadingMargin, .trailingMargin, .centerXWithinMargins:
return .width
case .top, .bottom, .height, .centerY, .lastBaseline, .firstBaseline,
.topMargin, .bottomMargin, .centerYWithinMargins:
return .height
case .notAnAttribute:
return nil
@unknown default:
return nil
}
}
}
// MARK: - Reset constant
extension AdaptedConstraint {
func saveConstant() {
initialConstant = self.constant
}
func resetConstant() {
if let initialConstant = initialConstant {
self.constant = initialConstant
}
}
}
import UIKit
var dimension: Dimension {
UIDevice.current.orientation.isPortrait ? .width : .height
}
func adapted(dimensionSize: CGFloat, to dimension: Dimension) -> CGFloat {
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
var ratio: CGFloat = 0.0
var resultDimensionSize: CGFloat = 0.0
switch dimension {
case .width:
ratio = dimensionSize / Device.baseScreenSize.rawValue.width
resultDimensionSize = screenWidth * ratio
case .height:
ratio = dimensionSize / Device.baseScreenSize.rawValue.height
resultDimensionSize = screenHeight * ratio
}
return resultDimensionSize
}
func resized(size: CGSize, basedOn dimension: Dimension) -> CGSize {
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
var ratio: CGFloat = 0.0
var width: CGFloat = 0.0
var height: CGFloat = 0.0
switch dimension {
case .width:
ratio = size.height / size.width
width = screenWidth * (size.width / Device.baseScreenSize.rawValue.width)
height = width * ratio
case .height:
ratio = size.width / size.height
height = screenHeight * (size.height / Device.baseScreenSize.rawValue.height)
width = height * ratio
}
return CGSize(width: width, height: height)
}
import UIKit
extension Array where Element == Int {
var VResized: CGSize {
guard self.count == 2 else { fatalError("You have to specify 2 values: [width, height]") }
return resized(size: CGSize(width: self[0], height: self[1]), basedOn: .height)
}
var HResized: CGSize {
guard self.count == 2 else { fatalError("You have to specify 2 values: [width, height]") }
return resized(size: CGSize(width: self[0], height: self[1]), basedOn: .width)
}
}
import UIKit
extension CGFloat {
var adaptedFontSize: CGFloat {
adapted(dimensionSize: self, to: dimension)
}
}
import UIKit
enum Device {
case iPhone5S
case iPhone8
case iPhone8Plus
case iPhone11Pro
case iPhone11ProMax
case iPhone12
case iPhone12ProMax
static let baseScreenSize: Device = .iPhone8
}
extension Device: RawRepresentable {
typealias RawValue = CGSize
init?(rawValue: CGSize) {
switch rawValue {
case CGSize(width: 320, height: 568):
self = .iPhone5S
case CGSize(width: 375, height: 667):
self = .iPhone8
case CGSize(width: 414, height: 736):
self = .iPhone8Plus
case CGSize(width: 375, height: 812):
self = .iPhone11Pro
case CGSize(width: 414, height: 896):
self = .iPhone11ProMax
case CGSize(width: 390, height: 844):
self = .iPhone12
case CGSize(width: 428, height: 926):
self = .iPhone12ProMax
default:
return nil
}
}
var rawValue: CGSize {
switch self {
case .iPhone5S:
return CGSize(width: 320, height: 568)
case .iPhone8:
return CGSize(width: 375, height: 667)
case .iPhone8Plus:
return CGSize(width: 414, height: 736)
case .iPhone11Pro:
return CGSize(width: 375, height: 812)
case .iPhone11ProMax:
return CGSize(width: 414, height: 896)
case .iPhone12:
return CGSize(width: 390, height: 844)
case .iPhone12ProMax:
return CGSize(width: 428, height: 926)
}
}
}
enum Dimension {
case width
case height
}
import UIKit
extension Int {
var VAdapted: CGFloat {
adapted(dimensionSize: CGFloat(self), to: .height)
}
var HAdapted: CGFloat {
adapted(dimensionSize: CGFloat(self), to: .width)
}
}
import UIKit
extension UIView {
func updateAdaptedConstraints() {
let adaptedConstraints = constraints.filter { (constraint) -> Bool in
return constraint is AdaptedConstraint
} as! [AdaptedConstraint]
for constraint in adaptedConstraints {
constraint.resetConstant()
constraint.awakeFromNib()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment