如有错误,请指正!谢谢!
侵权删!(部分转载)
1.PHAsset获取本地视频的url
PHCachingImageManager().requestAVAsset(forVideo: asset, options:nil, resultHandler: { (asset, audioMix, info)in
let avAsset = asset as? AVURLAsset
print(asset?.url)
})
2.手势冲突
moreTap.require(toFail: singleTap)
//优先检测singleTap,若singleTap检测不到,或检测失败,则检测moreTap,检测成功后,触发方法
singleTap.require(toFail: moreTap)
//优先检测moreTap,若moreTap检测不到,或检测失败,则检测singleTap,检测成功后,触发方法
原文链接:https://blog.csdn.net/a645258072/article/details/72896196
3.UITableViewCell UIButton不响应点击事件
cell.contentView.addSubview:(button)
4.ableViewCell取消点击方法与取消点击高亮状态
//取消触发点击方法
self.tableView.allowsSelection = false
//取消点击高亮
cell.selectionStyle = .none
5.UITableView 禁止滑动
tableView.isScrollEnabled = false
6.根据cell里的子控件来获取cell,以UIbutton为例
func superUITableViewCell(of : UIButton) -> TableViewCell?{
for view in sequence(first: of.superview, next: { $0?.superview }) {
if let cell = view as? TableViewCell {
return cell
}
}
return nil
}
7.收起/聚焦键盘
//收起键盘
//方法1
textField.resignFirstResponder()
//方法2
UIApplication.shared.keyWindow?.endEditing(true)
ios13弃用keyWindow,可以用
self.view.endEditing(true)
//聚焦输入框
textField.becomeFirstResponder()
8.管理Placeholder的文本属性(包括字体、颜色、大小)
textField.attributedPlaceholder = NSAttributedString(string: __("文本内容"),
attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 15),
NSAttributedString.Key.foregroundColor: UIColor.init(hex: 0x000000,alpha: 0.5)])
9.textfield文本距离边框的距离设置
let leftView = UIView.init(frame:CGRect.init(x:0, y: 0, width:12, height: 20))
leftView.backgroundColor = .clear
let textField = UITextField()
textField.leftViewMode = .always //此句代码较容易忽略
textField.leftView = leftView
//清空按钮的设置
textField.clearButtonMode = .whileEditing
10.sqlite更新blob类型数据
let sql = "update \(name) set coverPhoto=cast((?) as blob) where id=\(id)"
let db = SQLiteManager.shareManger().db
db.executeUpdate(sql, withArgumentsIn: [coverPhoto as Data])
//主要是
cast((?) as blob) 与 [coverPhoto as Data] 表明存入数据类型和发过来的数据类型
//cast(xxx as 类型). convert(xxx,类型)
11.获取字典的key或者value
Array(listArray[num].keys)[0]
Array(listArray[num].values)[0]
12.相册图片资源获取
//申请权限
PHPhotoLibrary.requestAuthorization({ (status) in
if status != .authorized {
DispatchQueue.main.async {
// self.navigationController?.popViewController(animated: true)
}
}else{
// 列出所有系统的智能相册
let smartOptions = PHFetchOptions()
let smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum,
subtype: .albumRegular,
options: smartOptions)
self.convertCollection(collection: smartAlbums)
//列出所有用户创建的相册
let userCollections = PHCollectionList.fetchTopLevelUserCollections(with: nil)
self.convertCollection(collection: userCollections
as! PHFetchResult<PHAssetCollection>)
//相册按包含的照片数量排序(降序)
self.items.sort { (item1, item2) -> Bool in
return item1.fetchResult.count > item2.fetchResult.count
}
//异步加载表格数据,需要在主线程中调用reloadData() 方法
DispatchQueue.main.async{
if self.items.count == 0{
}else{
}
}
}
})
//转化处理获取到的相簿
private func convertCollection(collection:PHFetchResult<PHAssetCollection>){
for i in 0..<collection.count{
//获取出但前相簿内的图片
let resultsOptions = PHFetchOptions()
resultsOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate",
ascending: false)]
let c = collection[i]
let assetsFetchResult = PHAsset.fetchAssets(in: c , options: resultsOptions)
//没有图片的空相簿不显示
if assetsFetchResult.count > 0{
let title = titleOfAlbumForChinse(title: c.localizedTitle)
items.append(AlbumItem(title: title,
fetchResult: assetsFetchResult))
}
}
}
//相册名转化
private func titleOfAlbumForChinse(title:String?) -> String? {
if title == "Slo-mo" {
return __("慢动作")
} else if title == "Recently Added" {
return __("最近添加")
} else if title == "Favorites" {
return __("个人收藏")
} else if title == "Recently Deleted" {
return __("最近删除")
} else if title == "Videos" {
return __("视频")
} else if title == "All Photos" {
return __("所有照片")
} else if title == "Selfies" {
return __("自拍")
} else if title == "Screenshots" {
return __("屏幕快照")
} else if title == "Camera Roll" {
return __("相机胶卷")
}
return title
}
13.相册资源缩略图获取
self.imageManager.requestImage(for: assetObject, targetSize: assetGridThumbnailSize,
contentMode: PHImageContentMode.aspectFit,
options: nil) { (image, nfo) in
(photoThumbnail = image?.pngData())
}
详细链接:Swift - 使用PhotoKit获取照片1(获取所有照片缩略图、原图及其信息)
14.相册视频移出
let option = PHVideoRequestOptions()
option.version = PHVideoRequestOptionsVersion.current
option.deliveryMode = PHVideoRequestOptionsDeliveryMode.automatic
let manager = PHImageManager.default()
manager.requestExportSession(forVideo: assetObject, options: option, exportPreset: AVAssetExportPresetPassthrough) {exportSession, info in
let videoPath = URL(fileURLWithPath: toURLPath)
if let session = exportSession{
session.outputURL = videoPath
session.outputFileType = session.supportedFileTypes.first
session.exportAsynchronously(completionHandler: {
switch session.status {
case .failed:
print("移出失败")
break
case .completed:
print("移出成功")
break
default:
break
}
}
15.加入缓存
lazy var imageCache:SDImageCache = {
let cache = SDImageCache()
return cache
}()
let imageId = String(indexPath.row)
if let cacheImage = imageCache.imageFromMemoryCache(forKey: imageId){
cell.photoImageView.image = cacheImage
}else{
DispatchQueue.main.async { [self] in
let url = photoUrl
print(url)
cell.photoImageView.sd_setImage(with: url.toURL(), completed: nil)
self.imageCache.storeImage(toMemory: cell.photoImageView.image, forKey: imageId)
}
LLog("无缓存", imageId)
}
16.关于HEIC/HEIF图片检测与转化为JPG图片
import Photos
var isHEIC = false
let resources = PHAssetResource.assetResources(for: asset)
for resource in resources {
let uti = resource.uniformTypeIdentifier
if uti == "public.heic" || uti == "public.heif" {
isHEIC = true
break
}
}
PHImageManager.default().requestImageData(for: asset, options: nil) { (imageData, dataUTI, orientation, info) in
if isHEIC { // 如果是 HEIC 图片
guard let imageData = imageData,
let ciImage = CIImage(data: imageData),
let colorSpace = ciImage.colorSpace else { return }
let context = CIContext()
guard let jpgData = context.jpegRepresentation(of: ciImage, colorSpace: colorSpace, options: [:]),
let jpgImage = UIImage(data: jpgData) else { return }
// 将原图片替换为 jpgImage
} else { // 如果不是 HEIC 图片
// 继续使用原图片
}
}
详细链接:掘金
17.检测图片是否属于iCloud,并弹窗提示
let selectedAsset = assets[indexPath.item]
let resourceArray = PHAssetResource.assetResources(for: selectedAsset)
let value = resourceArray.last?.value(forKey: "locallyAvailable")
var isLocal: Bool = false
if value is NSNumber {
let number: NSNumber = value as! NSNumber
isLocal = number.boolValue
}
if !isLocal {
let alert = UIAlertController(title: nil, message: __("该照片储存在iCloud中,请下载到系统相册"), preferredStyle: .alert)
let cancelAction = UIAlertAction(title: __("取消"), style: .default, handler: nil)
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil)
return
}
18.ipad多任务方向支持被拒
将UIRequiresFullScreen
键添加到 Xcode 项目Info.plist
文件并应用布尔值YES
https://stackoverflow.com/questions/32559724/ipad-multitasking-support-requires-these-orientations
19.进入页面自动聚焦输入栏
view.textfield.becomeFirstResponder()
20.实况图片的本地存储与读取
//存入文件夹
var isHEIC = false
let resources = PHAssetResource.assetResources(for: assetObject)
for resource in resources {
let uti = resource.uniformTypeIdentifier
if uti == "public.heic" || uti == "public.heif" {
isHEIC = true
break
}
}
PHImageManager.default().requestImageData(for: assetObject, options: nil) { (imageData, dataUTI, orientation, info) in
if isHEIC {
try! imageData!.write(to: URL(fileURLWithPath:documentPath+"/"+fileUrl+filename))
}else{
}
}
//读取
let suffix = photoDatas[firstNum].photoUrl.extension
//extension 是获取后缀名的扩展
if suffix == ".HEIC" || suffix == ".HEIF"{
do{
let data = try Data(contentsOf: URL(fileURLWithPath: photoUrl))
let image = UIImage(data: data)
previewImageView.image = image
} catch{
print("ERROR")
}
}else{
}
21.慢动作视频的后缀名获取失败
let fileName = avAsset?.url.lastPathComponent ?? "MP4"//一定要给好备选项,不要强解析
22.让某view一直在最上面显示
view.layer.zPosition = .greatestFiniteMagnitude
(父)self.view.bringSubviewToFront(view)(子)
23.从后台切换到前台,或者锁屏后开启唤醒
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self,selector:
#selector(applicationDidBecomeActive),name:
UIApplication.didBecomeActiveNotification, object: nil)
}
@objc func applicationDidBecomeActive(notification: NSNotification) {
// Application is back in the foreground
print("applicationDidBecomeActive")
}
}
链接:https://blog.csdn.net/zgpeace/article/details/107833217
24.获取鼠标点击处位置
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//获取点击的坐标位置
for touch:AnyObject in touches {
let t:UITouch = touch as! UITouch
print(t.location(in: self))
}
}
链接:macos - 在Swift中获取鼠标坐标 - IT工具网
25.获取视图在父元素里的位置
//获取self.cView在self.sView的坐标,size是self.CView;
let crect2 = self.sView?.convert((self.cView?.frame)!, from: self.cView);
//获取self.cView在self.sView的坐标,size是self.CView;
let crect = self.cView?.convert((self.cView?.frame)!, to: self.sView);
26.获取当前视图的父视图或父控制器
//获取当前视图所在导航控制器
func currentNavViewController() -> UINavigationController? {
var n = next
while n != nil {
if n is UINavigationController {
return n as? UINavigationController
}
n = n?.next
}
return nil
}
链接:swift 、OC 获取Controller或者View的方法 总结 - 代码先锋网
27.根据关键字过滤数组
//开头关键字
let array = ["asd","fff","aaa","sad"]
let filteredArray = array.filter(){
return $0.hasPrefix("a")
}
//包含关键字
let array = ["aaa","asd","dd"]
let filteredArray = array.filter(){
return $0.rangeOfString("a") != nil
}
28.NotificationCente,通知的发送与监听
//设定通知并发送
let notificationName = Notification.Name("sublineNotifiction")
NotificationCenter.default.post(name: notificationName, object: self, userInfo: ["direction":content])
//通知接受并处理
let notificationName = Notification.Name("sublineNotifiction")
NotificationCenter.default.addObserver(self, selector: #selector(setsubline(notification: )), name: notificationName, object: nil)
@objc func setsubline(notification:Notification){
let userInfo = notification.userInfo as! [String: AnyObject]
let direct = userInfo["direction"]!
}
//如果不需要的话,记得把相应的通知注册给取消,避免内存浪费或崩溃
deinit {
NotificationCenter.default.removeObserver(self)
}
链接:Swift - 使用NotificationCenter发送通知,接收通知
29.UserDefaults的使用(不是ground)
//Setting.swift
struct ProjectKeys{
static let quickSaveTime = "quickSaveTime"
}
let defaults = UserDefaults.standard
struct Setting{
static var quickSaveTime:Int{
set{
defaults.set(newValue,forKey: ProjectKeys.quickSaveTime)
}
get {
return defaults.integer(forKey: ProjectKeys.quickSaveTime)
}
}
}
//初始化
UserDefaults.standard.register(defaults: ["quickSaveTime":1])
//使用
Setting.quickSaveTime = 0
30.tableView section header 的样式设置
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
guard let header = view as? UITableViewHeaderFooterView else { return }
header.textLabel?.textColor = UIColor.black
header.textLabel?.font = UIFont.systemFont(ofSize:16 ,weight:.black)
header.textLabel?.frame = header.frame
header.textLabel?.textAlignment = .center
}
链接:如何更改UITableView Section Header的字体大小? - 问答 - 云+社区 - 腾讯云
31.view的部分圆角设置
lazy var backView: UIView = {
let view = UIView()
view.layer.maskedCorners = CACornerMask(rawValue: CACornerMask.layerMinXMinYCorner.rawValue | CACornerMask.layerMaxXMinYCorner.rawValue)
view.layer.cornerRadius = 15
view.clipsToBounds = true
view.backgroundColor = .white
return view
}()
32.coredata的封装使用
class Message{
var id:Int32?
var message:String?
init(id:Int32?,message:String){
self.id = id
self.message = message
}
}
///添加数据
public func addData(id:Int32,message:String)
{
// 用來操作 Core Data 的常數
let moc = (UIApplication.shared.delegate
as! AppDelegate).persistentContainer.viewContext
let myEntityName = "MessageData"
// insert
let student =
NSEntityDescription.insertNewObject(
forEntityName: myEntityName, into: moc)
as! MessageData
student.id = id
student.message = message
do {
try moc.save()
print("success")
} catch {
fatalError("\(error)")
}
}
/// 查询数据
func queryData() -> [Message]
{
//获取管理的数据上下文 对象
var dataArr:[Message] = []
let app = UIApplication.shared.delegate as! AppDelegate
let fetchRequest = NSFetchRequest<MessageData>(entityName:"MessageData")
let context = app.persistentContainer.viewContext
//设置查询条件
// let predicate = NSPredicate(format: "")
// fetchRequest.predicate = predicate
//查询操作
do {
let fetchedObjects = try context.fetch(fetchRequest)
//遍历查询的结果
for info in fetchedObjects{
// print("id=\(info.id)")
// print("username=\(info.message ?? "")")
dataArr.append(Message(id: info.id, message: info.message!))
}
}
catch {
fatalError("不能保存:\(error)")
}
return dataArr
}
/// 修改数据操作
func modifyData(id:Int32, message:String)
{
//获取管理的数据上下文 对象
let app = UIApplication.shared.delegate as! AppDelegate
let fetchRequest = NSFetchRequest<MessageData>(entityName:"MessageData")
let context = app.persistentContainer.viewContext
//设置查询条件
let predicate = NSPredicate(format: "id= '\(id)' ", "")
fetchRequest.predicate = predicate
//查询操作
do {
let fetchedObjects = try context.fetch(fetchRequest)
//遍历查询的结果
for info in fetchedObjects{
//修改密码
info.message = message
//重新保存
try context.save()
}
}
catch {
fatalError("不能保存:\(error)")
}
}
/// 删除数据操作
func deleteData(id:Int32)
{
let app = UIApplication.shared.delegate as! AppDelegate
let fetchRequest = NSFetchRequest<MessageData>(entityName:"MessageData")
let context = app.persistentContainer.viewContext
//设置查询条件
let predicate = NSPredicate(format: "id= '\(id)' ", "")
fetchRequest.predicate = predicate
//查询操作
do {
let fetchedObjects = try context.fetch(fetchRequest)
//遍历查询的结果
for info in fetchedObjects{
//删除对象
context.delete(info)
}
//重新保存-更新到数据库
try! context.save()
}
catch {
fatalError("不能保存:\(error)")
}
}
链接:Swift - 使用Core Data进行数据持久化存储 swift3.0:CoreData的使用 - 尚码园
Core Data · Swift 起步走。 Swift CoreData的使用 - 简书 [IOS开发]CoreData条件查询之NSPredicate应用 - 简书
33. UITextView 的 Placeholder 扩展
import Foundation
import UIKit
fileprivate var kTextViewPlaceholderLabel : Int = 0x2019_00
fileprivate var kTextViewPlaceholder : Int = 0x2019_01
fileprivate var kTextViewPlaceholderColor : Int = 0x2019_02
fileprivate var kTextViewPlaceholderFont : Int = 0x2019_03
fileprivate var kTextViewPlaceholderKeys : Int = 0x2019_04
extension UITextView {
/// 占位符
var x_placeholder: String {
get {
if let placeholder = objc_getAssociatedObject(self, &kTextViewPlaceholder) as? String {
return placeholder
} else {
return ""
}
}
set {
objc_setAssociatedObject(self, &kTextViewPlaceholder, newValue, .OBJC_ASSOCIATION_RETAIN)
x_placeholderLabel.text = newValue
}
}
/// 占位符颜色
var x_placeholderColor: UIColor {
get {
if let placeholderColor = objc_getAssociatedObject(self, &kTextViewPlaceholderColor) as? UIColor {
return placeholderColor
} else {
return UIColor(hex: 0xC4C4C4)
}
}
set {
objc_setAssociatedObject(self, &kTextViewPlaceholderColor, newValue, .OBJC_ASSOCIATION_RETAIN)
x_placeholderLabel.textColor = newValue
}
}
/// 占位符字体
var x_placeholderFont: UIFont {
get {
if let placeholderFont = objc_getAssociatedObject(self, &kTextViewPlaceholderColor) as? UIFont {
return placeholderFont
} else {
return UIFont.systemFont(ofSize: 14)
}
}
set {
objc_setAssociatedObject(self, &kTextViewPlaceholderColor, newValue, .OBJC_ASSOCIATION_RETAIN)
x_placeholderLabel.font = newValue
}
}
/// 占位符 标签
@IBInspectable var x_placeholderLabel: UILabel {
get {
var _placeholderLabel = UILabel()
if let label = objc_getAssociatedObject(self, &kTextViewPlaceholderLabel) as? UILabel {
_placeholderLabel = label
} else {
objc_setAssociatedObject(self, &kTextViewPlaceholderLabel, _placeholderLabel, .OBJC_ASSOCIATION_RETAIN)
}
addPlaceholderLabelToSuperView(label: _placeholderLabel)
return _placeholderLabel
}
set {
objc_setAssociatedObject(self, &kTextViewPlaceholderLabel, newValue, .OBJC_ASSOCIATION_RETAIN)
addPlaceholderLabelToSuperView(label: newValue)
}
}
/// 是否需要添加占位符到父视图
fileprivate var x_placeHolderNeedAddToSuperView: Bool {
get {
if let isAdded = objc_getAssociatedObject(self, &kTextViewPlaceholderKeys) as? Bool {
return isAdded
}
return true
}
set {
objc_setAssociatedObject(self, &kTextViewPlaceholderKeys, newValue, .OBJC_ASSOCIATION_RETAIN)
}
}
/// 添加占位符到父视图
///
/// - Parameter label: 占位符 标签
fileprivate func addPlaceholderLabelToSuperView(label: UILabel) {
guard x_placeHolderNeedAddToSuperView else { return }
x_placeHolderNeedAddToSuperView = false
NotificationCenter.default.addObserver(self, selector: #selector(x_textChange(noti:)), name: UITextView.textDidChangeNotification, object: nil)
addSubview(label)
label.snp.makeConstraints { (make) in
make.edges.equalToSuperview().inset(UIEdgeInsets(top: 8, left: 6, bottom: 0, right: 0))
}
}
/// 编辑事件
@objc fileprivate func x_textChange(noti: NSNotification) {
let isEmpty = text.isEmpty
print("text:\(String(describing: text))\nisEmpty:\(isEmpty)")
x_placeholderLabel.text = isEmpty ? x_placeholder : ""
x_placeholderLabel.isHidden = !isEmpty
}
}
链接:Swift UITextView Placeholder Extension - 掘金
34.防止block的循环引用,
guard let `self` = self else {return}
35.随机数
arc4random_uniform(11)//0...11
func rndm(min: Int, max: Int) -> Int {
if max < min {
fatalError("The max value should be greater than the min value.")
}
if min == max {
return min
}
return Int(arc4random_uniform(UInt32((max - min) + 1))) + min
}
rndm(min: 1, max: 6) //dice roll
链接:
36.字符串操作
let str = "Hello";
//截取某字符串的前3个字符串
let sub1 = str.prefix(3)
//截取某字符串的后3个字符串
let sub2 = str.suffix(3)
//通过获取字素位来截取字符串
let index1 = str.index(str.endIndex, offsetBy: -3)
let sub3 = str[index1..<str.endIndex]
//截取字符串的第1个字符到第4个字符范围的字符串
let index2 = str.index(str.startIndex, offsetBy: 1)
let index3 = str.index(str.startIndex, offsetBy: 3)
let sub4 = str[index2...index3]
//只截取字符串的一个字素,返回值是Character类型
let character = str[str.index(str.startIndex, offsetBy: 3, limitedBy: str.endIndex)!]
print("character = \(String(character))")
//返回一个可选类型的范围:Range<String.Index>
//lowerBound不包含e upperBound包含e
let range = str.range(of: "e")!
let s = str[str.startIndex..<range.lowerBound]
//替换一段内容,两个参数:替换的范围和用来替换的内容
str.replaceSubrange(start...end, with: "new")
//替换一段内容,有返回值,两个参数:要替换的内容和用来替换的内容
let reStr = h.replacingOccurrences(of: "Hello", with: "H")
链接:Swift-字符串截取、替换、插入_SSY_1992的博客-CSDN博客_swift 字符串 替换
37. UIButton设置圆角和边框及边框颜色
链接:https://my.oschina.net/huqiji/blog/3027302
38.tableview的左滑菜单
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .normal, title: __("")) { (action, sourceView, completionHandler) in
print("delete")
let id = self.information[indexPath.item].id
self.quickAlter(id: id!)
completionHandler(true)
}
let copyAction = UIContextualAction(style: .normal, title: __("")) { (action, sourceView, completionHandler) in
print("copy")
let message = self.information[indexPath.item].message
UIPasteboard.general.string = message
self.toastLabel.isHidden = false
Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false) { timer in
self.toastLabel.isHidden = true
timer.invalidate()
}
completionHandler(true)
}
let editAction = UIContextualAction(style: .normal, title: __("")) { (action, sourceView, completionHandler) in
print("edit")
Setting.quickSaveTime = 2
// self.quickMessageView.saveButton.setTitle(<#T##title: String?##String?#>, for: <#T##UIControl.State#>)
self.quickMessageView.isHidden = false
self.quickMessageView.quickTextView.text = self.information[indexPath.item].message
self.quickMessageView.quickTextView.x_placeholder = ""
self.quickMessageView.quickTextView.x_placeholderLabel.isHidden = true
self.quickMessageView.quickTextView.becomeFirstResponder()
self.clickID = self.information[indexPath.item].id!
completionHandler(true)
}
// deleteAction.backgroundColor = self.tableView.backgroundColor
deleteAction.image = UIImage(named: "delete")
deleteAction.backgroundColor = UIColor(hex: 0xF6F6F6)
copyAction.image = UIImage(named: "copy")
copyAction.backgroundColor = UIColor(hex: 0xF6F6F6)
editAction.image = UIImage(named: "edit")
editAction.backgroundColor = UIColor(hex: 0xF6F6F6)
let config = UISwipeActionsConfiguration(actions: [deleteAction,editAction,copyAction])
// 取消拉动长后自动删除
config.performsFirstActionWithFullSwipe = false
return config
}
39:alterview的封装
class AlterView: UIView{
var clickCancel:(() -> Void)?
var clickSetting:(() -> Void)?
lazy var alterView: UIView = {
let view = UIView()
view.layer.cornerRadius = 10
view.backgroundColor = .white
return view
}()
lazy var titleLable: UILabel = {
let label = UILabel()
label.text = __("暂无内容")
label.font = UIFont.systemFont(ofSize: 16, weight: .black)
return label
}()
lazy var describLabel: UILabel = {
let label = UILabel()
label.text = __("是否进入快捷回复中设置")
label.font = UIFont.systemFont(ofSize: 14)
return label
}()
lazy var cancelButton: UIButton = {
let button = UIButton()
button.setTitle(__("取消"), for: .normal)
button.setTitleColor(UIColor(hex:0x007AFF), for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 16)
button.addTarget(self, action: #selector(cnacel), for: .touchUpInside)
button.layer.borderWidth = 0.5
return button
}()
lazy var settingButton: UIButton = {
let button = UIButton()
button.setTitle(__("去设置"), for: .normal)
button.setTitleColor(UIColor(hex:0x007AFF), for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .black)
button.addTarget(self, action: #selector(gosetting), for: .touchUpInside)
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
setUP()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension AlterView{
func setUP(){
addSubview(alterView)
alterView.addSubviews(titleLable, describLabel, cancelButton, settingButton)
alterView.snp.makeConstraints { make in
make.width.equalTo(270)
make.height.equalTo(140)
make.center.equalToSuperview()
}
titleLable.snp.makeConstraints { make in
make.top.equalToSuperview().inset(19)
make.centerX.equalToSuperview()
}
describLabel.snp.makeConstraints { make in
make.top.equalTo(titleLable.snp.bottom).offset(15)
make.centerX.equalToSuperview()
}
cancelButton.snp.makeConstraints { make in
make.left.bottom.equalToSuperview()
make.width.equalTo(135)
make.height.equalTo(44)
}
settingButton.snp.makeConstraints { make in
make.right.bottom.equalToSuperview()
make.width.equalTo(135)
make.height.equalTo(44)
}
}
}
extension AlterView{
@objc func gosetting(){
clickSetting!()
}
@objc func cnacel(){
clickCancel!()
}
}
40.禁止自动旋转
// 禁止自动旋转
override var shouldAutorotate : Bool {
return false
}
41.横竖渐变
extension CAGradientLayer {
//获取彩虹渐变层
func rainbowLayer() -> CAGradientLayer {
//定义渐变的颜色
let gradientColors = [UIColor(hex: 0x000000, alpha: 1).cgColor,
UIColor(hex: 0x000000, alpha: 0).cgColor]
//定义每种颜色所在的位置
let gradientLocations:[NSNumber] = [0.0, 1.0]
//创建CAGradientLayer对象并设置参数
self.colors = gradientColors
self.locations = gradientLocations
//设置渲染的起始结束位置
self.startPoint = CGPoint(x: 0, y: 0)
self.endPoint = CGPoint(x: 0, y: 1)
return self
}
func signViewLayer() -> CAGradientLayer {
//定义渐变的颜色
let gradientColors = [UIColor(hex: 0xF2D9B6, alpha: 1).cgColor,
UIColor(hex: 0xF2BB6D, alpha: 1).cgColor]
//定义每种颜色所在的位置
let gradientLocations:[NSNumber] = [0.0, 1.0]
//创建CAGradientLayer对象并设置参数
self.colors = gradientColors
self.locations = gradientLocations
//设置渲染的起始结束位置
self.startPoint = CGPoint(x: 0, y: 0)
self.endPoint = CGPoint(x: 1, y: 0)
return self
}
}
//应用
let gradientLayer = CAGradientLayer().rainbowLayer()
//设置彩虹渐变层的frame,并插入view的layer
gradientLayer.frame = self.navView.frame
self.navView.layer.insertSublayer(gradientLayer, at: 0)
42.导航栏设置
//标题颜色
navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.white]
//背景颜色
navigationController?.navigationBar.barTintColor = UIColor(red: 66/256.0, green: 176/256.0, blue: 216/256.0, alpha: 1)
//是否透明
navigationController?.navigationBar.isTranslucent = false
//是否显隐
navigationController?.navigationBar.isHidden = false
43.label行间距
//通过富文本来设置行间距
let paraph = NSMutableParagraphStyle()
//将行间距设置为28
paraph.lineSpacing = 20
//样式属性集合
let attributes = [NSFontAttributeName:UIFont.systemFont(ofSize: 15),NSParagraphStyleAttributeName: paraph]
label.attributedText = NSAttributedString(string: str, attributes: attributes)
链接: Swift - 设置UILabel、UITextView的文字行间距
44.label下划线
label2.attributedText = NSAttributedString(string: text, attributes: [NSAttributedStringKey.underlineStyle : 1])
45.系统语言类型获取
let preferredLang = Bundle.main.preferredLocalizations.first! as NSString
46.分享弹窗
let content = URL(string: "https://apps.apple.com")
let activityVC = UIActivityViewController(activityItems: [content as Any], applicationActivities: nil)
if UIDevice.current.userInterfaceIdiom == .pad {
if let wppc = activityVC.popoverPresentationController {
wppc.sourceView = UIView()
}
}
//分享弹窗拉下后执行
activityVC.completionWithItemsHandler = { (activityType, completed, returnedItems, error) in
if completed {
Marketing.shared.didShareRT()
}
}
present(activityVC, animated: true, completion: nil)
47.阴影设置
//设置视图边框宽度
view.layer.borderWidth = width
//设置边框颜色
view.layer.borderColor = bColor.cgColor
//设置边框圆角
view.layer.cornerRadius = radius
//设置阴影颜色
view.layer.shadowColor = sColor.cgColor
//设置透明度
view.layer.shadowOpacity = opacity
//设置阴影半径
view.layer.shadowRadius = radius
//设置阴影偏移量
view.layer.shadowOffset = offset
链接: Swift-视图阴影篇 - 简书
48.相册权限与设置跳转封装
import Foundation
import Photos
import Toolkit
class AssetLibrary {
}
// MARK: - Permission
extension AssetLibrary {
static func requestPermissions(_ authorizedBlock: @escaping () -> Swift.Void) {
//相册
let currentStatus = PHPhotoLibrary.authorizationStatus()
switch currentStatus {
case .notDetermined:
PHPhotoLibrary.requestAuthorization({ (status) in
if status == .authorized {
DispatchQueue.main.async(execute: {
authorizedBlock()
})
}
})
case .authorized:
authorizedBlock()
case .denied:
let message = String(format: __("我们无权访问图片库,请更改隐私设置"), Util.appName())
let title = __("无法访问相册")
AssetLibrary.presentAskPermissionAlert(message: message, title: title)
case .restricted:
break
case .limited:
break
@unknown default:
fatalError()
}
}
private static func presentAskPermissionAlert(message: String,title: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: __("取消"), style: .cancel, handler: nil))
alert.addAction(UIAlertAction(title: __("去设置"), style: .default, handler: { (_) in
// UIApplication.shared.openURL(URL(string: UIApplication.openSettingsURLString)!)
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
}))
Util.topViewController().present(alert, animated: true, completion: nil)
}
static func image(asset: PHAsset,
size: CGSize,
scale: CGFloat = UIScreen.main.scale,
resultHandler: @escaping (UIImage?, [AnyHashable : Any]?) -> Void)
{
let options = PHImageRequestOptions()
options.deliveryMode = .opportunistic
let retinaSize = CGSize(width: size.width * scale, height: size.height * scale)
PHImageManager.default().requestImage(for: asset,
targetSize: retinaSize,
contentMode: .aspectFill,
options: options,
resultHandler:
{ (image, info) in
DispatchQueue.main.async {
resultHandler(image, info)
}
})
}
}
49.UIColor -> Int
extension UIColor {
var hexa: Int {
var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0
getRed(&red, green: &green, blue: &blue, alpha: &alpha)
return Int(alpha * 255) << 24
+ Int(red * 255) << 16
+ Int(green * 255) << 8
+ Int(blue * 255)
}
}
50.网络判定
import Foundation
import UIKit
import Alamofire
enum ReachabilityStatus{
case notReachable
case unknown
case ethernetOrWiFi
case wwan
}
class RLHTTPManage: NSObject {
static let rlHttpManage = RLHTTPManage()
func netWorkReachability(reachabilityStatus: @escaping(ReachabilityStatus)->Void){
let manager = NetworkReachabilityManager.init()
manager!.startListening { (status) in
//wifi
if status == NetworkReachabilityManager.NetworkReachabilityStatus.reachable(.ethernetOrWiFi){
print("------.wifi")
reachabilityStatus(.ethernetOrWiFi)
}
//不可用
if status == NetworkReachabilityManager.NetworkReachabilityStatus.notReachable{
print("------没网")
reachabilityStatus(.notReachable)
}
//未知
if status == NetworkReachabilityManager.NetworkReachabilityStatus.unknown{
print("------未知")
reachabilityStatus(.unknown)
}
//蜂窝
if status == NetworkReachabilityManager.NetworkReachabilityStatus.reachable(.cellular){
print("------蜂窝")
reachabilityStatus(.wwan)
}
}
}
}
51.图片质量优化
extension UIImage {
func normalized() -> UIImage {
if (self.imageOrientation == UIImage.Orientation.up) {
return self;
}
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale);
let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
self.draw(in: rect)
if let normalizedImage = UIGraphicsGetImageFromCurrentImageContext() {
UIGraphicsEndImageContext()
return normalizedImage
} else {
return self
}
}
func resizeImage() -> UIImage? {
let originalImg = self
//prepare constants
let width = originalImg.size.width
let height = originalImg.size.height
let scale = width/height
var sizeChange = CGSize()
if width <= 1280 && height <= 1280 { //a,圖片寬或者高均小於或等於1280時圖片尺寸保持不變,不改變圖片大小
return originalImg
}else if width > 1280 || height > 1280 {//b,寬或者高大於1280,但是圖片寬度高度比小於或等於2,則將圖片寬或者高取大的等比壓縮至1280
if scale <= 2 && scale >= 1 {
let changedWidth:CGFloat = 1280
let changedheight:CGFloat = changedWidth / scale
sizeChange = CGSize(width: changedWidth, height: changedheight)
}else if scale >= 0.5 && scale <= 1 {
let changedheight:CGFloat = 1280
let changedWidth:CGFloat = changedheight * scale
sizeChange = CGSize(width: changedWidth, height: changedheight)
}else if width > 1280 && height > 1280 {//寬以及高均大於1280,但是圖片寬高比大於2時,則寬或者高取小的等比壓縮至1280
if scale > 2 {//高的值比較小
let changedheight:CGFloat = 1280
let changedWidth:CGFloat = changedheight * scale
sizeChange = CGSize(width: changedWidth, height: changedheight)
}else if scale < 0.5{//寬的值比較小
let changedWidth:CGFloat = 1280
let changedheight:CGFloat = changedWidth / scale
sizeChange = CGSize(width: changedWidth, height: changedheight)
}
}else {//d, 寬或者高,只有一個大於1280,並且寬高比超過2,不改變圖片大小
return originalImg
}
}
UIGraphicsBeginImageContext(sizeChange)
//draw resized image on Context
originalImg.draw(in: CGRect(x: 0, y: 0, width: sizeChange.width, height: sizeChange.height))
//create UIImage
let resizedImg = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return resizedImg
}
}
//使用
image.normalized().resizeImage()
52.使view在controller上
self.navigationController?.view.addSubview(view)
self.view.bringSubviewToFront(view)//把操作层也放到最上面
if #available(iOS 13, *) {
UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.addSubview(retainView)
} else {
UIApplication.shared.keyWindow!.addSubview(retainView)
}
53.UIView的自适应高度
//主要原理便是给予UIView里最后一个元素的bottom与UIView的关系
54.label文本不同颜色设置
func textColorChange(labelObject:InputView, text:String){
// 1. 获取 StoryBoard 中 Label 的原有属性
let attributes = labelObject.titleLabel.attributedText!.attributes(at: 1, effectiveRange: NSRangePointer(bitPattern: 0))
// 2. 创建新的可编辑的字符对象
let mString = NSMutableAttributedString(string: text,
attributes: attributes)
// 3. 在生成的 NSMutableAttributedString 对象中修改前两位的颜色
mString.setAttributes(
[NSAttributedString.Key.foregroundColor : UIColor.red],
range: NSRange(location: 0, length: 1)
)
// 4. 修改后面剩余字符的颜色
mString.setAttributes(
[NSAttributedString.Key.foregroundColor : UIColor(hex: 0x666666)],
range: NSRange(location: 1, length: mString.string.count - 1)
)
// 5. 把修改好的 NSMutableAttributedString 重新赋值给 Label
labelObject.titleLabel.attributedText = mString
}
Swift 修改字符串的范围颜色 NSAttributedString NSMutableAttributedString_十月ooOO的博客-CSDN博客
55.自定义类型转json文本,json转对象
import Foundation
public protocol CGYJSON {
func toJSONModel() -> AnyObject?
func toJSONString() -> String?
}
extension CGYJSON {
public func toJSONModel() -> AnyObject? {
let mirror = Mirror(reflecting: self)
guard mirror.children.count > 0 else {
return self as? AnyObject
}
var result: [String: AnyObject] = [:]
var superClss = mirror.superclassMirror()
while superClss != nil {
for case let (label?, value) in superClss!.children {
if let jsonValue = value as? CGYJSON {
result[label] = jsonValue.toJSONModel()
}
}
superClss = superClss?.superclassMirror()
}
for case let (label?, value) in mirror.children {
if let jsonValue = value as? CGYJSON {
result[label] = jsonValue.toJSONModel()
}
}
return result
}
public func toJSONString() -> String? {
guard let jsonModel = self.toJSONModel() else {
return nil
}
let data = try? NSJSONSerialization.dataWithJSONObject(jsonModel, options: [])
let str = NSString(data: data!, encoding: NSUTF8StringEncoding)
return str as? String
}
}
extension Optional: CGYJSON {
public func toJSONModel() -> AnyObject? {
if let _self = self {
if let value = _self as? CGYJSON {
return value.toJSONModel()
}
}
return NSNull()
}
}
extension Array: CGYJSON {
public func toJSONModel() -> AnyObject? {
var results: [AnyObject] = []
for item in self {
if let ele = item as? CGYJSON {
if let eleModel = ele.toJSONModel() {
results.append(eleModel)
}
}
}
return results
}
}
extension Dictionary: CGYJSON {
public func toJSONModel() -> AnyObject? {
var results: [String: AnyObject] = [:]
for (key, value) in self {
if let key = key as? String {
if let value = value as? CGYJSON {
if let valueModel = value.toJSONModel() {
results[key] = valueModel
continue
}
} else if let value = value as? AnyObject {
results[key] = value
continue
}
results[key] = NSNull()
}
}
return results
}
}
extension NSDate: CGYJSON {
public func toJSONModel() -> AnyObject? {
let dateFormat = NSDateFormatter()
dateFormat.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
return dateFormat.stringFromDate(self)
}
}
extension String: CGYJSON {}
extension Int: CGYJSON {}
extension Int8: CGYJSON {}
extension Int16: CGYJSON {}
extension Int32: CGYJSON {}
extension Int64: CGYJSON {}
extension UInt: CGYJSON {}
extension UInt8: CGYJSON {}
extension UInt16: CGYJSON {}
extension UInt32: CGYJSON {}
extension UInt64: CGYJSON {}
extension Bool: CGYJSON {}
extension Float: CGYJSON {}
extension Double: CGYJSON {}
//js json转对象
var json = JSON.parse(str);
var json = eval("(" + str + ")");
var json = (new Function("return " + str))();