在開(kāi)發(fā)中經(jīng)常會(huì)遇到一些問(wèn)題,剛開(kāi)始感覺(jué)匪夷所思,但是當(dāng)你真正探究,理解了就會(huì)發(fā)現(xiàn)確實(shí)如此。
19、translatesAutoresizingMaskIntoConstraints
translatesAutoresizingMaskIntoConstraints
屬性和autolayout有關(guān),
如果你定義的view想用autolayout,就將translatesAutoresizingMaskIntoConstraints設(shè)為NO,如果你使用的不是autolayout,就將translatesAutoresizingMaskIntoConstraints設(shè)為YES,對(duì)應(yīng)關(guān)系如下
autolayout | translatesAutoresizingMaskIntoConstraints |
---|---|
是 | NO |
否 | YES |
18、navigationBar setBackgroundImage和setBarTintColor區(qū)別
在處理導(dǎo)航要不要透明時(shí)發(fā)現(xiàn)了下面的問(wèn)題,
[nav.navigationBarsetBackgroundImage:[UIImageimageNamed:@"bt_green.png"]forBarMetrics:UIBarMetricsDefault];
用這個(gè)來(lái)跑的效果是在Xib里UI不用+64像素,
[nav.navigationBar setBarTintColor:[ColorTool colorWithHexString:COLOR_THEME_NAVIGATION]]; [nav.navigationBar setTintColor:[ColorTool colorWithHexString:COLOR_THEME_NAVIGATION]];
使用這2個(gè)方法來(lái)定義導(dǎo)航顏色時(shí),在Xib里的UI實(shí)際位置需要+64個(gè)像素,
使用設(shè)置了
nav.navigationBar.translucent =NO;
在配合上面2個(gè)方法就能達(dá)到和setBackgroundImage
一樣的效果。這都是在ios7之后的變化。
可以去體驗(yàn)下。
- navigation controller容器中布局到ios7中往上偏移了64px
iOS6中默認(rèn)的布局將從navigation bar的底部開(kāi)始,但到了iOS7中默認(rèn)布局從navigation bar的頂部開(kāi)始,這就是為什么所有的UI元素都往上漂移了。因?yàn)樵趇OS7中,蘋(píng)果引入了一個(gè)新的屬性,叫做[UIViewController setEdgesForExtendedLayout:]
,它的默認(rèn)值為UIRectEdgeAll,使用edgesForExtendedLayout指定視圖的哪條邊需要擴(kuò)展,不用理會(huì)操作欄的透明度。所以這種情況快速修復(fù)的方法是:在-(void)viewDidLoad中添加如下一行代碼:
self.edgesForExtendedLayout = UIRectEdgeNone;
extendedLayoutIncludesOpaqueBars
關(guān)于這個(gè)屬性的測(cè)試版本中默認(rèn)值是YES,正式版本是NO!
如果你使用了不透明的navigation bar,設(shè)置edgesForExtendedLayout 還是默認(rèn)值UIRectEdgeAll,你又想整個(gè)view全屏(navigation bar下面的內(nèi)容網(wǎng)上漂移64px) extendedLayoutIncludesOpaqueBars 的值設(shè)置為YES。
17、other linker flags參數(shù)的作用
在前面我們說(shuō)如果出現(xiàn)問(wèn)題要在Other Linker Flags中加入-ObjC或者-all_load或者-force_load,我們?yōu)槭裁匆尤脒@樣的參數(shù)呢,他們究竟做了什么事呢?下面就是對(duì)這個(gè)三個(gè)參數(shù)的一個(gè)講解.
ObjC
: 一般這個(gè)參數(shù)足夠解決前面提到的問(wèn)題,這個(gè)flag告訴鏈接器把庫(kù)中定義的Objective-C類(lèi)和Category都加載進(jìn)來(lái)。這樣編譯之后的app會(huì)變大,因?yàn)榧虞d了很多不必要的文件而導(dǎo)致可執(zhí)行文件變大。但是如果靜態(tài)庫(kù)中有類(lèi)和category的話(huà)只有加入這個(gè)flag才行,但是Objc也不是萬(wàn)能的,當(dāng)靜態(tài)庫(kù)中只有分類(lèi)而沒(méi)有類(lèi)的時(shí)候,Objc就失效了,這就需要使用-all_load或者-force_load了。-all_load
: -all_load會(huì)強(qiáng)制鏈接器把目標(biāo)文件都加載進(jìn)來(lái),即使沒(méi)有objc代碼。但是這個(gè)參數(shù)也有一個(gè)弊端,那就是你使用了不止一個(gè)靜態(tài)庫(kù)文件,那么你很有可能會(huì)遇到ld: duplicate symbol錯(cuò)誤,因?yàn)椴煌膸?kù)文件里面可能會(huì)有相同的目標(biāo)文件 這里會(huì)有兩種方法解決 1:用命令行就行拆包. 2:就是用下面的這個(gè)參數(shù)-force_load
: 這個(gè)flag所做的事情跟-all_load其實(shí)是一樣的,只是-force_load需要指定要進(jìn)行全部加載的庫(kù)文件的路徑,這樣的話(huà),你就只是完全加載了一個(gè)庫(kù)文件,不影響其余庫(kù)文件的按需加載 .
總結(jié)
-
個(gè)人建議ObjC與force_load搭配使用比較好.
16、 如果項(xiàng)目中打了斷點(diǎn),但是Debug時(shí)不停,那可能時(shí)BuildSettings中了關(guān)掉了。修改Generate Debug Symbols
為YES
。
15、數(shù)組中排序可能使用 NSStringCompareOptions,每個(gè)參數(shù)的意義如下:
typedefNS_OPTIONS(NSUInteger, NSStringCompareOptions) {
NSCaseInsensitiveSearch = 1, //不區(qū)分大小寫(xiě)比較
NSLiteralSearch = 2, //逐字節(jié)比較 區(qū)分大小寫(xiě)
NSBackwardsSearch = 4, //從字符串末尾開(kāi)始搜索
NSAnchoredSearch = 8, //搜索限制范圍的字符串
NSNumericSearch = 64, //按照字符串里的數(shù)字為依據(jù),算出順序。例如 Foo2.txt < Foo7.txt < Foo25.txt
NSDiacriticInsensitiveSearchNS_ENUM_AVAILABLE(10_5, 2_0) = 128,//忽略 "-" 符號(hào)的比較
NSWidthInsensitiveSearchNS_ENUM_AVAILABLE(10_5, 2_0) = 256,//忽略字符串的長(zhǎng)度,比較出結(jié)果
NSForcedOrderingSearchNS_ENUM_AVAILABLE(10_5, 2_0) = 512,//忽略不區(qū)分大小寫(xiě)比較的選項(xiàng),并強(qiáng)制返回 NSOrderedAscending 或者 NSOrderedDescending
NSRegularExpressionSearchNS_ENUM_AVAILABLE(10_7, 3_2) = 1024 //只能應(yīng)用于 rangeOfString:..., stringByReplacingOccurrencesOfString:...和 replaceOccurrencesOfString:... 方法。使用通用兼容的比較方法,如果設(shè)置此項(xiàng),可以去掉 NSCaseInsensitiveSearch 和 NSAnchoredSearch
};
14、NavigationBar自定義高度和調(diào)整子控件的位置
- 設(shè)置navigationbar的高度
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, ScreenWidth, 64)];
[self.navigationController.navigationBar addSubview:view];
- 設(shè)置子空間的位置
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.navigationController.navigationBar setTitleVerticalPositionAdjustment:20.0 forBarMetrics:UIBarMetricsDefault];
[self.navigationItem.leftBarButtonItem setBackgroundVerticalPositionAdjustment:20.0 forBarMetrics:UIBarMetricsDefault];
}
- (void)viewDidDisappear:(BOOL)animated{
[self.navigationController.navigationBar setTitleVerticalPositionAdjustment:0.0 forBarMetrics:UIBarMetricsDefault];
[self.navigationItem.leftBarButtonItem setBackgroundVerticalPositionAdjustment:0.0 forBarMetrics:UIBarMetricsDefault];
}
注:上述運(yùn)行結(jié)果的前提是使用自定義圖片的leftBarButtonItem作為返回按鈕替代系統(tǒng)默認(rèn)的 backBarButtonItem,并且你的leftBarButtonItem是使用 initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action這個(gè)方法創(chuàng)建的(原因我后面會(huì)講)。
問(wèn)題1:系統(tǒng)默認(rèn)的導(dǎo)航欄返回按鈕垂直位置無(wú)法調(diào)節(jié)。
當(dāng)返回按鈕使用系統(tǒng)默認(rèn)的backBarButtonItem的時(shí)候,使用UIBarButtonItem的- (void)setBackButtonBackgroundVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics來(lái)調(diào)整它的垂直位置,不起作用。
問(wèn)題2:自定義的返回按鈕在導(dǎo)航欄中的垂直位置僅在某一種情況下可以調(diào)節(jié)。
后來(lái)我又發(fā)現(xiàn),即使不用系統(tǒng)默認(rèn)地返回按鈕,使用自定義的leftBarButtonItem,也只在使用 initWithImage:style target:action:這個(gè)方法創(chuàng)建的UIBarButtonItem時(shí)生效,使用其他init方法情況一律無(wú)效。至于什么原因不明覺(jué)厲。
參考:小荷才露尖尖角的iOS 如何自定義NavigationBar的高度
13、point的轉(zhuǎn)換
-(CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;//點(diǎn)轉(zhuǎn)換
-(CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view;//點(diǎn)轉(zhuǎn)換
-(CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;//矩形轉(zhuǎn)換
-(CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;//矩形轉(zhuǎn)換
使用注意:
1.使用convertPoint:toView:時(shí),調(diào)用者應(yīng)為covertPoint的父視圖。即調(diào)用者應(yīng)為point的父控件。toView即為需要轉(zhuǎn)換到的視圖坐標(biāo)系,以此視圖的左上角為(0,0)點(diǎn)。
2.使用convertPoint:fromView:時(shí)正好相反,調(diào)用者為需要轉(zhuǎn)換到的視圖坐標(biāo)系。fromView為point所在的父控件。
3.toView可以為nil。此時(shí)相當(dāng)于toView傳入self.view.window
12、CATransform3D是一個(gè)4 x 4的矩陣,矩陣中每一個(gè)值所代表的意義
struct CATransform3D
{
CGFloat m11(x縮放), m12(y切變), m13(旋轉(zhuǎn)), m14();
CGFloat m21(x切變), m22(y縮放), m23(), m24();
CGFloat m31(旋轉(zhuǎn)), m32( ), m33(), m34(透視效果,要操作的這個(gè)對(duì)象要有旋轉(zhuǎn)的角度,否則沒(méi)有效果。正直/負(fù)值都有意義);
CGFloat m41(x平移), m42(y平移), m43(z平移), m44();
};
11、Xcode7 升級(jí)到Xcode8 一編寫(xiě)代碼就閃退問(wèn)題,記錄下,希望對(duì)有些小伙伴有用。PS:也是網(wǎng)上友人的解決方法。
xcode升級(jí)到8之后 ,插件不能用了,就又從心裝了一下插件裝完插件之后,再打開(kāi)xcode,發(fā)現(xiàn)一寫(xiě)代碼就閃退,很是郁悶。。。網(wǎng)上找了一下資料,發(fā)現(xiàn)是插件KSImageName的問(wèn)題,于是把這個(gè)插件刪除,重啟了一下xcode就可以了
xcode插件的路徑:~/Library/Developer/Xcode/Plug-ins
老版本:~/Library/Developer/Application Support/Developer/Shared/Xcode/Plug-ins
10、Xcode 工程文件打開(kāi)不出來(lái), cannot be opened because the project file cannot be parsed.
svn更新代碼后,打開(kāi)xcode工程文件,會(huì)出現(xiàn) xxx..xcodeproj cannot be opened because the project file cannot be parsed.
因?yàn)?xcodeproj工程文件沖突了,然后還是會(huì)強(qiáng)制更新,內(nèi)部文件出現(xiàn)了沖突,所以解析不了文件。
會(huì)出現(xiàn)這樣的沖突消息
<<<<<<< .mine 9ADAAC6A15DCEF6A0019ACA8 .... in Resources */, ======= 52FD7F3D15DCEAEF009E9322 ... in Resources */, >>>>>>> .r269
解決方法:
- 1.對(duì).xcodeproj 文件右鍵,顯示包內(nèi)容
- 2.雙擊打開(kāi) project.pbxproj 文件
- 3.找到以上類(lèi)似的沖突信息(可以用commad + f 搜索)
- 4.刪除 <<<<<<<,======,>>>>>>這些行
- 5.保存,退出
- 6.重新打開(kāi).xcodeproj文件即可
9 、button 文字圖片上下/左右經(jīng)常會(huì)用到,記錄一下
- 上下:
self.rechargeButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;//使圖片和文字水平居中顯示
[self.rechargeButton setTitleEdgeInsets:UIEdgeInsetsMake(self.rechargeButton.imageView.frame.size.height+10 ,-self.rechargeButton.imageView.frame.size.width, 0.0,0.0)];//文字距離上邊框的距離增加imageView的高度,距離左邊框減少imageView的寬度,距離下邊框和右邊框距離不變
[self.rechargeButton setImageEdgeInsets:UIEdgeInsetsMake(-10, 0.0,0.0, -self.rechargeButton.titleLabel.bounds.size.width)];//圖片距離右邊框距離減少圖片的寬度,其它不邊
- 左右:(因?yàn)槟J(rèn)button 圖片在左,文字在右, 下面代碼是反過(guò)來(lái)的: 文字 圖片)
[self.DetailButton setTitleEdgeInsets:UIEdgeInsetsMake(0, -self.DetailButton.imageView.bounds.size.width, 0, self.DetailButton.imageView.bounds.size.width)];
[self.DetailButton setImageEdgeInsets:UIEdgeInsetsMake(0, self.DetailButton.titleLabel.bounds.size.width, 0, -self.DetailButton.titleLabel.bounds.size.width)];
8、解決pod update 更新緩慢的問(wèn)題。
第一次導(dǎo)入第三包:
pod install --verbose --no-repo-update
以后每次更新:
pod update --verbose --no-repo-update
7、三種設(shè)置圖片圓角的方法
- 1.通過(guò)Layer的屬性來(lái)設(shè)置圓角
// 設(shè)置圓角半徑
view.layer.cornerRadius = cornersSize;
view.layer.masksToBounds = YES;
- 2.通過(guò)Layer和bezierPath來(lái)設(shè)置圓角,下面的方法是寫(xiě)在UIImageView的一個(gè)Category中,所以
self
是UIImageView
,可以根據(jù)項(xiàng)目需求對(duì)方法進(jìn)行相應(yīng)的改變:
//設(shè)置圓角
- (void)useShaperLayerCornersSize:(CGFloat)cornersSize {
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:cornersSize];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.bounds;
maskLayer.path = maskPath.CGPath;
self.layer.mask = maskLayer;
}
重點(diǎn):CALayer 有個(gè) mask 屬性,用作 layer 的遮罩。這個(gè)遮罩和普通蓋在上面的顯示層不同,普通的遮罩是,蓋上去,就遮住了下面的內(nèi)容,而 mask 則是遮什么顯示什么。
- 3、通過(guò)Graphics 和 BezierPath 設(shè)置圓角,下面這個(gè)方法也是寫(xiě)在
UIImageView
的分類(lèi)中:
- (void) userGraphicsCornersSize:(CGFloat )cornersSize{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 1.f);
[[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:self.frame.size.width] addClip];
[self drawRect:self.bounds];
self.image = UIGraphicsGetImageFromCurrentImageContext();
//結(jié)束畫(huà)圖
UIGraphicsEndImageContext();
}
6、UITableView當(dāng)Style是Plain時(shí),如果數(shù)據(jù)沒(méi)有一屏幕,下面的這樣顯示,沒(méi)有數(shù)據(jù)有一行行分割線(xiàn),這樣的界面往往不是我們想要的。
如何讓沒(méi)有數(shù)據(jù)的行不顯示呢?
- 1、
TableView.tableFooterView = [[UIView alloc] init];
,通過(guò)設(shè)置TableView的footerView來(lái)實(shí)現(xiàn)。 - 2、
TableView.separatorStyle = UITableViewCellSeparatorStyleNone;
設(shè)置不顯示分割線(xiàn)來(lái)實(shí)現(xiàn)。
有時(shí)候可能設(shè)置BackgroundColor
來(lái)使tableView更美觀(guān)。
5、IOS中NSLog輸出格式大全:
格式 | 對(duì)象 |
---|---|
%zd | NSInteger |
%tu | NSUInteger |
%02d | 不滿(mǎn)兩位的整數(shù)補(bǔ)0 |
%.2f | 保留兩位小數(shù) |
%@ | 對(duì)象 |
%d, %i | 整數(shù) |
%u | 無(wú)符整形 |
%f | 浮點(diǎn)/雙字 |
%x, %X | 二進(jìn)制整數(shù) |
%o | 八進(jìn)制整數(shù) |
%zu | size_t |
%p | 指針 |
%e | 浮點(diǎn)/雙字 (科學(xué)計(jì)算) |
%g | 浮點(diǎn)/雙字 |
%s | C 字符串 |
%.*s | Pascal字符串 |
%c | 字符 |
%C | unichar |
%lld | 64位長(zhǎng)整數(shù)(long long) |
%llu | 無(wú)符64位長(zhǎng)整數(shù) |
%Lf | 64位雙字 |
4、如何設(shè)置TabBar圖片的渲染顏色
-
使用過(guò)TabBarController的小伙伴都知道,蘋(píng)果提供按鈕選中的默認(rèn)顏色是藍(lán)色,假如UI給你一張有顏色的TabBar選中圖片,如下:
projecselect.png
但是你會(huì)悲催的發(fā)現(xiàn)事實(shí)不是這樣的,而是下面這樣的:
QQ20170224-145338.png
如何使用原始的圖片呢?
實(shí)際上當(dāng)你設(shè)置選中圖片時(shí),如果不需要渲染圖片,需要這樣設(shè)置
[tabBarItem setSelectedImage:[[UIImage imageNamed:@"xxx"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
UIImageRenderingModeAlwaysOriginal
這個(gè)屬性可以完成你所想要的效果。
- 如果你想你的TabBar跟隨主題顏色變化,當(dāng)然也可以提供多套主題顏色相關(guān)的圖片,但是這樣太繁瑣了,我們可以通過(guò)設(shè)置TabBar的tintColor來(lái)實(shí)現(xiàn):
self.tabBar.tintColor = [UIColor orangeColor];
3、UITableView分割線(xiàn)
- IOS7以后UITableView的分割線(xiàn)距離左側(cè)會(huì)有一點(diǎn)的距離,如何讓分割線(xiàn)從屏幕左邊開(kāi)始呢?分別在ViewController中這兩個(gè)方法中添加如下代碼:
//設(shè)置分割線(xiàn)距離左側(cè)屏幕距離為零 ios 7;
-(void)viewDidLayoutSubviews
{
if ([self.mainTableView respondsToSelector:@selector(setSeparatorInset:)]) {
[self.mainTableView setSeparatorInset:UIEdgeInsetsMake(0,0,0,0)];
}
if ([self.mainTableView respondsToSelector:@selector(setLayoutMargins:)]) {
[self.mainTableView setLayoutMargins:UIEdgeInsetsMake(0,0,0,0)];
}
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
2、NavigationBar 設(shè)置Item顏色和文字顏色
-
iOS7以前:
- tintColor:設(shè)置navigationBar和navigationItem的顏色,navigationItem里面的字體默認(rèn)為白色,如果想修改navigationItem字體顏色,需要自定義給navigationItem(Custom)。
-
iOS7之后(新增barTintColor屬性):
- tintColor:不再是以前的設(shè)置navigationBar和navigationItem的顏色,而是變成了只修改navigationItem里面的字體顏色。
- barTintColor:設(shè)置navigationBar和navigationItem的顏色,由于iOS7的navigationItem以文字的方式體現(xiàn),默認(rèn)為藍(lán)色,所以barTintColor看似乎對(duì)navigationItem無(wú)效。
此外,如果想修改NavigationBar標(biāo)題的顏色,可以通過(guò)設(shè)置
titleTextAttributes
屬性來(lái)改變,顏色,字體,陰影等都可以設(shè)置
NSDictionary * dict = [NSDictionary dictionaryWithObject:color forKey:NSForegroundColorAttributeName];
//大功告成
self.navigationController.navigationBar.titleTextAttributes = dict;
1、圖片緩存
應(yīng)用中經(jīng)常會(huì)加載圖片,SDWebImage為我們提供了方便高效的請(qǐng)求網(wǎng)絡(luò)資源圖片的方法,但是有時(shí)候我們需要請(qǐng)求的圖片可能服務(wù)器修改了,但是SDWebImage緩存還沒(méi)有失效,這樣的話(huà)就無(wú)法正確實(shí)時(shí)的展示服務(wù)器修改的圖片。
SDWebImage可以通過(guò)
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options
方法中的options - SDWebImageOptions
來(lái)設(shè)置緩存策略。SDWebImageRefreshCached
每次都刷新緩存,但是這需要服務(wù)器配合:setHeader("Cache-Control", "no-cache");
要禁用緩存。-
還有一種方法就是簡(jiǎn)單粗暴的,直接清空?qǐng)D片緩存
- 一種是磁盤(pán)緩存
[[[SDWebImageManager sharedManager] imageCache] clearDisk];
- 一種為內(nèi)存緩存
[[[SDWebImageManager sharedManager] imageCache] clearMemory];
- 在IOS7中你會(huì)發(fā)現(xiàn)使用這兩個(gè)方法緩存總清除不干凈,即使斷網(wǎng)下還是會(huì)有數(shù)據(jù)。這是因?yàn)樵贗OS7中,緩存機(jī)制做了修改,使用上述兩個(gè)方法只清除了SDWebImage的緩存,沒(méi)有清除系統(tǒng)的緩存,所以我們可以在清除緩存的代理中額外添加以下
[[NSURLCache sharedURLCache] removeAllCachedResponses];
- 一種是磁盤(pán)緩存