Last active
July 3, 2023 10:04
-
-
Save tixster/9ebc09aea94a3a3552af058051b55605 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import UIKit | |
| extension CGFloat { | |
| var adaptedFontSize: CGFloat { | |
| adapted(dimensionSize: self, to: dimension) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| enum Dimension { | |
| case width | |
| case height | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import UIKit | |
| extension Int { | |
| var VAdapted: CGFloat { | |
| adapted(dimensionSize: CGFloat(self), to: .height) | |
| } | |
| var HAdapted: CGFloat { | |
| adapted(dimensionSize: CGFloat(self), to: .width) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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