IOS开发Swift——开发小知识(持续更新)
如有错误,请指正!谢谢!
侵权删!(部分转载)
1.PHAsset获取本地视频的url
PHCachingImageManager().requestAVAsset(forVideo: asset, options:nil, resultHandler: { (asset, audioMix, info)inlet avAsset = asset as? AVURLAssetprint(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 = .clearlet 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) inif 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: userCollectionsas! PHFetchResult<PHAssetCollection>)//相册按包含的照片数量排序(降序)self.items.sort { (item1, item2) -> Bool inreturn 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.automaticlet 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 = videoPathsession.outputFileType = session.supportedFileTypes.firstsession.exportAsynchronously(completionHandler: {switch session.status {case .failed:print("移出失败")breakcase .completed:print("移出成功")breakdefault: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] inlet url = photoUrlprint(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 Photosvar isHEIC = false
let resources = PHAssetResource.assetResources(for: asset)
for resource in resources {let uti = resource.uniformTypeIdentifierif uti == "public.heic" || uti == "public.heif" {isHEIC = truebreak}
}PHImageManager.default().requestImageData(for: asset, options: nil) { (imageData, dataUTI, orientation, info) inif 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! NSNumberisLocal = 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.uniformTypeIdentifierif uti == "public.heic" || uti == "public.heif" {isHEIC = truebreak}
}PHImageManager.default().requestImageData(for: assetObject, options: nil) { (imageData, dataUTI, orientation, info) inif 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 foregroundprint("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! UITouchprint(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 = nextwhile 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
}
链接:Swift - 使用闭包筛选过滤数据元素
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.standardstruct 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.blackheader.textLabel?.font = UIFont.systemFont(ofSize:16 ,weight:.black)header.textLabel?.frame = header.frameheader.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 = 15view.clipsToBounds = trueview.backgroundColor = .whitereturn view}()
32.coredata的封装使用
class Message{var id:Int32?var message:String?init(id:Int32?,message:String){self.id = idself.message = message}
}
///添加数据
public func addData(id:Int32,message:String)
{// 用來操作 Core Data 的常數let moc = (UIApplication.shared.delegateas! AppDelegate).persistentContainer.viewContextlet myEntityName = "MessageData"// insertlet student =NSEntityDescription.insertNewObject(forEntityName: myEntityName, into: moc)as! MessageDatastudent.id = idstudent.message = messagedo {try moc.save()print("success")} catch {fatalError("\(error)")}
}/// 查询数据
func queryData() -> [Message]
{//获取管理的数据上下文 对象var dataArr:[Message] = []let app = UIApplication.shared.delegate as! AppDelegatelet 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! AppDelegatelet 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! AppDelegatelet 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 Foundationimport UIKitfileprivate 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_04extension 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 = falseNotificationCenter.default.addObserver(self, selector: #selector(x_textChange(noti:)), name: UITextView.textDidChangeNotification, object: nil)addSubview(label)label.snp.makeConstraints { (make) inmake.edges.equalToSuperview().inset(UIEdgeInsets(top: 8, left: 6, bottom: 0, right: 0))}}/// 编辑事件@objc fileprivate func x_textChange(noti: NSNotification) {let isEmpty = text.isEmptyprint("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...11func 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
链接:
随机数
Swift中的随机数 - 知乎
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包含elet 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) inprint("delete")let id = self.information[indexPath.item].idself.quickAlter(id: id!)completionHandler(true)}let copyAction = UIContextualAction(style: .normal, title: __("")) { (action, sourceView, completionHandler) inprint("copy")let message = self.information[indexPath.item].messageUIPasteboard.general.string = messageself.toastLabel.isHidden = falseTimer.scheduledTimer(withTimeInterval: 1.5, repeats: false) { timer inself.toastLabel.isHidden = truetimer.invalidate()}completionHandler(true)}let editAction = UIContextualAction(style: .normal, title: __("")) { (action, sourceView, completionHandler) inprint("edit")Setting.quickSaveTime = 2
// self.quickMessageView.saveButton.setTitle(<#T##title: String?##String?#>, for: <#T##UIControl.State#>)self.quickMessageView.isHidden = falseself.quickMessageView.quickTextView.text = self.information[indexPath.item].messageself.quickMessageView.quickTextView.x_placeholder = ""self.quickMessageView.quickTextView.x_placeholderLabel.isHidden = trueself.quickMessageView.quickTextView.becomeFirstResponder()self.clickID = self.information[indexPath.item].id!completionHandler(true)}// deleteAction.backgroundColor = self.tableView.backgroundColordeleteAction.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 = falsereturn config}
39:alterview的封装
class AlterView: UIView{var clickCancel:(() -> Void)?var clickSetting:(() -> Void)?lazy var alterView: UIView = {let view = UIView()view.layer.cornerRadius = 10view.backgroundColor = .whitereturn 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.5return 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 inmake.width.equalTo(270)make.height.equalTo(140)make.center.equalToSuperview()}titleLable.snp.makeConstraints { make inmake.top.equalToSuperview().inset(19)make.centerX.equalToSuperview()}describLabel.snp.makeConstraints { make inmake.top.equalTo(titleLable.snp.bottom).offset(15)make.centerX.equalToSuperview()}cancelButton.snp.makeConstraints { make inmake.left.bottom.equalToSuperview()make.width.equalTo(135)make.height.equalTo(44)}settingButton.snp.makeConstraints { make inmake.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 = gradientColorsself.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 = gradientColorsself.locations = gradientLocations//设置渲染的起始结束位置self.startPoint = CGPoint(x: 0, y: 0)self.endPoint = CGPoint(x: 1, y: 0)return self}
}//应用let gradientLayer = CAGradientLayer().rainbowLayer()//设置彩虹渐变层的frame,并插入view的layergradientLayer.frame = self.navView.frameself.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])
链接: 创建一个带下划线的UILabel - 简书
45.系统语言类型获取
let preferredLang = Bundle.main.preferredLocalizations.first! as NSString
链接: swift 获取当前系统语言 - 简书
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) inif 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 Toolkitclass AssetLibrary {}// MARK: - Permission
extension AssetLibrary {static func requestPermissions(_ authorizedBlock: @escaping () -> Swift.Void) {//相册let currentStatus = PHPhotoLibrary.authorizationStatus()switch currentStatus {case .notDetermined:PHPhotoLibrary.requestAuthorization({ (status) inif 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:breakcase .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 = .opportunisticlet retinaSize = CGSize(width: size.width * scale, height: size.height * scale)PHImageManager.default().requestImage(for: asset,targetSize: retinaSize,contentMode: .aspectFill,options: options,resultHandler:{ (image, info) inDispatchQueue.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 = 0getRed(&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 Alamofireenum ReachabilityStatus{case notReachablecase unknowncase ethernetOrWiFicase wwan}class RLHTTPManage: NSObject {static let rlHttpManage = RLHTTPManage()func netWorkReachability(reachabilityStatus: @escaping(ReachabilityStatus)->Void){let manager = NetworkReachabilityManager.init()manager!.startListening { (status) in//wifiif 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 constantslet width = originalImg.size.widthlet height = originalImg.size.heightlet scale = width/heightvar sizeChange = CGSize()if width <= 1280 && height <= 1280 { //a,圖片寬或者高均小於或等於1280時圖片尺寸保持不變,不改變圖片大小return originalImg}else if width > 1280 || height > 1280 {//b,寬或者高大於1280,但是圖片寬度高度比小於或等於2,則將圖片寬或者高取大的等比壓縮至1280if scale <= 2 && scale >= 1 {let changedWidth:CGFloat = 1280let changedheight:CGFloat = changedWidth / scalesizeChange = CGSize(width: changedWidth, height: changedheight)}else if scale >= 0.5 && scale <= 1 {let changedheight:CGFloat = 1280let changedWidth:CGFloat = changedheight * scalesizeChange = CGSize(width: changedWidth, height: changedheight)}else if width > 1280 && height > 1280 {//寬以及高均大於1280,但是圖片寬高比大於2時,則寬或者高取小的等比壓縮至1280if scale > 2 {//高的值比較小let changedheight:CGFloat = 1280let changedWidth:CGFloat = changedheight * scalesizeChange = CGSize(width: changedWidth, height: changedheight)}else if scale < 0.5{//寬的值比較小let changedWidth:CGFloat = 1280let changedheight:CGFloat = changedWidth / scalesizeChange = CGSize(width: changedWidth, height: changedheight)}}else {//d, 寬或者高,只有一個大於1280,並且寬高比超過2,不改變圖片大小return originalImg}}UIGraphicsBeginImageContext(sizeChange)//draw resized image on ContextoriginalImg.draw(in: CGRect(x: 0, y: 0, width: sizeChange.width, height: sizeChange.height))//create UIImagelet 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 重新赋值给 LabellabelObject.titleLabel.attributedText = mString}
Swift 修改字符串的范围颜色 NSAttributedString NSMutableAttributedString_十月ooOO的博客-CSDN博客
55.自定义类型转json文本,json转对象
import Foundationpublic 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] = valueModelcontinue}} else if let value = value as? AnyObject {results[key] = valuecontinue}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))();
链接:https://github.com/Chakery/JSONExample
IOS开发Swift——开发小知识(持续更新)相关推荐
- golang 小知识-持续更新中
Golang 中的指针 - Pointer Go 的原生数据类型可以分为基本类型和高级类型,基本类型主要包含 string, bool, int 及 float 系列,高级类型包含 struct,ar ...
- Unity3D小功能 小技巧 小教程 小原理(持续更新...)
Unity3D小功能 小技巧 小教程 小原理(持续更新...) 1.Unity的.NET版本是2.0 按道理来说,C#能用的功能Unity也能用,但是Unity的.NET却不是最新版 要是用一些别的D ...
- 前端开发技术栈(插件篇):400+常用前端开发插件总结清单(持续更新......)
常用前端开发插件总结清单,日常前端开发的时候,尤其在使用一些常用的功能的时候,例如:表单,,动画效果,时间选择,文件上传,下拉框等功能.直接用插件可以让自己节省更多的开发时间,更多的去关心业务,自己封 ...
- 快应用开发常见问题以及解决方案【持续更新】
接触快应用也有一段时间了,踩过了大大小小的坑,让我活到了今天.准备在此立贴持续更新,记录遇到的问题以及解决方案,造福大众. css 方面 1.文字竖排不支持 目前官方还不支持writing-mode, ...
- AutoCAD2019+vs2019+C# 二次开发学习笔记day01(持续更新)
目录 一.新建项目 1.应用程序 目标框架 选择 4.7.2版 2.生成 目标平台选择x64 3.调试 启动外部程序 选择 acad.exe 二.添加autocad类库 三.如何运用命名空间 1.[C ...
- Android开发样式问题总结【持续更新】
目录 Android控件/框架开源库收集 配置国内仓库 1. Java中设置控件的大小需要把dp先转换为像素(转换如下) 2. Java中设置GridLayout布局的layout_columnWei ...
- iOS开发-审核被拒原因总结[持续更新]
交流群 更多iOS审核问题欢迎加QQ群 828079826 GitHub整理的分类被拒方案,欢迎大家pull request. AppStoreReviewGuidelines 即将实行的隐私政策要求 ...
- ASP.NET 开发小技巧 (持续更新)
有时为一些小问题而去查资料.浪费太多的时间,为此把开发中经常遇到的一些小问题.记录下来.供日常开发查询用: 1.项目中使用Forms验证.而有些文件又不需要验证就能访问,最常见的是验证码文件或admi ...
- 小飞鱼通达二开 小飞鱼OA开发案例集锦目录(持续更新)
工作流二次开发 小飞鱼通达二开 <小飞鱼工作流超级管理中心>助你流程管理效率轻松提升十倍+! 小飞鱼通达二开 通达OA工作流超时自动转交程序,让工作流加速到360迈!(图文) 小飞鱼软件 ...
最新文章
- 最简单的日历控件“星期几”变为“几”
- DL-3利用MNIST搭建神经网络模型(三种方法):1.用CNN 2.用CNN+RNN 3.用自编码网络autoencoder
- 【Linux】一步一步学Linux——Centos7.5安装图解(08)
- 《转》程序员必须知道的10大基础实用算法及其讲解
- 华南理工计算机接口技术随堂练习_研究生考试计算机408跟845有什么区别?
- 工作243:name报错
- Netty线程模型和核心概念
- android表情面板_Android Q:应用内设置面板
- 【课程作业】学术英语写作:文献阅读报告1
- border和boder-radius
- 分享5款小众软件,大家按需下载
- 大型网站技术架构-核心原理与案例分(李智慧 著)第1章-大型网站架构演化
- GYM 101350 I. Mirrored String II
- 计算机x线影像ppt,计算机X线摄影课件
- Convolutional Neural Networks on Graphs with Fast Localized Spectral Filtering 论文阅读
- “达内”JAVA技术培训有感(二)
- 实现仿百度图片查看功能(点击缩略图放大效果)
- Android 编译之source和lunch
- 漫谈程序员系列 请区别对待女程序员
- (转)Apache对文件后缀解析的分析利用