ios - 如何将 iOS 项目和字体大小缩放为屏幕大小
问题描述
我想让项目和字体大小看起来与屏幕大小相同。我曾经使用项目比例来缩放以处理不同的 iOS 屏幕,但是项目的大小出现了问题,这极大地增加了更大的 iOS 屏幕。此外,我创建了 FontHelper,它可以将字体大小调整为屏幕大小。例如,如果我已经定义iPhone SE 中的字体大小为 17,iPhone 8 中的大小为 19,iPhone 8 Plus 中的大小为 21 等。据我所知,如果我将项目大小高度定义为特定数字,它将被调整为设备屏幕。标签的字体大小也是如此,如果我将字体大小定义为特定数字,它将被调整为设备屏幕,因为它是由点定义的,但是我创建了XIB文件并放置了不同高度的视图和不同字体大小的标签检查它们是否会被调整。如您所见,它们看起来完全一样。
他们是调整了还是我完全误解了 iOS 开发中的点?是否有任何建议来处理不同 iOS 设备的大小和字体?
解决方案
如果您想为不同的 iPhone 型号处理不同的字体大小。您必须为此创建自定义类。检查下面的代码:
import Foundation
import UIKit
// for label
class ClassLabelSizeClass: UILabel {
override func awakeFromNib() {
super.awakeFromNib()
switch UIDevice().type {
case .iPhoneSE, .iPhone5, .iPhone5S, .iPhone5C:
self.font = self.font.withSize(?*self.font.pointSize)
case .iPhone6, .iPhone6S, .iPhone7, .iPhone8:
self.font = self.font.withSize(?*self.font.pointSize + 2)
case .iPhone6plus, .iPhone6Splus, .iPhone7plus, .iPhone8plus:
self.font = self.font.withSize(?*self.font.pointSize + 2)
case .iPhoneX, .iPhoneXR, .iPhoneXS, .iPhoneXSMax, .iPhone11, .iPhone11Pro, .iPhone11ProMax:
self.font = self.font.withSize(?*self.font.pointSize + 3)
default:
self.font = self.font.withSize(?*self.font.pointSize + 4)
}
}
}
//for textfield
class ClassTextFieldSizeClass: UITextField {
override func awakeFromNib() {
super.awakeFromNib()
switch UIDevice().type {
case .iPhoneSE, .iPhone5, .iPhone5S, .iPhone5C:
self.font = self.font?.withSize(?*self.font?.pointSize)
case .iPhone6, .iPhone6S, .iPhone7, .iPhone8:
self.font = self.font?.withSize(?*self.font?.pointSize + 2)
case .iPhone6plus, .iPhone6Splus, .iPhone7plus, .iPhone8plus:
self.font = self.font?.withSize(?*self.font?.pointSize + 2)
case .iPhoneX, .iPhoneXR, .iPhoneXS, .iPhoneXSMax, .iPhone11, .iPhone11Pro, .iPhone11ProMax:
self.font = self.font?.withSize(?*self.font?.pointSize + 3)
default:
self.font = self.font?.withSize(?*self.font?.pointSize + 4)
}
}
}
//for button
class ClassButtonSizeClass: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
switch UIDevice().type {
case .iPhoneSE, .iPhone5, .iPhone5S, .iPhone5C:
self.titleLabel?.font = self.titleLabel?.font.withSize(?*self.titleLabel?.font.pointSize)
case .iPhone6, .iPhone6S, .iPhone7, .iPhone8:
self.titleLabel?.font = self.titleLabel?.font.withSize(?*self.titleLabel?.font.pointSize + 2)
case .iPhone6plus, .iPhone6Splus, .iPhone7plus, .iPhone8plus:
self.titleLabel?.font = self.titleLabel?.font.withSize(?*self.titleLabel?.font.pointSize + 2)
case .iPhoneX, .iPhoneXR, .iPhoneXS, .iPhoneXSMax, .iPhone11, .iPhone11Pro, .iPhone11ProMax:
self.titleLabel?.font = self.titleLabel?.font.withSize(?*self.titleLabel?.font.pointSize + 3)
default:
self.titleLabel?.font = self.titleLabel?.font.withSize(?*self.titleLabel?.font.pointSize + 4)
}
}
}
// for textView
class ClassTextViewSizeClass: UITextView {
override func awakeFromNib() {
super.awakeFromNib()
switch UIDevice().type {
case .iPhoneSE, .iPhone5, .iPhone5S, .iPhone5C:
self.font = self.font?.withSize(?*self.font?.pointSize)
case .iPhone6, .iPhone6S, .iPhone7, .iPhone8:
self.font = self.font?.withSize(?*self.font?.pointSize + 2)
case .iPhone6plus, .iPhone6Splus, .iPhone7plus, .iPhone8plus:
self.font = self.font?.withSize(?*self.font?.pointSize + 2)
case .iPhoneX, .iPhoneXR, .iPhoneXS, .iPhoneXSMax, .iPhone11, .iPhone11Pro, .iPhone11ProMax:
self.font = self.font?.withSize(?*self.font?.pointSize + 3)
default:
self.font = self.font?.withSize(?*self.font?.pointSize + 4)
}
}
}
//for custom value returning
class ClassUIDeviceTypeReturn {
static let shared = ClassUIDeviceTypeReturn()
func returnFloatValue(iPhone5: CGFloat, iPhone6: CGFloat, iPhone6Plus: CGFloat, iPhoneX: CGFloat, iPadDefault: CGFloat) -> CGFloat {
switch UIDevice().type {
case .iPhoneSE, .iPhone5, .iPhone5S, .iPhone5C:
return iPhone5
case .iPhone6, .iPhone6S, .iPhone7, .iPhone8:
return iPhone6
case .iPhone6plus, .iPhone6Splus, .iPhone7plus, .iPhone8plus:
return iPhone6Plus
case .iPhoneX, .iPhoneXR, .iPhoneXS, .iPhoneXSMax, .iPhone11, .iPhone11Pro, .iPhone11ProMax:
return iPhoneX
default:
return iPadDefault
}
}
}
public enum EnumModel: String {
case simulator = "simulator/sandbox",
//iPod
iPod1 = "iPod 1",
iPod2 = "iPod 2",
iPod3 = "iPod 3",
iPod4 = "iPod 4",
iPod5 = "iPod 5",
//iPad
iPad2 = "iPad 2",
iPad3 = "iPad 3",
iPad4 = "iPad 4",
iPadAir = "iPad Air ",
iPadAir2 = "iPad Air 2",
iPad5 = "iPad 5", //aka iPad 2017
iPad6 = "iPad 6", //aka iPad 2018
//iPad mini
iPadMini = "iPad Mini",
iPadMini2 = "iPad Mini 2",
iPadMini3 = "iPad Mini 3",
iPadMini4 = "iPad Mini 4",
//iPad pro
iPadPro9_7 = "iPad Pro 9.7\"",
iPadPro10_5 = "iPad Pro 10.5\"",
iPadPro12_9 = "iPad Pro 12.9\"",
iPadPro2_12_9 = "iPad Pro 2 12.9\"",
//iPhone
iPhone4 = "iPhone 4",
iPhone4S = "iPhone 4S",
iPhone5 = "iPhone 5",
iPhone5S = "iPhone 5S",
iPhone5C = "iPhone 5C",
iPhone6 = "iPhone 6",
iPhone6plus = "iPhone 6 Plus",
iPhone6S = "iPhone 6S",
iPhone6Splus = "iPhone 6S Plus",
iPhoneSE = "iPhone SE",
iPhone7 = "iPhone 7",
iPhone7plus = "iPhone 7 Plus",
iPhone8 = "iPhone 8",
iPhone8plus = "iPhone 8 Plus",
iPhoneX = "iPhone X",
iPhoneXS = "iPhone XS",
iPhoneXSMax = "iPhone XS Max",
iPhoneXR = "iPhone XR",
iPhone11 = "iPhone 11",
iPhone11Pro = "iPhone 11 Pro",
iPhone11ProMax = "iPhone 11 Pro Max",
//Apple TV
AppleTV = "Apple TV",
AppleTV_4K = "Apple TV 4K",
unrecognized = "?unrecognized?"
}
// #-#-#-#-#-#-#-#-#-#-#-#-#-#-#
// MARK: UIDevice extensions
// #-#-#-#-#-#-#-#-#-#-#-#-#-#-#
public extension UIDevice {
public var type: EnumModel {
var systemInfo = utsname()
uname(&systemInfo)
let modelCode = withUnsafePointer(to: &systemInfo.machine) {
$0.withMemoryRebound(to: CChar.self, capacity: 1) {
ptr in String.init(validatingUTF8: ptr)
}
}
var modelMap : [ String: EnumModel ] = [
"i386": .simulator,
"x86_64": .simulator,
//iPod
"iPod1,1": .iPod1,
"iPod2,1": .iPod2,
"iPod3,1": .iPod3,
"iPod4,1": .iPod4,
"iPod5,1": .iPod5,
//iPad
"iPad2,1": .iPad2,
"iPad2,2": .iPad2,
"iPad2,3": .iPad2,
"iPad2,4": .iPad2,
"iPad3,1": .iPad3,
"iPad3,2": .iPad3,
"iPad3,3": .iPad3,
"iPad3,4": .iPad4,
"iPad3,5": .iPad4,
"iPad3,6": .iPad4,
"iPad4,1": .iPadAir,
"iPad4,2": .iPadAir,
"iPad4,3": .iPadAir,
"iPad5,3": .iPadAir2,
"iPad5,4": .iPadAir2,
"iPad6,11": .iPad5, //aka iPad 2017
"iPad6,12": .iPad5,
"iPad7,5": .iPad6, //aka iPad 2018
"iPad7,6": .iPad6,
//iPad mini
"iPad2,5": .iPadMini,
"iPad2,6": .iPadMini,
"iPad2,7": .iPadMini,
"iPad4,4": .iPadMini2,
"iPad4,5": .iPadMini2,
"iPad4,6": .iPadMini2,
"iPad4,7": .iPadMini3,
"iPad4,8": .iPadMini3,
"iPad4,9": .iPadMini3,
"iPad5,1": .iPadMini4,
"iPad5,2": .iPadMini4,
//iPad pro
"iPad6,3": .iPadPro9_7,
"iPad6,4": .iPadPro9_7,
"iPad7,3": .iPadPro10_5,
"iPad7,4": .iPadPro10_5,
"iPad6,7": .iPadPro12_9,
"iPad6,8": .iPadPro12_9,
"iPad7,1": .iPadPro2_12_9,
"iPad7,2": .iPadPro2_12_9,
//iPhone
"iPhone3,1": .iPhone4,
"iPhone3,2": .iPhone4,
"iPhone3,3": .iPhone4,
"iPhone4,1": .iPhone4S,
"iPhone5,1": .iPhone5,
"iPhone5,2": .iPhone5,
"iPhone5,3": .iPhone5C,
"iPhone5,4": .iPhone5C,
"iPhone6,1": .iPhone5S,
"iPhone6,2": .iPhone5S,
"iPhone7,1": .iPhone6plus,
"iPhone7,2": .iPhone6,
"iPhone8,1": .iPhone6S,
"iPhone8,2": .iPhone6Splus,
"iPhone8,4": .iPhoneSE,
"iPhone9,1": .iPhone7,
"iPhone9,3": .iPhone7,
"iPhone9,2": .iPhone7plus,
"iPhone9,4": .iPhone7plus,
"iPhone10,1": .iPhone8,
"iPhone10,4": .iPhone8,
"iPhone10,2": .iPhone8plus,
"iPhone10,5": .iPhone8plus,
"iPhone10,3": .iPhoneX,
"iPhone10,6": .iPhoneX,
"iPhone11,2": .iPhoneXS,
"iPhone11,4": .iPhoneXSMax,
"iPhone11,6": .iPhoneXSMax,
"iPhone11,8": .iPhoneXR,
"iPhone12,1": .iPhone11,
"iPhone12,3": .iPhone11Pro,
"iPhone12,5": .iPhone11ProMax,
//AppleTV
"AppleTV5,3": .AppleTV,
"AppleTV6,2": .AppleTV_4K
]
if let model = modelMap[String.init(validatingUTF8: modelCode!)!] {
if model == .simulator {
if let simModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
if let simModel = modelMap[String.init(validatingUTF8: simModelCode)!] {
return simModel
}
}
}
return model
}
return EnumModel.unrecognized
}
}
不要忘记为故事板中的标签、文本字段、按钮、文本视图提供自定义类。
希望能帮助到你 :)
推荐阅读
- r - 如何根据 IF AND 在其他两列中创建具有设定值的新列
- c - 使用 libECC 执行 ECDH
- php - Laravel 迁移在 Plesk 服务器上无法正常工作
- json - 添加从与主报表相同的数据源获取数据的子报表
- c# - 如何在 C# switch 表达式的左侧使用 >=?
- r - 在 R 中格式化日期以仅显示年份
- java - App Engine 和 Firestore 的内存问题
- reactjs - 更改 AsyncStorage 项 REACT NATIVE 的数据
- react-native - 无法在 android 模拟器上运行 react native expo 项目
- javascript - 在 npm build 之后,使用 rewire 禁用块仍然会创建块