写在前面
最近在学习swift,从 github 上下载很多 demo 进行学习,收获不小,发现了一些不错的写法,记录一下方便以后查询,同时分享给大家,共同成长。
UI 相关的一些常量和辅助方法
以下代码主要定义了一个 swift 工程中的 UI 部分的常量亮和定义,当然,这只是 demo,正式工程可以按照这个思路进行扩展。
一个 XYUI 结构体囊括了 Screen
、Color
、Font
三个子结构体,分别定义了屏幕、颜色、字体相关的常量和方法,结构清晰,方便后续扩展。
struct XYUI {
struct Screen {
static let Width : CGFloat = UIScreen.main.bounds.width
static let Height : CGFloat = UIScreen.main.bounds.size.height
static let NavH : CGFloat = XYUI.Screen.IphoneX == true ? 88 : 64
static let StatusbarH : CGFloat = XYUI.Screen.IphoneX == true ? 44 : 20
static let IphoneX: Bool = Int(XYUI.Screen.Height/XYUI.Screen.Width) == 216 // 判断是否是 iPhoneX 序列
}
// 颜色
struct Color {
/// 主色调
static let primary = UIColor.hexString(color: "#FFCA07")
static let black = UIColor.hexString(color: "#333333")
static let white = UIColor.white
}
struct Font {static func fitFont(size:CGFloat) -> CGFloat {
if UIScreen.main.bounds.size.width == 320 {return size * 0.8}
return size
}
static let f10 = UIFont.systemFont(ofSize: 10)
static let f11 = UIFont.systemFont(ofSize: 11)
static let f12 = UIFont.systemFont(ofSize: 12)
static let f13 = UIFont.systemFont(ofSize: 13)
static let f14 = UIFont.systemFont(ofSize: 14)
static let f15 = UIFont.systemFont(ofSize: 15)
static let f16 = UIFont.systemFont(ofSize: 16)
static let f17 = UIFont.systemFont(ofSize: 17)
static let f18 = UIFont.systemFont(ofSize: 18)
static let f20 = UIFont.systemFont(ofSize: 20)
}
}
关于 cellIdentifier 使用
关于 tableview 和collectionView的 cellIdentifier 定义,在 objective-c 中,我之前是这样定义的:
static const NSString *kXXXIdentifier = @"XXXIdentifier"; //XXX 换成对应 cell 的类名
后来发现了一个更简便的写法, 就是在对应的 cell 中,定义一个 类方法,在类方法中使用反射机制进行类名的获取,从而生成复用标识。代码如下:
+ (NSString *)cellIdentifier{return NSStringFromClass([self class]);
}
这样就不用绞尽脑汁去想复用标识的常量名了,而且更为简洁。
在 swift 中通常的做法和在 objective-c 中一样,定义一个常量,
static let kXXXIdentifier: String = "XXXIdentifier"; //XXX 换成对应 cell 的类名
更为简洁的写法:
public class func identifier() -> String {let name: AnyClass! = object_getClass(self)
return NSStringFromClass(name)
}
从代码上看,不管是 objective- c 还是 swift,使用反射获取的 cellIdentifier 和对应的 cell 绑定在一起,不仅可以直接进行代码的 copy 复用,而且免去了在绞尽脑汁想复用标识常量名的麻烦,何乐为不为呢。
根据对应的屏幕尺寸进行缩放
我们开发中进行 UI 布局的时候,即使采用的是自动布局,一些控件的尺寸、控件间的间距也是应该按照屏幕的大小进行缩放的,这样才能做到标准的 UI 自适应。以下是以 iPhone6、iPhone6s 的屏幕尺寸为基准进行缩放的方法,特别收录一下。
// 宽度比
let kWidthRatio = kScreenW / 375.0 //iPhone6、iPhone6s 的宽度为基准
// 高度比
let kHeightRatio = kScreenH / 667.0 //iPhone6、iPhone6s 的高度为基准
// 按比例自适应
func Adapt(_ value : CGFloat) -> CGFloat {return AdaptW(value)
}
// 自适应宽度
func AdaptW(_ value : CGFloat) -> CGFloat {return ceil(value) * kWidthRatio
}
// 自适应高度
func AdaptH(_ value : CGFloat) -> CGFloat {return ceil(value) * kHeightRatio
}
ceil函数从网上查了一下,意思是向上取整。
关于通知
iOS 开发中,通知 也是我们经常使用的 观察者 模式的一种实现。在 OC 中,我们通常把通知名定义成一个全局的常量,这样方便调用和修改。
在 OC 中,我们之前是这样做定义的:
NotificationGlobalName.h
extern NSString *const buildRouteNotification;
extern NSString *const placeDeletedNotification;
extern NSString *const centerPlaceOnMapNotification;
NotificationGlobalName.m
//`XXX` 替换成工程名
NSString *const buildRouteNotification = @"XXX.buildRouteNotification";
NSString *const placeDeletedNotification = @"XXX.placeDeletedNotification";
NSString *const centerPlaceOnMapNotification = @"XXX.centerPlaceOnMapNotification";
我们可以在内部使用 #pragma mark - 模块名
分模块定义,这样方便后续的更新和查找。
swift 中我们可以这样做:
extension Notification.Name {static let buildRoute = Notification.Name("buildRouteNotification")
static let placeDeleted = Notification.Name("placeDeletedNotification")
static let centerPlaceOnMap = Notification.Name("centerPlaceOnMapNotification")
}
利用扩展把通知名定义成常量,方便后续的调用。