1. 程式人生 > >Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結

Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結

一:Swift3.0為檢視新增旋轉動畫,效果如下:

這裡寫圖片描述

程式碼實現:

//建立動畫
let anim = CABasicAnimation(keyPath: "transform.rotation")
//設定相關屬性
anim.toValue =  2 * M_PI
anim.repeatCount = MAXFLOAT
anim.duration = 15
//完成之後不移除,testView被釋放,動畫隨著一起刪除
anim.isRemovedOnCompletion = false 
testView(anim, forKey: nil)

二:解決專案中每次介面跳轉隱藏TabBar的問題

思路:在UINavigationController 中重寫pushViewController 方法,不必每次跳轉都呼叫hidesBottomBarWhenPushed

override func pushViewController(_ viewController: UIViewController, animated: Bool) {
    //隱藏tabbar
    if childViewControllers.count > 0 {
        viewController.hidesBottomBarWhenPushed = true
    }
    super
.pushViewController(viewController, animated: animated) }

三:Swift3.0中使用NSLayoutConstraint為控制元件新增約束

//設定通過程式碼新增Constraint,否則View還是會按照以往的autoresizingMask進行計算
centerButton.translatesAutoresizingMaskIntoConstraints = false

//依次新增X,Y, W,H
view.addConstraint(NSLayoutConstraint(item: centerButton, attribute: .centerX
, relatedBy: .equal, toItem: self.view, attribute: .centerX, multiplier: 1.0, constant: 0)) view.addConstraint(NSLayoutConstraint(item: centerButton, attribute: .centerY, relatedBy: .equal, toItem: self.view, attribute: .centerY, multiplier: 1.0, constant: -60)) view.addConstraint(NSLayoutConstraint(item: centerButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 50)) view.addConstraint(NSLayoutConstraint(item: centerButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 50))

方法解讀:

在view檢視中,為引數1新增約束

設定 引數1(一般為檢視)引數2(座標或寬高) 屬性 引數3(大於等於小魚) 引數4(參照檢視)引數5(座標或寬高) 屬性 乘以 引數6 加上 引數7

注意:單純設定寬高的時候,引數4傳入nil,引數5傳入.notAnAttribute

view.addConstraint(NSLayoutConstraint(item: 引數1, attribute: 引數2, relatedBy: 引數3, toItem: 引數4, attribute: 引數5, multiplier: 引數6, constant: 引數7))

四:Swift3.0通過十六進位制值設定UIColor

extension UIColor {
    class func colorWithHex(hexValue: UInt32) -> UIColor {
        let r = (hexValue & 0xff0000) >> 16
        let g = (hexValue & 0x00ff00) >> 8
        let b = hexValue & 0x0000ff
        return UIColor(red: CGFloat(r) / 255.0, green: CGFloat(g) / 255.0, blue: CGFloat(b) / 255.0, alpha: 1.0)
    }
}

//示例呼叫:
view.backGroundColor = UIColor.colorWithHex(hexValue: 0xff0000)

五:Swift3.0中&error的寫法

var error: NSError?
context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error)

六:動態設定TableView的滑動範圍

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    //一般獲取最後控制元件的最大Y座標,labelExplain是最後一個cell下追加的控制元件
    self.tableView.contentSize = CGSizeMake(0,CGRectGetMaxY(self.labelExplain.frame) + 10);
}

七:clipstobounds與maskstobounds的區別

clipsToBounds(UIView)
是指檢視上的子檢視,如果超出父檢視的部分就擷取掉

masksToBounds(CALayer)
卻是指檢視的圖層上的子圖層,如果超出父圖層的部分就擷取掉

八:檢視真機沙盒資料夾,檢視真機崩潰日誌

這裡寫圖片描述

九:常用的路徑位置

模擬器的位置:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs 

文件安裝位置:
/Applications/Xcode.app/Contents/Developer/Documentation/DocSets

外掛儲存路徑:
~/Library/ApplicationSupport/Developer/Shared/Xcode/Plug-ins

自定義程式碼段的儲存路徑:
~/Library/Developer/Xcode/UserData/CodeSnippets/     //如果找不到CodeSnippets資料夾,可以自己新建一個CodeSnippets資料夾。

描述檔案路徑
~/Library/MobileDevice/Provisioning Profiles

十:富文字和HTML字串互相轉化

