天天看點

Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結<持續添加更新...>

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

Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結<持續添加更新...>

代碼實作:

//建立動畫
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

override func pushViewController(_ viewController: UIViewController, animated: Bool) {
    //隐藏tabbar
    if childViewControllers.count >  {
        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: , 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(一般為視圖)

參數2(坐标或寬高)

屬性

參數3(大于等于小魚)

參數4(參照視圖)

參數5(坐标或寬高)

屬性 乘以

參數6

加上 參數7

注意:單純設定寬高的時候,參數4傳入

nil

,參數5傳入

.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

的寫法

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

六:動态設定

TableView

的滑動範圍

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

七:clipstobounds與maskstobounds的差別

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

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

八:檢視真機沙盒檔案夾,檢視真機崩潰日志

Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結<持續添加更新...>

九:常用的路徑位置

模拟器的位置:
/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

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>切換

Find

Replace

(這裡也可以采用正則進行查找搜尋

Regular Expression

)

Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結<持續添加更新...>

3>輸入要搜尋的内容和替換結果,然後點選

Replace All

即可

Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結<持續添加更新...>

十四:

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實際開發中可能遇到的小功能小技巧總結&lt;持續添加更新...&gt;
)

1>先添加英語之外的一種語言

Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結&lt;持續添加更新...&gt;

2>

Show in Finder

工程檔案 –> 顯示包内容 –> 用文本打開

project.pbxproj

–> 搜尋

developmentRegion

–> 将值改為

zh-Hans

Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結&lt;持續添加更新...&gt;

3>修改成功
Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結&lt;持續添加更新...&gt;

十七:使用

runtime

為分類添加屬性

我們知道系統的

UITableView

section

row

屬性,就是定義在

NSIndexPath

的分類裡的

Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結&lt;持續添加更新...&gt;

示例方法:

//寫一個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

的衍生方法,在都是字元串的前提下,判斷字元串的内容是否相等,如果知道了兩個對象都是字元串,

isEqualToString

isEqual

要快

二十三:修改

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

需要立即更新子視圖的布局後擷取即可

二十六:

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
           

會有如下提示:

Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結&lt;持續添加更新...&gt;

點選

OK

後,換一個與目前模拟器裝置不同的機型

Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結&lt;持續添加更新...&gt;

然後在

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 == ) {
        NSLog(@"滑到頂部更新");
    }
}
// 另外點選狀态欄會調用
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
{
    NSLog(@"點選狀态欄調用");
}
           

二十八:區分

__weak

,

__unsafe_unretained

,

__block

__weak 在釋放指針後能夠同時将指針置為nil
__unsafe_unretained 隻留下一個無效的也指針
__block 打破循環 copy副本 内部修改
           

二十九:Xcode恢複預設字型

Swift / Objective_C / Xcode實際開發中可能遇到的小功能小技巧總結&lt;持續添加更新...&gt;

三十: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];
        }
    }
}