記錄一些iOS學習過程當中的筆記html
option + command + /
複製代碼
關閉代碼正則表達式
textField.resignFirstResponder()
複製代碼
關閉方式1: 在Controller中重寫touchesEnded()方法,而後在這裏面關閉軟件盤,意思是點擊空白處關閉json
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
name.resignFirstResponder()
}
複製代碼
關閉方式2: 點擊下一步時,關閉軟鍵盤; Controller實現UITextFieldDelegate協議; 實現UITextFieldDelegate協議中的textFieldShouldReturn方法;swift
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
複製代碼
func calAge(by datePicker: UIDatePicker) -> Int? {
let gregorian = NSCalendar(calendarIdentifier: .gregorian)
let now = Date()
let components = gregorian?.components(NSCalendar.Unit.year, from: datePicker.date, to: now, options: NSCalendar.Options.init(rawValue: 0))
return components?.year
}
複製代碼
有兩個Controller:ViewController和GalleryViewController。從ViewController跳轉到GalleryViewController。 ViewController重寫方法:prepare,該方法在頁面跳轉時會被調用,咱們須要在裏面判斷是跳轉到哪一個頁面。api
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// 須要給Segue取名
if segue.identifier == "GoToGallery" {
let index = beautyPicker.selectedRow(inComponent: 0)
var imageName: String?
switch index {
case 0:
imageName = "fangbingbing"
case 1:
imageName = "libingbing"
case 2:
imageName = "wangfei"
case 3:
imageName = "yangmi"
case 4:
imageName = "zhouxu"
default:
imageName = nil
}
// 獲得下一個頁面的Controller
let vc = segue.destination as! GalleryViewController
vc.imageName = imageName
}
}
複製代碼
beautyImage.image = UIImage(named: imageName)
複製代碼
關閉頁面後,Controller能夠得到上個頁面傳回來的值 該方法寫在前一個頁面數組
@IBAction func closedPrePage(segue: UIStoryboardSegue) {
print("closed")
}
複製代碼
if #available(iOS 11.0, *) {
tableView.contentInsetAdjustmentBehavior = .never
}
複製代碼
collectionView?.contentInset.top = -UIApplication.shared.statusBarFrame.height
複製代碼
let refreshControl = UIRefreshControl()
// 初始化刷新
refreshControl.backgroundColor = UIColor.blue //設置刷新的背景顏色
refreshControl.attributedTitle = NSAttributedString(string: "刷新一下:\(Data())", attributes: [NSAttributedStringKey.foregroundColor: UIColor.white]) // 設置字體顏色
refreshControl.tintColor = UIColor.green // 加載菊花顏色
refreshControl.tintAdjustmentMode = .dimmed // 色彩調整模式
refreshControl.addTarget(self, action: #selector(addcount), for: .valueChanged) //添加方法目標
// 添加該刷新
tableView.refreshControl = refreshControl
複製代碼
刷新方法緩存
@objc func addcount() {
dataArrary.append(contentsOf: dataArrary)
tableView.reloadData()
refreshControl.endRefreshing()
}
複製代碼
developer.apple.com/documentati…服務器
因爲iOS的用的字體名稱並非文件名稱,而是字體自己名稱。 下面代碼搜索全部字體,而後咱們在控制檯,找到多出來的名稱。app
for family: String in UIFont.familyNames
{
print("\(family)")
for names: String in UIFont.fontNames(forFamilyName: family)
{
print("== \(names)")
}
}
複製代碼
override func viewDidLoad() {
super.viewDidLoad()
let appearance = UITabBarItem.appearance()
appearance.setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "Ubuntu-Light", size: 9)!], for: .normal)
}
複製代碼
.isEnabled = false
後圖片按鈕的背景圖片被改變UIButton.adjustsImageWhenDisabled = false
複製代碼
@IBDesignable extension UIButton {
@IBInspectable var borderWidth: CGFloat {
set {
layer.borderWidth = newValue
}
get {
return layer.borderWidth
}
}
@IBInspectable var cornerRadius: CGFloat {
set {
layer.cornerRadius = newValue
}
get {
return layer.cornerRadius
}
}
@IBInspectable var borderColor: UIColor? {
set {
guard let uiColor = newValue else { return }
layer.borderColor = uiColor.cgColor
}
get {
guard let color = layer.borderColor else { return nil }
return UIColor(cgColor: color)
}
}
}
複製代碼
extension UIButton {
func alignVertical(spacing: CGFloat = 6.0, imageBottom: CGFloat = 0.0) {
guard let imageSize = self.imageView?.image?.size,
let text = self.titleLabel?.text,
let font = self.titleLabel?.font
else { return }
self.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: -imageSize.width, bottom: -(imageSize.height + spacing), right: 0.0)
let labelString = NSString(string: text)
let titleSize = labelString.size(withAttributes: [NSAttributedStringKey.font: font])
self.imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + spacing), left: 0.0, bottom: imageBottom, right: -titleSize.width)
let edgeOffset = abs(titleSize.height - imageSize.height) / 2.0;
self.contentEdgeInsets = UIEdgeInsets(top: edgeOffset, left: 0.0, bottom: edgeOffset, right: 0.0)
}
}
複製代碼
reloadData
致使移動到列表頂部失效UIView.animate(withDuration: 0, animations: {
self.tableView.contentOffset = CGPoint.zero
}, completion: { _ in
self.tableView.reloadData()
})
複製代碼
self.collectionView?.contentInsetAdjustmentBehavior = .automatic
複製代碼
/// 獲取版本名
let appVersion = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as? String
/// 獲取版本號
let versionNumber = Bundle.main.infoDictionary!["CFBundleVersion"] as? String
複製代碼
func clearCache() {
// 取出cache文件夾目錄 緩存文件都在這個目錄下
let cachePath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.cachesDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first
// 取出文件夾下全部文件數組
let fileArr = FileManager.default.subpaths(atPath: cachePath!)
// 遍歷刪除
for file in fileArr! {
let path = cachePath?.appendingFormat("/\(file)")
if FileManager.default.fileExists(atPath: path!) {
do {
try FileManager.default.removeItem(atPath: path!)
} catch {
}
}
}
}
複製代碼
// App Store URL.
let appStoreLink = "https://itunes.apple.com/cn/app/id1144351773?mt=8"
/* First create a URL, then check whether there is an installed app that can open it on the device. */
if let url = URL(string: appStoreLink), UIApplication.shared.canOpenURL(url) {
// Attempt to open the URL.
UIApplication.shared.open(url, options: [:], completionHandler: {(success: Bool) in
if success {
print("Launching \(url) was successful")
}})
}
複製代碼
UIImageView
寬度和高度,假如設置爲60*60Clip to Bounds
,
Content Insets
選擇Never
Safe Area Relative Margins
extension UIImage {
func blurred(radius: CGFloat) -> UIImage {
let ciContext = CIContext(options: nil)
guard let cgImage = cgImage else { return self }
let inputImage = CIImage(cgImage: cgImage)
guard let ciFilter = CIFilter(name: "CIGaussianBlur") else { return self }
ciFilter.setValue(inputImage, forKey: kCIInputImageKey)
ciFilter.setValue(radius, forKey: "inputRadius")
guard let resultImage = ciFilter.value(forKey: kCIOutputImageKey) as? CIImage else { return self }
guard let cgImage2 = ciContext.createCGImage(resultImage, from: inputImage.extent) else { return self }
return UIImage(cgImage: cgImage2)
}
}
複製代碼
extension UIImage {
func overlayWith(image: UIImage, posX: CGFloat, posY: CGFloat) -> UIImage {
let newWidth = size.width < posX + image.size.width ? posX + image.size.width : size.width
let newHeight = size.height < posY + image.size.height ? posY + image.size.height : size.height
let newSize = CGSize(width: newWidth, height: newHeight)
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
draw(in: CGRect(origin: CGPoint.zero, size: size))
image.draw(in: CGRect(origin: CGPoint(x: posX, y: posY), size: image.size))
let newImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return newImage
}
}
複製代碼
img.sd_setImage(with: URL(string: "http://url"),
placeholderImage: #imageLiteral(resourceName: "default_square")) { image, error, cacheType, url in
}
複製代碼
SDWebImageDownloader
.shared()
.downloadImage(with: URL(string: "http://url"),
options: SDWebImageDownloaderOptions.init(rawValue: 0),
progress: nil,
completed: { image, data, error, finished in
if finished {
}
})
複製代碼
import AVKit
func playVideoByUrl(string: String) {
let videoURL = URL(string: string)
let player = AVPlayer(url: videoURL!)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
}
複製代碼
User Interaction Enabled
uiimageview.userInteractionEnabled = true
extension PHAsset {
func getURL(completionHandler : @escaping ((_ responseURL : URL?) -> Void)){
if self.mediaType == .image {
let options: PHContentEditingInputRequestOptions = PHContentEditingInputRequestOptions()
options.canHandleAdjustmentData = {(adjustmeta: PHAdjustmentData) -> Bool in
return true
}
self.requestContentEditingInput(with: options, completionHandler: {(contentEditingInput: PHContentEditingInput?, info: [AnyHashable : Any]) -> Void in
completionHandler(contentEditingInput!.fullSizeImageURL as URL?)
})
} else if self.mediaType == .video {
let options: PHVideoRequestOptions = PHVideoRequestOptions()
options.version = .original
PHImageManager.default().requestAVAsset(forVideo: self, options: options, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [AnyHashable : Any]?) -> Void in
if let urlAsset = asset as? AVURLAsset {
let localVideoUrl: URL = urlAsset.url as URL
completionHandler(localVideoUrl)
} else {
completionHandler(nil)
}
})
}
}
}
複製代碼
extension UIView {
var parentViewController: UIViewController? {
var parentResponder: UIResponder? = self
while parentResponder != nil {
parentResponder = parentResponder!.next
if let viewController = parentResponder as? UIViewController {
return viewController
}
}
return nil
}
}
複製代碼
extension String {
var htmlToAttributedString: NSAttributedString? {
guard let data = data(using: .utf8) else { return NSAttributedString() }
do {
return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil)
} catch {
return NSAttributedString()
}
}
var htmlToString: String {
return htmlToAttributedString?.string ?? ""
}
}
複製代碼
/// 正則表達式匹配
extension String {
func matchingStrings(regex: String) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex)
let results = regex.matches(in: self,
range: NSRange(self.startIndex..., in: self))
return results.map {
String(self[Range($0.range, in: self)!])
}
} catch let error {
print("invalid regex: \(error.localizedDescription)")
return []
}
}
}
複製代碼
extension Data {
mutating func append(_ string: String, using encoding: String.Encoding = .utf8) {
if let data = string.data(using: encoding) {
append(data)
}
}
}
複製代碼
extension Array{
mutating func randamArray() {
var list = self
for index in 0..<list.count {
let newIndex = Int(arc4random_uniform(UInt32(list.count-index))) + index
if index != newIndex {
list.swapAt(index, newIndex)
}
}
self = list
}
}
複製代碼
extension UIImage {
func blurred(radius: CGFloat) -> UIImage {
let ciContext = CIContext(options: nil)
guard let cgImage = cgImage else { return self }
let inputImage = CIImage(cgImage: cgImage)
guard let ciFilter = CIFilter(name: "CIGaussianBlur") else { return self }
ciFilter.setValue(inputImage, forKey: kCIInputImageKey)
ciFilter.setValue(radius, forKey: "inputRadius")
guard let resultImage = ciFilter.value(forKey: kCIOutputImageKey) as? CIImage else { return self }
guard let cgImage2 = ciContext.createCGImage(resultImage, from: inputImage.extent) else { return self }
return UIImage(cgImage: cgImage2)
}
}
複製代碼
extension UIImage {
func overlayWith(image: UIImage, posX: CGFloat, posY: CGFloat) -> UIImage {
let newWidth = size.width < posX + image.size.width ? posX + image.size.width : size.width
let newHeight = size.height < posY + image.size.height ? posY + image.size.height : size.height
let newSize = CGSize(width: newWidth, height: newHeight)
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
draw(in: CGRect(origin: CGPoint.zero, size: size))
image.draw(in: CGRect(origin: CGPoint(x: posX, y: posY), size: image.size))
let newImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return newImage
}
}
複製代碼
extension UIImage {
func scaled(withSize size: CGSize) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
defer { UIGraphicsEndImageContext() }
draw(in: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
return UIGraphicsGetImageFromCurrentImageContext()!
}
}
複製代碼
extension JSONEncoder {
/// 將實體類轉換成Json數據
func toJson<T: Encodable>(_ entity: T) -> String? {
guard let encodedData = try? encode(entity) else {
return nil
}
return String(data: encodedData, encoding: .utf8)
}
}
複製代碼
extension JSONDecoder {
func from<T: Decodable>(_ type: T.Type, json: String) -> T? {
do {
return try decode(type, from: json.data(using: .utf8)!)
}
catch {
return nil
}
}
}
複製代碼
extension Dictionary {
func percentEscaped() -> String {
return map { (key, value) in
let escapedKey = "\(key)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
let escapedValue = "\(value)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
return escapedKey + "=" + escapedValue
}
.joined(separator: "&")
}
}
extension CharacterSet {
static let urlQueryValueAllowed: CharacterSet = {
let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimitersToEncode = "!$&'()*+,;="
var allowed = CharacterSet.urlQueryAllowed
allowed.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
return allowed
}()
}
複製代碼
extension UIViewController {
/// 添加子ViewController
func addSubController(child: UIViewController, to: UIView? = nil) {
addChildViewController(child)
if let to = to {
child.view.frame = to.frame
to.addSubview(child.view)
}
else {
child.view.frame = view.frame
view.addSubview(child.view)
}
child.didMove(toParentViewController: self)
}
}
複製代碼
extension UIViewController {
/// 移除子ViewController
func removeSubController(child: UIViewController) {
child.willMove(toParentViewController: nil)
child.removeFromParentViewController()
child.view.removeFromSuperview()
}
}
複製代碼
extension UIViewController {
/// 關閉當前頁面
func closePage() {
self.dismiss(animated: true, completion: nil)
}
}
複製代碼
extension UIViewController {
func closeAllPage() {
//獲取根VC
var rootVC = self.presentingViewController
while let parent = rootVC?.presentingViewController {
rootVC = parent
}
//釋放全部下級視圖
rootVC?.dismiss(animated: true, completion: nil)
}
}
複製代碼
extension UIViewController {
class func displaySpinner(onView : UIView) -> UIView {
let spinnerView = UIView.init(frame: onView.bounds)
spinnerView.backgroundColor = UIColor.init(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5)
let ai = UIActivityIndicatorView.init(activityIndicatorStyle: .whiteLarge)
ai.startAnimating()
ai.center = spinnerView.center
DispatchQueue.main.async {
spinnerView.addSubview(ai)
onView.addSubview(spinnerView)
}
return spinnerView
}
class func removeSpinner(spinner :UIView) {
DispatchQueue.main.async {
spinner.removeFromSuperview()
}
}
}
複製代碼
顯示dom
let sp = UIViewController.displaySpinner(onView: self.view)
複製代碼
關閉
UIViewController.removeSpinner(spinner: sp)
複製代碼
使用
IAPHelper.shared.fetchAvailableProducts
從蘋果服務器獲取全部傳入的產品id的產品信息,傳入的參數是產品的id字符串數組IAPHelper.shared.purchase(id: id)
,id是產品idIAPHelper.shared.purchase(id: selectItem!.product_id) {alert, product, transaction in
if alert == .purchased { //購買成功
if let receiptUrl = Bundle.main.appStoreReceiptURL, let receiptData = NSData(contentsOf: receiptUrl) {
let receiptString = receiptData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
// 對receiptString加密字符串進行驗證
}
}
else if alert == .restored {
}
else if alert == .purchasing {
}
else {
}
}
複製代碼
IAPHelper 代碼
import StoreKit
enum IAPHelperAlertType{
case disabled
case restored
case purchased
case purchasing
case setProductIds
func message() -> String{
switch self {
case .setProductIds: return "未設置產品id,請調用 fetchAvailableProducts()"
case .disabled: return "購買已取消"
case .restored: return "您已成功恢復購買"
case .purchased: return "您已成功購買此商品"
case .purchasing: return "正在購買..."
}
}
}
class IAPHelper: NSObject {
static let shared = IAPHelper()
private override init() { }
fileprivate var productID = ""
fileprivate var productsRequest = SKProductsRequest()
fileprivate var productDict = [String:SKProduct]()
fileprivate var fetchProductCompletion: (([SKProduct])->Void)?
fileprivate var productToPurchase: SKProduct?
var purchaseProductCompletion: ((IAPHelperAlertType, SKProduct?, SKPaymentTransaction?) -> Void)?
// MARK: - 購買產品
func canMakePurchases() -> Bool { return SKPaymentQueue.canMakePayments() }
func purchase(id: String, completion: @escaping ((IAPHelperAlertType, SKProduct?, SKPaymentTransaction?)->Void)) {
self.purchaseProductCompletion = completion
self.productToPurchase = productDict[id]
guard let product = self.productToPurchase else {
print(IAPHelperAlertType.setProductIds.message())
fatalError(IAPHelperAlertType.setProductIds.message())
}
if self.canMakePurchases() {
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().add(payment)
print("採購產品: \(product.productIdentifier)")
productID = product.productIdentifier
}
else {
completion(.disabled, nil, nil)
}
}
// MARK: - 恢復購買
func restorePurchase(){
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().restoreCompletedTransactions()
}
// MARK: - 獲取可用的iap產品
func fetchAvailableProducts(by ids: [String], completion: @escaping (([SKProduct])->Void)){
self.fetchProductCompletion = completion
// 把您的IAP產品id放到這裏面
guard !ids.isEmpty else {
print("沒有設置產品id")
fatalError(IAPHelperAlertType.setProductIds.message())
}
productsRequest = SKProductsRequest(productIdentifiers: Set(ids))
productsRequest.delegate = self
productsRequest.start()
}
}
extension IAPHelper: SKProductsRequestDelegate, SKPaymentTransactionObserver{
// MARK: - 請求IAP產品
func productsRequest (_ request:SKProductsRequest, didReceive response:SKProductsResponse) {
if (response.products.count > 0) {
for product in response.products {
print("product.productIdentifier = \(product.productIdentifier)")
self.productDict[product.productIdentifier] = product
}
self.fetchProductCompletion?(response.products)
}
}
func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
self.purchaseProductCompletion?(.restored, nil, nil)
}
// MARK:- IAP付款隊列
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
print("調用了幾回啊!!!")
for transaction:AnyObject in transactions {
if let trans = transaction as? SKPaymentTransaction {
switch trans.transactionState {
case .purchased:
print("產品已購買")
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
self.purchaseProductCompletion?(.purchased, self.productToPurchase, trans)
break
case .failed:
print("產品購買失敗\(trans.error.debugDescription)")
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
self.purchaseProductCompletion?(.disabled, self.productToPurchase, trans)
break
case .purchasing:
print("正在購買...")
self.purchaseProductCompletion?(.purchasing, self.productToPurchase, trans)
break
case .restored:
print("產品已恢復購買")
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
self.purchaseProductCompletion?(.restored, self.productToPurchase, trans)
break
default: break
}
}
}
}
}
複製代碼