//富文字轉html字串
- (NSString *)attriToStrWithAttributeString:(NSAttributedString *)attributeString
{
    NSDictionary *tempDic = @{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute:[NSNumber numberWithInt:NSUTF8StringEncoding]};
    NSData *htmlData = [attributeString dataFromRange:NSMakeRange(0, attributeString.length) documentAttributes:tempDic error:nil];
    return [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
}

//html字串轉富文字
- (NSAttributedString *)strToAttriWithString:(NSString *)htmlString
{
    return [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding] options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType} documentAttributes:nil error:nil];
}

十一:Swift專案中引入Objective_C三方框架後手動橋接的方法

1>手動建立一個.h的檔案,比如:Demo-Bridge.h

2>在Build Setteings 中找到 Objective_C Bridging Header 新增路徑$(SRCROOT)/Demo/Demo-Bridge.h

3>包含Objective_C標頭檔案,例如:#import "UIView+WebCache.h"

十二:UITableView多行選擇修改系統預設選擇樣式

在自定義的cell中重寫layoutSubviews

- (void)layoutSubviews
{
    [super layoutSubviews];

    // 設定UITableViewCellEditControl樣式
    for (UIControl *control in self.subviews) {
        if ([control isMemberOfClass:NSClassFromString(@"UITableViewCellEditControl")]) {
            for(UIView *view in control.subviews) {
                if([view isKindOfClass: [UIImageView class]]) {
                    UIImageView *img = (UIImageView *)view;
                    if(self.selected) {
                        //選擇狀態圖片
                        img.image= [UIImage imageNamed:@"image1"];
                    } else {
                        //未選中狀態圖片
                        img.image= [UIImage imageNamed:@"image2"];
                    }
                }
            }
        }
    }
}

十三:Xcode專案中一鍵替換專案中所有類中指定文字或程式碼

1>快捷鍵command + shift + F喚醒全域性搜尋並進入輸入狀態

2>切換FindReplace(這裡也可以採用正則進行查詢搜尋Regular Expression)

這裡寫圖片描述

3>輸入要搜尋的內容和替換結果,然後點選Replace All即可

這裡寫圖片描述

十四:NSUserDefaults判斷應用程式是否是安裝完首次次啟動

if (![[NSUserDefaults standardUserDefaults] valueForKey:@"FirstStart"]) {
    [[NSUserDefaults standardUserDefaults] setValue:@"firstStart" forKey:@"FirstStart"];
    //第一次啟動,可以設定歡迎頁或者設定預設語言
} else {
    //非第一次啟動
}

十五:Swift 設定在debug模式下列印日誌,並且鎖定程式碼位置(Objective_C列印設定)

// 可以把下列程式碼放在AppDelegate的@UIApplicationMain的上方
func DebugLog<T>(messsage : T, file : String = #file, funcName : String = #function, lineNum : Int = #line) {
    #if DEBUG
        let fileName = (file as NSString).lastPathComponent
        print("\(fileName):(\(lineNum))-\(messsage)")
    #endif
}
//使用方法
DebugLog(messsage: "test")
//輸出類名 + 程式碼行數 + 輸出資訊
ViewController.swift:(37)-test

十六:修改預設開發語言(Xcode預設開發語言是英語這裡寫圖片描述)

1>先新增英語之外的一種語言

這裡寫圖片描述

2>Show in Finder工程檔案 –> 顯示包內容 –> 用文字開啟project.pbxproj –> 搜尋developmentRegion –> 將值改為zh-Hans

這裡寫圖片描述

3>修改成功這裡寫圖片描述

十七:使用runtime為分類新增屬性

我們知道系統的UITableViewsectionrow屬性,就是定義在NSIndexPath的分類裡的

這裡寫圖片描述

示例方法:

//寫一個UIView的分類命名:UIView+Category
UIView+Category.h
//增加的屬性
@property (nonatomic, strong) NSObject *propertyTest;

