通常的,一个正常的流程包括:git
通常的若是新建了一个Objective-C
工程,默认先调用main
函数,main
函数内部会调用UIApplicationMain
函数。github
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
复制代码
但在Swift
项目中,并无main.m
文件也没有main
函数。Swift
工程是在AppDelegate
中用一个@UIApplicationMain
标签。那么UIApplicationMain
作了哪些操做呢:windows
UIApplication
单例对象UIApplication
的委托对象,即AppDelegate
AppDelegate
UIWindows
对象,Info.plist
中设置的默认启动storyboard
文件名称is Initial View Controller
storyboard文件,同时建立对应的View Controller
对象View Controller
为UIWindows
的根视图rootViewController
Windows
上的试图运行工程能够看到以下图: 最底层是一个UIWindwos后端
通常的一个工程,默认从main.storyboard
中的设置的Initial view controller
启动的,那么咱们该如何设置本身的初始启动View Controller
呢?bash
在前面咱们工程的结构:RPChat_iOS是UI的显示以及交互相关的代码,因此在RPChat_iOS
新建文件夹SignIn
app
新建登录界面Controller
命名为SignInViewController
ide
在AppDelegatedidFinishLaunchingWithOptions launchOptions
回调方法中添加代码,设置SignInViewController
为默认启动控制器:函数
if #available(iOS 13, *) {
} else {
window = UIWindow.init()
window?.frame = UIScreen.main.bounds
window?.makeKeyAndVisible()
let signInVC = SignInViewController()
window?.rootViewController = signInVC
}
复制代码
在SceneDelegateoptions connectionOptions
方法中添加代码:单元测试
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window?.windowScene = windowScene
window?.backgroundColor = .white
let tabBar = SignInViewController()
window?.rootViewController = tabBar
window?.makeKeyAndVisible()
复制代码
先看一下这是最终效果图:测试
Auto Layout
至于UI,考虑到版本兼容和后期维护我采用了系统NSLayoutAnchor
适配,
NSLayoutAnchor
经常使用属性
关于Auto Layout
其余更多使用细节请参考官方文档:
Apple Develope NSLayoutConstraint
WWDC 2018 What's New in Cocoa Touch
新建一个View
命名SignInRootView
做为登陆界面的主View
,采用懒加载的方式初始化视图
最顶部的Logo
图片实现代码:
lazy var logoImg: UIImageView = {
self.addSubview($0)
$0.translatesAutoresizingMaskIntoConstraints = false
let top = $0.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor, constant: 44)
let centerX = $0.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: 0)
let width = $0.widthAnchor.constraint(equalToConstant: 120)
let height = $0.heightAnchor.constraint(equalToConstant: 120)
NSLayoutConstraint.activate([top, centerX, width, height])
return $0
}(UIImageView())
复制代码
用户名输入框实现代码:
lazy var accountNumberView: UIView = {
self.addSubview($0)
$0.translatesAutoresizingMaskIntoConstraints = false
let top = $0.topAnchor.constraint(equalTo: logoImg.bottomAnchor, constant: 20)
let left = $0.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 40)
let right = $0.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -40)
let height = $0.heightAnchor.constraint(equalToConstant: 50)
NSLayoutConstraint.activate([top, left, right, height])
$0.layer.cornerRadius = 25
return $0
}(UIView())
lazy var accountNumberLab: UITextField = {
accountNumberView.addSubview($0)
$0.translatesAutoresizingMaskIntoConstraints = false
$0.topAnchor.constraint(equalTo: accountNumberView.topAnchor, constant: 0).isActive = true
$0.leftAnchor.constraint(equalTo: accountNumberView.leftAnchor, constant: 16).isActive = true
$0.rightAnchor.constraint(equalTo: accountNumberView.rightAnchor, constant: -16).isActive = true
$0.bottomAnchor.constraint(equalTo: accountNumberView.bottomAnchor, constant: 0).isActive = true
$0.font = UIFont.init(name: "PingFangTC-Semibold", size: 19)
return $0
}(UITextField())
复制代码
密码输入框实现代码:
lazy var inputPasswordView: UIView = {
self.addSubview($0)
$0.translatesAutoresizingMaskIntoConstraints = false
let top = $0.topAnchor.constraint(equalTo: accountNumberView.bottomAnchor, constant: 20)
let left = $0.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 40)
let right = $0.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -40)
let height = $0.heightAnchor.constraint(equalToConstant: 50)
NSLayoutConstraint.activate([top, left, right, height])
$0.layer.cornerRadius = 25
return $0
}(UIView())
lazy var inputPasswordTxt: UITextField = {
inputPasswordView.addSubview($0)
$0.translatesAutoresizingMaskIntoConstraints = false
$0.topAnchor.constraint(equalTo: inputPasswordView.topAnchor, constant: 0).isActive = true
$0.leftAnchor.constraint(equalTo: inputPasswordView.leftAnchor, constant: 16).isActive = true
$0.rightAnchor.constraint(equalTo: inputPasswordView.rightAnchor, constant: -16).isActive = true
$0.bottomAnchor.constraint(equalTo: inputPasswordView.bottomAnchor, constant: 0).isActive = true
$0.font = UIFont.init(name: "PingFangTC-Semibold", size: 19)
return $0
}(UITextField())
复制代码
登陆按钮实现代码:
lazy var signInBtn: UIButton = {
self.addSubview($0)
$0.translatesAutoresizingMaskIntoConstraints = false
let top = $0.topAnchor.constraint(equalTo: inputPasswordView.bottomAnchor, constant: 20)
let left = $0.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 40)
let right = $0.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -40)
let height = $0.heightAnchor.constraint(equalToConstant: 50)
NSLayoutConstraint.activate([top, left, right, height])
$0.layer.cornerRadius = 25
$0.titleLabel?.font = UIFont.init(name: "PingFangTC-Semibold", size: 20)
$0.setTitle(NSLocalizedString("Sign In", comment: ""), for: .normal)
return $0
}(UIButton())
复制代码
此处代码较多,具体实现请看代码: gitub RPChat
因为设计师给出的颜色通常为16进制,此处须要作一个转码处理:
open class func hexStringToColor(hexadecimal: String) -> UIColor {
var cstr = hexadecimal.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased() as NSString;
if(cstr.length < 6){
return UIColor.clear;
}
if(cstr.hasPrefix("0X")){
cstr = cstr.substring(from: 2) as NSString
}
if(cstr.hasPrefix("#")){
cstr = cstr.substring(from: 1) as NSString
}
if(cstr.length != 6){
return UIColor.clear;
}
var range = NSRange.init()
range.location = 0
range.length = 2
let rStr = cstr.substring(with: range);
range.location = 2;
let gStr = cstr.substring(with: range)
range.location = 4;
let bStr = cstr.substring(with: range)
var r :UInt32 = 0x0;
var g :UInt32 = 0x0;
var b :UInt32 = 0x0;
Scanner.init(string: rStr).scanHexInt32(&r);
Scanner.init(string: gStr).scanHexInt32(&g);
Scanner.init(string: bStr).scanHexInt32(&b);
return UIColor.init(red: CGFloat(r)/255.0, green: CGFloat(g)/255.0, blue: CGFloat(b)/255.0, alpha: 1)
}
复制代码
而后就能够用设计师给的16进制设置背景颜色:
signInBtn.backgroundColor = UIColor.hexStringToColor(hexadecimal: "0xF5BE62")
复制代码
因为iOS 13
以后苹果处理Drak Mode
,做为开发者也应该作相应的兼容处理。如今我在代码中并无此时调整模拟器为暗模式,运行工程能够看到在暗模式下,用户名和密码输入框背景色不见了。此时就应该作暗模式的兼容处理。
此处个人作法也很简单,对UIColor
作extension
处理,而后再扩展方法中分别对Drak Mode
和Light Mode
两种模式作对应的处理,代码以下:
open class func configDarkModeViewColor() -> UIColor {
let retColor: UIColor!
if #available(iOS 13.0, *) {
retColor = UIColor { (collection) -> UIColor in
if (collection.userInterfaceStyle == .dark) {
return UIColor.init(red: 100/255, green: 100/255, blue: 100/255, alpha: 1)
}
return UIColor.white
}
} else {
return UIColor.white
}
return retColor
}
open class func configDarkModeViewColorWithdDfaultColor(dfaultColor: UIColor) -> UIColor {
let retColor: UIColor!
if #available(iOS 13.0, *) {
retColor = UIColor { (collection) -> UIColor in
if (collection.userInterfaceStyle == .dark) {
return UIColor.init(red: 100/255, green: 100/255, blue: 100/255, alpha: 1)
}
return dfaultColor
}
} else {
return dfaultColor
}
return retColor
}
复制代码
只须要在设置颜色时调用便可:
view.backgroundColor = UIColor.configDarkModeViewColorWithdDfaultColor(dfaultColor: UIColor.groupTableViewBackground)
复制代码
再次运行项目,能够看到界面已经兼容了暗模式:
本文主要写了: