一:Swift3.0為視圖添加旋轉動畫,效果如下:

代碼實作:
//建立動畫
let anim = CABasicAnimation(keyPath: "transform.rotation")
//設定相關屬性
anim.toValue = * M_PI
anim.repeatCount = MAXFLOAT
anim.duration =
//完成之後不移除,testView被釋放,動畫随着一起删除
anim.isRemovedOnCompletion = false
testView(anim, forKey: nil)
二:解決項目中每次界面跳轉隐藏TabBar的問題
思路:在 UINavigationController
中重寫 pushViewController
方法,不必每次跳轉都調用 hidesBottomBarWhenPushed
UINavigationController
pushViewController
hidesBottomBarWhenPushed
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
//隐藏tabbar
if childViewControllers.count > {
viewController.hidesBottomBarWhenPushed = true
}
super.pushViewController(viewController, animated: animated)
}
三:Swift3.0中使用 NSLayoutConstraint
為控件添加限制
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: , constant: ))
view.addConstraint(NSLayoutConstraint(item: centerButton, attribute: .centerY, relatedBy: .equal, toItem: self.view, attribute: .centerY, multiplier: , constant: -))
view.addConstraint(NSLayoutConstraint(item: centerButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: , constant: ))
view.addConstraint(NSLayoutConstraint(item: centerButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: , constant: ))
方法解讀:
在view視圖中,為 參數1
添加限制
參數1
設定 參數1(一般為視圖)
的 參數2(坐标或寬高)
屬性 參數3(大于等于小魚)
參數4(參照視圖)
的 參數5(坐标或寬高)
屬性 乘以 參數6
加上 參數7
參數1(一般為視圖)
參數2(坐标或寬高)
參數3(大于等于小魚)
參數4(參照視圖)
參數5(坐标或寬高)
參數6
注意:單純設定寬高的時候,參數4傳入 nil
,參數5傳入 .notAnAttribute
nil
.notAnAttribute
view.addConstraint(NSLayoutConstraint(item: 參數, attribute: 參數, relatedBy: 參數, toItem: 參數, attribute: 參數, multiplier: 參數, constant: 參數))
四: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
的寫法
&error
var error: NSError?
context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error)
六:動态設定 TableView
的滑動範圍
TableView
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//一般擷取最後控件的最大Y坐标,labelExplain是最後一個cell下追加的控件
self.tableView.contentSize = CGSizeMake(,CGRectGetMaxY(self.labelExplain.frame) + );
}
七: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(, 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
.h
Demo-Bridge.h
2>在 Build Setteings
中找到 Objective_C Bridging Header
添加路徑 $(SRCROOT)/Demo/Demo-Bridge.h
Build Setteings
Objective_C Bridging Header
$(SRCROOT)/Demo/Demo-Bridge.h
3>包含 Objective_C
頭檔案,例如: #import "UIView+WebCache.h"
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
喚醒全局搜尋并進入輸入狀态
command + shift + F
2>切換 Find
為 Replace
(這裡也可以采用正則進行查找搜尋 Regular Expression
)
Find
Replace
Regular Expression
3>輸入要搜尋的内容和替換結果,然後點選 Replace All
即可
Replace All
十四: NSUserDefaults
判斷應用程式是否是安裝完首次次啟動
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:()-test
十六:修改預設開發語言(Xcode預設開發語言是英語
Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結<持續添加更新...> )
1>先添加英語之外的一種語言
2> Show in Finder
工程檔案 –> 顯示包内容 –> 用文本打開 project.pbxproj
–> 搜尋 developmentRegion
–> 将值改為 zh-Hans
Show in Finder
project.pbxproj
developmentRegion
zh-Hans
3>修改成功
Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結<持續添加更新...>
十七:使用 runtime
為分類添加屬性
runtime
我們知道系統的 UITableView
的 section
和 row
屬性,就是定義在 NSIndexPath
的分類裡的
UITableView
section
row
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
方法,例如:
OC
get
- (DataModel *)model
{
if (!_model) {
_model = [[DataModel alloc] init];
_model.title = @"标題";
}
return _model;
}
swift
中有專門的懶加載修飾符 lazy
,實作如下:
swift
lazy
private lazy var model: DataModel = {
let model = DataModel()
model.title = "标題"
return model
}()
二十:Swift中 shouldAutorotate
的重寫
shouldAutorotate
override open var shouldAutorotate: Bool {
return false / true
}
//或者
open override var shouldAutorotate: Bool {
get {
return false / true
}
}
二十一:螢幕旋轉的時候狀态欄顯示問題
如果是在視圖 View
中,重寫 layoutSubviews
;如果是在 ViewController
中重寫 viewWillLayoutSubviews
, Swift
代碼如下:
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
isEqualToString
==
: 比較的是記憶體位址
==
isEqual
: 是 NSObject
的方法,首先都會判斷指針是否相等 ,相等直接傳回 YES
,不相等再判斷是否是同類對象或非空,空或非同類對象直接傳回 NO
,而後依次判斷對象對應的屬性是否相等,若均相等,傳回 YES
isEqual
NSObject
YES
NO
YES
isEqualToString
: 是 NSString
的方法,從繼承關系角度來說是 isEqual
的衍生方法,在都是字元串的前提下,判斷字元串的内容是否相等,如果知道了兩個對象都是字元串, isEqualToString
比 isEqual
要快
isEqualToString
NSString
isEqual
isEqualToString
isEqual
二十三:修改 GitHub
項目顯示語言
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
值
Masonry
Frame
需要立即更新子視圖的布局後擷取即可
二十六: Xcode
同時打開兩個 Simulator
模拟器(做通信 APP
友善調試)
Xcode
Simulator
APP
打開終端進到xcode路徑下的Applications路徑
$:cd /Applications/Xcode.app/Contents/Developer/Applications/
打開模拟器
$:open -n Simulator.app/
或者執行一個腳本也可以,建立檔案 xim.sh
,鍵入以下代碼
xim.sh
#!/bin/sh
cd /Applications/Xcode.app/Contents/Developer/Applications/
open -n Simulator.app/
sudo sh sim.sh
會有如下提示:
點選 OK
後,換一個與目前模拟器裝置不同的機型
OK
然後在 Xcode
中選擇剛選取的機型 run
包即可同時打開調試
Xcode
run
實際上多開别的 APP
道理也是一樣的,進到 APP
應用目錄, open -n appName.app/
即可
APP
APP
open -n appName.app/
二十七: TableView
檢測滑動到底部和頂部(可用于聊天界面取曆史消息)
TableView
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.y == scrollView.contentSize.height - scrollView.frame.size.height) {
NSLog(@"滑到底部加載更多");
}
if (scrollView.contentOffset.y == ) {
NSLog(@"滑到頂部更新");
}
}
// 另外點選狀态欄會調用
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
{
NSLog(@"點選狀态欄調用");
}
二十八:區分 __weak
, __unsafe_unretained
, __block
__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 = ;
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: animated:YES];
}
}
}