UIView+Category.m
//加入執行時標頭檔案
#import <objc/runtime.h>
@implementation UIView (Category)
//獲取關聯的物件
- (NSObject *)propertyTest {
    return objc_getAssociatedObject(self, @selector(propertyTest));
}
//給物件新增關聯物件
- (void)setPropertyTest:(NSObject *)value {
    objc_setAssociatedObject(self, @selector(propertyTest), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
此後,就可以正常訪問了該屬性了

十八:App迭代開發版本號的規則

0>首先我們的App第一版本首次上線, 比如以1.0.0為首次上線的版本號

1>上線後突然發現一個嚴重的Bug那我們就要修復更新版本, 此時我們的版本號為1.0.1, 所以說如果修復Bug或者優化功能, 我們只修改疊加第三位數字, 其他不變

2>如果有了新的需求, 在原來的基礎上增加了一個新功能, 那麼我們的版本號變為1.1.0, 需要清空第三位數字為0, 來疊加修改第二位數字

3>如果App需求功能大改, 更新量非常大, 那我們的版本號變為2.0.0, 需要疊加修改第一位數字, 清空其他數字為0

十九:Swift中懶載入

先說說OC中的懶載入,通常是寫get方法,例如:

- (DataModel *)model
{
    if (!_model) {
        _model  = [[DataModel alloc] init];
        _model.title = @"標題";
    }
    return _model;
}

swift中有專門的懶載入修飾符lazy,實現如下:

private lazy var model: DataModel = {
    let model = DataModel()
    model.title = "標題"
    return model
}()

二十:Swift中shouldAutorotate的重寫

override open var shouldAutorotate: Bool {
    return false / true
}
//或者
open override var shouldAutorotate: Bool {
    get {
        return false / true
    }
}

二十一:螢幕旋轉的時候狀態列顯示問題

如果是在檢視View中,重寫layoutSubviews;如果是在ViewController中重寫viewWillLayoutSubviews,Swift程式碼如下:

//檢視控制器中
override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    UIApplication.shared.isStatusBarHidden = false
}
//檢視中
override func layoutSubviews() {
    super.layoutSubviews()
    UIApplication.shared.isStatusBarHidden = false
}

二十二:區分==,isEqual,isEqualToString

==: 比較的是記憶體地址

isEqual: 是 NSObject 的方法,首先都會判斷指標是否相等 ,相等直接返回YES,不相等再判斷是否是同類物件或非空,空或非同類物件直接返回NO,而後依次判斷物件對應的屬性是否相等,若均相等,返回YES

isEqualToString: 是NSString的方法,從繼承關係角度來說是 isEqual的衍生方法,在都是字串的前提下,判斷字串的內容是否相等,如果知道了兩個物件都是字串,isEqualToStringisEqual要快

二十三:修改GitHub專案顯示語言

開啟Terminal 進入到倉庫資料夾
$:cd /Users/MacName/Desktop/Demo

建立一個`.gitattributes`的檔案
$:touch .gitattributes

開啟檔案
$:open .gitattributes

寫入如下程式碼,比如設定語言為Swift
*.h linguist-language=swift
*.m linguist-language=swift

重新push專案到GitHub, 完成修改

二十四:Terminal命令檢視系統隱藏檔案

顯示隱藏檔案:
$:defaults write com.apple.finder AppleShowAllFiles -bool true

關閉顯示隱藏檔案:
defaults write com.apple.finder AppleShowAllFiles -bool false

***執行命令後需要開啟強制退出介面(快捷鍵option+command+esc),重啟Finder

二十五:Masonry佈局後獲取Frame

需要立即更新子檢視的佈局後獲取即可

[self layoutIfNeeded];

二十六:Xcode同時開啟兩個Simulator模擬器(做通訊APP方便除錯)

開啟終端進到xcode路徑下的Applications路徑

$:cd /Applications/Xcode.app/Contents/Developer/Applications/

開啟模擬器

$:open -n Simulator.app/

或者執行一個指令碼也可以,建立檔案xim.sh,鍵入以下程式碼

#!/bin/sh
cd /Applications/Xcode.app/Contents/Developer/Applications/

open -n Simulator.app/
sudo sh sim.sh

會有如下提示:

這裡寫圖片描述

點選OK後,換一個與當前模擬器裝置不同的機型

這裡寫圖片描述

然後在Xcode中選擇剛選取的機型run包即可同時開啟除錯

實際上多開別的APP道理也是一樣的,進到APP應用目錄,open -n appName.app/即可

二十七:TableView檢測滑動到底部和頂部(可用於聊天介面取歷史訊息)

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    if (scrollView.contentOffset.y == scrollView.contentSize.height - scrollView.frame.size.height) {
        NSLog(@"滑到底部載入更多");
    }
    if (scrollView.contentOffset.y == 0) {
        NSLog(@"滑到頂部更新");
    }
}
// 另外點選狀態列會呼叫
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
{
    NSLog(@"點選狀態列呼叫");
}

二十八:區分__weak,__unsafe_unretained,__block

__weak 在釋放指標後能夠同時將指標置為nil
__unsafe_unretained 只留下一個無效的也指標
__block 打破迴圈 copy副本 內部修改

二十九:Xcode恢復預設字型

這裡寫圖片描述

三十:UIAlertView點選背景消失的方法

- (void)longPressTableViewShowAlertView:(UIGestureRecognizer *)gesture
{
    if (gesture.state == UIGestureRecognizerStateBegan) {
        self.alertView = [[UIAlertView alloc] initWithTitle:@"請輸入審批意見" message:nil delegate:self cancelButtonTitle:@"同意" otherButtonTitles:@"駁回", nil];
        [self.alertView setAlertViewStyle:UIAlertViewStylePlainTextInput];
        self.alertView.delegate = self;
        [self.alertView show];
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
        tap.numberOfTapsRequired = 1;
        tap.cancelsTouchesInView = NO;
        [[UIApplication sharedApplication].keyWindow addGestureRecognizer:tap];
    }
}

- (void)tap:(UITapGestureRecognizer *)tap
{
    if (tap.state == UIGestureRecognizerStateEnded){
        CGPoint location = [tap locationInView:nil];
        if (![self.alertView pointInside:[self.alertView convertPoint:location fromView:self.alertView.window] withEvent:nil]){
            [self.alertView.window removeGestureRecognizer:tap];
            [self.alertView dismissWithClickedButtonIndex:0 animated:YES];
        }
    }
}

相關推薦

Swift / Objective_C / Xcode實際開發可能遇到的功能技巧總結

一:Swift3.0為檢視新增旋轉動畫,效果如下: 程式碼實現: //建立動畫 let anim = CABasicAnimation(keyPath: "transform.rotation") //設定相關屬性 anim.toValue =

Java 反射在實際開發的應用

放松 hello set 加載器 glib 應該 throwable tde ffffff   運行時類型識別(RTTI, Run-Time Type Information)是Java中非常有用的機制,在java中,有兩種RTTI的方式,一種是傳統的,即假設在編譯時已

Java 數據類型在實際開發應用二枚舉

項目 arraylist font 編譯器 tid null left join 基本 size   在實際編程中,往往存在著這樣的“數據集”,它們的數值在程序中是穩定的,而且“數據集”中的元素是有限的。在JDK1.5之前,人們用接口來描述這一種數據類型。 1.5以後引入枚

經驗 windows目錄在實際開發使用/代替

路徑 斜杠 反斜杠 轉義#include <boost\shared_ptr.hpp>盡量不要使用\,而是使用/,這樣子方面移植代碼到Linux 環境下代碼如下:#include "stdafx.h"#include <iostream>#include <fstream>

HTML <area><map>標簽及在實際開發的應用

覆蓋 們的 大量 pla ren 創建 lock walk note 之前,我一直以為HTML <area>是一個雞肋HTML,估計到了HTML5時代會被廢棄的命。但是,最近一查資料,乖乖了個咚,不僅沒被廢棄,反而發展了,新增了一些標簽屬性,例如rel,medi

tomcat配置虛擬路徑,可以解決實際開發測試時前端訪問後臺電腦上的圖片的問題

ram 使用 mage height 顯示 地址 cal 重啟 server 首先電腦上要已經安裝好tomcat,安裝tomcat的教程可以從網上找到很多。這裏就不贅述了。 一般開始做一個web項目後,會涉及到用戶頭像,商品圖片等信息,這些圖片保存在項目中不方便,於是我將選

[轉]Java 反射在實際開發的應用

擴展 pub 多對一 容器 redis 連接 一起 odin mapping 一:Java類加載和初始化 1.1 類加載器(類加載的工具) 1.2 Java使用一個類所需的準備工作 二:Java中RTTI   2.1 :為什麽要用到運行時類型信息

收集 - 實際開發技巧記錄【頁面】

clas 固定 text pan pre ips -o pac 設置 文本類: ● 單行文本溢出顯示省略號: 主要 CSS 屬性是 text-overflow,值設為 ellipsis,另外需要給文本容器設置固定的 width 值。CSS 代碼如下: overfl

Solr05-Solr在實際開發的應用

示例 文件 主機 博客 版本 擴展 測試 責任 3.4 目錄 1 配置中文分詞器 1.1 準備IK中文分詞器 1.2 配置schema.xml文件 1.2.1 加入使用IK分詞器的域類型 1.2.2 加入使用IK分詞器的域 1.3 重啟Tomcat並測試 2 配置業務

RunLoop六:在實際開發的應用 之 控制執行緒生命週期(執行緒保活) 二

八、 停止 NSRunLoop 執行 上章提到了 ,只有控制器釋放了。執行緒沒有被釋放。這是因為 程式碼 卡在了 [[NSRunLoop currentRunLoop] run];這句程式碼. 任務執行完成後,執行緒會銷燬。但是 有 run 方法的話。代表系統一直在執行run

RunLoop六:在實際開發的應用 之 控制執行緒生命週期(執行緒保活)

一、前言 OC 的程式設計師大多數用過的 AFNetwork 這個網路請求框架。這個框架中就使用了 RunLoop 技術,去控制子執行緒的生命週期。 相當於 它建立了一個子執行緒,這個子執行緒會一直都在記憶體中,不會死亡。當某個時間段需要子執行緒工作時,會告訴子執行緒需要做什麼?過一段時間,

RunLoop五:在實際開發的應用

一、在實際開發中的應用 控制執行緒生命週期(執行緒保活) 解決NSTimer在滑動時停止工作的問題 監控應用卡頓 效能優化 二、控制執行緒生命週期(執行緒保活) 在專案中會遇到建立一個子執行緒去做一些事情。為什麼要建立一個子執行緒去做事情?因為如果把所

設計模式在實際開發的應用

分析功能:1.接到專案後要先分析好模組,分析好模組後再從模組裡分析功能,把一個大的專案分成N個模組再把模組分析成N個功能點,把每個功能點都進行封裝,有一個管理類進行管理。 程式碼邏輯分工 程式碼要做到層層管理,一個類管理著另外的一個些管理類,管理類裡面又要管理封裝一些功能點。做這一部分的時候建議使

android---實際開發遇到的問題總結

在實際開發專案的時候經常會遇到一些問題,在這裡進行總結,希望讀者在遇到相同問題的時候能夠儘快解決自己的問題,或者為讀者提供一種解決方案 問題1:          隨著專案的逐漸增大,不可避免

專案實際開發遇到的事務問題

廢話不多說 看功能: 最近做了一個app的記步功能,要求是app一開啟就開始進行步數的計算,然後一分鐘向後臺傳送一次資料儲存到資料庫中,此時儲存的是使用者的走的步數和有效步數(有效步數是在一分鐘內步頻大於90的算是真正的走路)和有效時間,然後當你開啟記步頁面的時候,又一個請求一分鐘一次

實際開發String轉換為json串作為入參發生"JSON parse error:Cannot deserialize value of type Date......not a valid解決

實際開發中,String拼接成json串作為入參請求介面,發生以下錯誤 {     "timestamp": "2018-11-09 14:55:49",     "status": 400,     "error": "Bad R

實際開發,解決iReport列印圖片不顯示問題

ireport  中增加圖片,新增上屬性,但是執行時報錯如下,是屬性logoPath沒有宣告到map中 1. Parameter not found : logoPath net.sf.jasperreports.engine.design.JRValid

實際開發,解決列印iReport獲取list集合遍歷,並且縮小間距

用iReport做列印的時候,在後端程式碼中得到map集合後,map中存放list 用$F獲取屬性,欄屬性代表每行的空、間隔 /*** * * @author xxx * @param checkVisaReqVo *

實際開發,獲得到的list為重複的最後一條資料問題解決

在開發中迴圈把物件中的值賦給list,最後取得list進行返回。老是會出現獲得的list是重複的值,並且值為最後一個物件。 這就是開發中沒有宣告好物件和list的位置。都應該在外面宣告list和物件。 注意:物件要在迴圈裡重新初始化一次,否則最後一個數據會把前面的資料全部覆蓋掉。注意第9

實際開發遇到java.lang.NoSuchMethodError

在開發中遇到java.lang.NoSuchMethodError的錯誤。 java.lang.NoSuchMethodError: com.sinosoft.ims.api.kernel.dto.RequestPrpDuserDto.getCodeMethod()Ljava/lang/Stri