- 連續(xù)使用多目運(yùn)算符要謹(jǐn)慎,容易漏掉特殊的情況
- 點(diǎn)擊彈出的微信消息再返回,點(diǎn)擊某些控件不能隱藏(默認(rèn)點(diǎn)擊隱藏/顯示)
- 操場(chǎng)形狀的進(jìn)度條.
- 顯示兩位小數(shù),不夠的以0來替補(bǔ)
- 箭頭居中的氣泡
- 兩種不同的App Store 跳轉(zhuǎn)方式:
- copyWithZone:方法也可以返回一個(gè)可以打印的字符串
- 跳到橫屏控制器
- 讓UIScrollView只沿著一個(gè)方向滑動(dòng)
- block 中的UI操作無(wú)法實(shí)現(xiàn)
- <NSIndexPath: 0xc000000001a00016> {length = 2, path = 0 - 13}
- YYLabel 只顯示一行
- AFN 請(qǐng)求接口時(shí) , 斷言 請(qǐng)求的NSUrl對(duì)象為 nil .
- 適配 iPhone X 的時(shí)候 , 屏幕高度始終為 667.
- 紅色嘆號(hào)的invalid bitcode signature
- 解析字符串中的 json 串
- 將 debug安裝包 安裝到 xcode 模擬器中
- "xx.app"已損壞溉愁,打不開。您應(yīng)該將它移到廢紙簍
- Embedded binary's bundle identifier is not prefixed with the parent app's bundle identifier.
- UILabel 在設(shè)置attributedText 的值時(shí) , numberOfLines屬性不生效
- 取消 UITableView 的 cell 被選中的方法
- 繼承 UITableViewCell 時(shí) , 重寫 init 方法沒有被調(diào)用
- 觸發(fā)按鈕點(diǎn)擊事件的方法
- 子視圖的動(dòng)畫超出了父視圖
- 微信的選中效果
- 隱藏 iPhone X 全屏?xí)r的虛擬按鍵
- UpdatePublicKey: database is locked
- Command /usr/bin/codesign failed with exit code 1
- pod 導(dǎo)入的文件, file not find
- 當(dāng)前時(shí)區(qū)的時(shí)間
- The file “CycleProgressBar” couldn’t be opened because you don’t have permission to view it.
- A 跳到 B, B 跳到 C以后, 不想讓用戶看到 B, 可以通過更改UINavigationController的viewControllers.
- 比較字符串的大小, 可以用字符串的 compare 方法.
- UIScrollView無(wú)法滑動(dòng)
- 最簡(jiǎn)單快速的動(dòng)畫代碼
- 最簡(jiǎn)單的讓 UICollectionView 無(wú)限滑動(dòng)
- 視圖不顯示的幾種情況
- 崩潰MASViewConstraint install
- 讓 UIScrollView 中的視圖不跟著滑動(dòng)
- 程序設(shè)計(jì)常見問題
- 使用 hittest 時(shí), 需要考慮隱藏的視圖.
- iOS控制代碼段大小在60M 以內(nèi)
- 后臺(tái)播放的定時(shí)器, 可以使用NSObject 的performSelector:...方法.
- UITableView 的底部有多余的下劃線
- 使用 SourceTree push 代碼時(shí)彈出 password required
- git rebase 代碼時(shí), 自己的代碼合不見了, 可以通過查看 reflog 操作, 回退到某個(gè)提交
- 比較容易忽略的循環(huán)引用
- 從系統(tǒng)瀏覽器通過 schema 打開 app , APP崩潰
- 提交代碼到錯(cuò)誤的分支上, 可以使用 git cherry-pick xx命令補(bǔ)救
- 一個(gè)視圖, 在橫屏和豎屏都需要展示, 可以在切換屏幕時(shí)切換父視圖.
- 有 UIScrollView 的視圖, 無(wú)法左滑退出
- 運(yùn)行 Xcode 提示: You don't have permission to access
- MJRefresh上拉刷新到最底部后, 下拉刷新只能刷新一頁(yè)
- 圖文混排, 可以使用NSAttributedString+YYText.h分類的方法
- 響應(yīng)推送通知的系統(tǒng)方法, 有兩個(gè)
- deletesection:方法解決 MJFresh 數(shù)據(jù)較少時(shí)刷新列表, footer 無(wú)法自動(dòng)歸位的問題
- deletesection:崩潰
- YYLabel 不僅要設(shè)置4個(gè)約束, 而且在更新 textLayout 時(shí)要設(shè)準(zhǔn) contentsize.
- pause program execusion 查找dispatch_semaphore_wait
- git stash 暫存當(dāng)前的測(cè)試代碼到緩存棧.
- 誤刪git遠(yuǎn)程分支
1. 連續(xù)使用多目運(yùn)算符要謹(jǐn)慎,容易漏掉特殊的情況
1> 錯(cuò)誤代碼如下:
CGFloat AnchorLevelImgWid = isHost ? 27 : 0;
AnchorLevelImgWid = anchorLevel < 0 ? 0 : 27;
2> 以上代碼用邏輯的關(guān)系來分析,是或的關(guān)系,等價(jià)于
CGFloat AnchorLevelImgWid = 0;
if (isHost)
{
AnchorLevelImgWid = 27;
}
if (anchorLevel >= 0)
{
AnchorLevelImgWid = 27;
}
3> 但是實(shí)際需求卻是 isHost 和 anchorLevel < 0 同時(shí)為真的時(shí)候,才執(zhí)行AnchorLevelImgWid的值是27.正確的雙目運(yùn)算符應(yīng)該是
CGFloat AnchorLevelImgWid = isHost ? (anchorLevel < 0 ? 0 : 27) : 0;
2. 點(diǎn)擊彈出的微信消息再返回,點(diǎn)擊某些控件不能隱藏(默認(rèn)點(diǎn)擊隱藏/顯示)
1> 點(diǎn)不動(dòng)某些控件.
應(yīng)該是點(diǎn)擊了,但是在某些地方return 了.
2> 上老司機(jī)殺手锏------斷點(diǎn)
- 在控件被觸發(fā)的地方插入斷點(diǎn).
- 使用 MAC qq 給自己的手機(jī)發(fā)消息,并狂點(diǎn)手機(jī)的頂部,一邊讓頂部控件隱藏/顯示,一邊等待 qq 消息的彈出.
- 在 qq 中編輯后,再返回,奇跡發(fā)生了------控件的觸發(fā)方法被調(diào)用了,在一個(gè)與鍵盤變量有關(guān)的地方返回了.
- 全局搜索此方法名,發(fā)現(xiàn)是鍵盤顯示/隱藏的通知調(diào)用的.
- 得出結(jié)論:鍵盤的顯示/隱藏通知 是全局的,從當(dāng)前 app 跳到其他 app 的瞬間,也會(huì)收到該通知.
- 解決方案:收到鍵盤相關(guān)的通知后,同時(shí)判斷當(dāng)前輸入框是否是第一響應(yīng)者.
3.操場(chǎng)形狀的進(jìn)度條.
- 可以使用 layer.mask 來給視圖切圓角.
- 其子視圖即使是方的,左側(cè)也依舊會(huì)根據(jù)原始圖的 mask 路徑來切圓角,右側(cè)是直的.
- 創(chuàng)建的代碼如下:
/// 創(chuàng)建一個(gè)可以切掉圓角的 UIImageView
+ (id)imageViewWithRoundedRect:(CGSize)size radius:(NSInteger)r
{
UIImageView *newImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, size.width, size.height)];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:newImageView.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(r, r)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
//設(shè)置大小
maskLayer.frame = newImageView.bounds;
//設(shè)置圖形樣子
maskLayer.path = maskPath.CGPath;
newImageView.layer.mask = maskLayer;
return newImageView;
}
4.顯示兩位小數(shù),不夠的以0來替補(bǔ)
1> 方法一:使用%.0nf
比較方便,但是四舍五入后在某些情況下有些不準(zhǔn)確.
2> 方法二:直接使用官方自帶的貨幣計(jì)算用的類:NSDecimalNumber
- 觀察頭文件,看到了decimalNumberWithString:快速構(gòu)造方法,decimalNumberByRoundingAccordingToBehavior:行為構(gòu)造方法.
- 既然是小數(shù)精度構(gòu)造類,肯定有一個(gè)自定義的操作,來選擇精度的制造方法,很容易想到從第一條的行為構(gòu)造方法的參數(shù)------NSDecimalNumberBehaviors協(xié)議的對(duì)象 來構(gòu)造.
- 進(jìn)入該協(xié)議,看到了兩個(gè)協(xié)議方法,貌似對(duì)精度確定沒什么作用.
- 在當(dāng)前頭文件中搜索NSDecimalNumberBehaviors,不經(jīng)意間找到了遵循該協(xié)議的NSDecimalNumberHandler
- 在當(dāng)前對(duì)象中找到了decimalNumberHandlerWithRoundingMode:scale:raiseOnExactness:raiseOnOverflow:raiseOnUnderflow:raiseOnDivideByZero:方法.參數(shù)解釋如下:
// Rounding policies :
// OrgValue 1.2 1.21 1.25 1.35 1.27
// Plain 1.2 1.2 1.3 1.4 1.3 四舍五入
// Down 1.2 1.2 1.2 1.3 1.2 向下取正
// Up 1.2 1.3 1.3 1.4 1.3 向上取正
// Bankers 1.2 1.2 1.2 1.4 1.3 (特殊的四舍五入,碰到保留位數(shù)后一位的數(shù)字為5時(shí)钙勃,根據(jù)前一位的奇偶性決定。為偶時(shí)向下取正唁奢,為奇數(shù)時(shí)向上取正句灌。如:1.25保留1為小數(shù)悟耘。5之前是2偶數(shù)向下取正1.2柱恤;1.35保留1位小數(shù)時(shí)数初。5之前為3奇數(shù),向上取正1.4)
// scale : 需要保留的精度梗顺。
// raiseOnExactness : 為YES時(shí)在處理精確時(shí)如果有錯(cuò)誤泡孩,就會(huì)拋出異常。
// raiseOnOverflow : YES時(shí)在計(jì)算精度向上溢出時(shí)會(huì)拋出異常寺谤,否則返回仑鸥。
// raiseOnUnderflow : YES時(shí)在計(jì)算精度向下溢出時(shí)會(huì)拋出異常,否則返回.
// raiseOnDivideByZero : YES時(shí)变屁。當(dāng)除以0時(shí)會(huì)拋出異常眼俊,否則返回。
6.測(cè)試代碼如下:
- (void)test1
{
NSString *string = @"0.00002";
NSDecimalNumber *subtotal = [[self class] getRightTwoDecimalNumber:string];
NSString *dstStr = @"0";
if (subtotal.floatValue != 0)
{
dstStr = [self getTwoDecimalNumberStringWithNumber:subtotal];
}
NSLog(@"%@",dstStr);
}
/// 嚴(yán)格兩位小數(shù)
- (NSString *)getTwoDecimalNumberStringWithNumber:(NSNumber *)number
{
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setPositiveFormat:@"0.00"];
NSString *formattedNumberString = [numberFormatter stringFromNumber:number];
return formattedNumberString;
}
/// 獲取向下取整的兩位數(shù)
+ (NSDecimalNumber *)getRightTwoDecimalNumber:(NSString *)string
{
NSDecimalNumberHandler *handler = [NSDecimalNumberHandler
decimalNumberHandlerWithRoundingMode:NSRoundDown
scale:2
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:YES];
NSDecimalNumber *subtotal = [NSDecimalNumber decimalNumberWithString:string];
subtotal = [subtotal decimalNumberByRoundingAccordingToBehavior:handler];
return subtotal;
}
5.箭頭居中的氣泡
- 由于 iOS 只能支持圖片以一塊區(qū)域?yàn)榛鶞?zhǔn)拉伸,因此可以準(zhǔn)備兩張圖片,一張是可以左右拉伸的矩形,另一張是能遮住矩形底部邊線的中心的箭頭.
- 在文字伸縮的時(shí)候,設(shè)定矩形區(qū)域的長(zhǎng)度和拉伸方式,并讓箭頭的水平中心和矩形的一致.箭頭的頂部略微蓋過矩形區(qū)域.
- 代碼如下
CGFloat scale = [UIScreen mainScreen].scale;
CGFloat accessyOffsetY = 1.0/scale;
accessyOffsetY = (scale == 3 ? 0.34 : accessyOffsetY);
[curExpAccessoryView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(curExpView);
make.top.mas_equalTo(curExpView.mas_bottom).offset(-accessyOffsetY);
make.size.mas_equalTo(CGSizeMake(15, 3));
}];
4.對(duì)于依賴比較多約束的控件,可以先添加到父視圖上,等其他控件的創(chuàng)建代碼布局代碼都寫完了,再在最后補(bǔ)充也可以.
[_curExpLabelBgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.greaterThanOrEqualTo(_levelDetailView).priorityHigh();
make.right.lessThanOrEqualTo(_levelDetailView).priorityHigh();
make.centerX.mas_equalTo(_curExpProcessView.mas_right).priorityLow();
make.top.mas_equalTo(_seperatorLine.mas_bottom).offset(10*kBigScreenViewWidthRate);
make.width.mas_equalTo(@(0));
make.height.mas_equalTo(@(20*kBigScreenViewWidthRate));
}];
6.兩種不同的App Store 跳轉(zhuǎn)方式:
- 打開 App Store
- (void)openRateWindow
{
NSString *str = [NSString stringWithFormat:@"itms-apps://itunes.apple.com/app/id%@",@"1106329353"];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];
}
- 彈出當(dāng)前 App 評(píng)價(jià)頁(yè)面的控制器.
#import <StoreKit/StoreKit.h>
- (void)test1
{
[self openAppWithIdentifier:@"1106329353"];
}
- (void)openAppWithIdentifier:(NSString *)appId
{
SKStoreProductViewController *storeProductVC = [[SKStoreProductViewController alloc] init];
storeProductVC.delegate = self;
NSDictionary *dict = [NSDictionary dictionaryWithObject:appId forKey:SKStoreProductParameterITunesItemIdentifier];
[storeProductVC loadProductWithParameters:dict completionBlock:^(BOOL result, NSError *error) {
if (result) {
[self presentViewController:storeProductVC animated:YES completion:nil];
}
}];
}
- (void)productViewControllerDidFinish:(SKStoreProductViewController *)storeProductVC {
[storeProductVC dismissViewControllerAnimated:YES completion:^{
[self.navigationController popToRootViewControllerAnimated:YES];
}];
}
7.copyWithZone:方法也可以返回一個(gè)可以打印的字符串
- 在使用 copy 方法,復(fù)制一個(gè)對(duì)象到一個(gè)新的地址時(shí),必須實(shí)現(xiàn)copyWithZone:方法.
1.1 若實(shí)現(xiàn)時(shí)返回字符串,打印當(dāng)前對(duì)象,輸出的是字符串的內(nèi)容
1.2 否則,打印的是當(dāng)前對(duì)象的類名加地址
- (id)copyWithZone:(NSZone *)zone
{
return @"哈哈";
}
- (void)test
{
HSPerson *person1 = [[HSPerson alloc] init];
person1.name = @"HanMei";
person1.age = 18;
HSPerson *person2 = [person1 copy];
NSLog(@"%@---%@",person1,person2); // 結(jié)果是<HSPerson: 0x60800002f1c0>---哈哈
}
2.復(fù)制一個(gè)普通的對(duì)象
- (id)copyWithZone:(NSZone *)zone
{
// 使用系統(tǒng)分配的內(nèi)存 zone 創(chuàng)建相應(yīng)對(duì)象,若使用 alloc+init 效果也一樣,只是得另外開辟一段內(nèi)存
HSPerson *person = [HSPerson allocWithZone:zone];
return person;
}
- (void)test
{
HSPerson *person1 = [[HSPerson alloc] init];
person1.name = @"HanMei";
HSPerson *person2 = [person1 copy];
NSLog(@"%@---%@",person1,person2); // 結(jié)果是<HSPerson: 0x60800003cc00>---<HSPerson: 0x60800003cd60>
NSLog(@"%@---%@",person1.name,person2.name); // HanMei---(null)
}
- 由以上結(jié)果了解到, 這里的 copy 其實(shí)是深拷貝,地址發(fā)生了變化,簡(jiǎn)單了一些(不像 NSString 的 copy 那樣,由于只是字符內(nèi)容的變化,地址就不會(huì)變,想要地址變化,還得用 multyCopy)
- 但是打印 name 屬性時(shí),內(nèi)容沒有改變,需要在 copyWithZone: 方法中,給新的對(duì)象拷貝當(dāng)前HSPerson對(duì)象的內(nèi)容.
- (id)copyWithZone:(NSZone *)zone
{
// 使用系統(tǒng)分配的內(nèi)存 zone 創(chuàng)建相應(yīng)對(duì)象,若使用 alloc+init 效果也一樣,只是得另外開辟一段內(nèi)存
HSPerson *person = [HSPerson allocWithZone:zone];
person.name = self.name;
return person;
}
小結(jié):由于 copyWithZone: 方法是個(gè)對(duì)象方法,因此可以直接調(diào)用當(dāng)前對(duì)象的屬性,來拷貝到另一個(gè)對(duì)象中,以做到深拷貝,降低耦合.
8. 跳到橫屏控制器
1.在要彈出的控制器中,使用如下代碼,即可讓控制器橫屏.
@implementation LandscapeVc
- (BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft ;
}
@end
- 若要 present 一個(gè)導(dǎo)航控制器,則需要在導(dǎo)航控制器中寫出以上代碼,即可使該導(dǎo)航控制器下的所有控制器都可以橫屏.
- 若要要 present 一個(gè)導(dǎo)航控制器,而且該導(dǎo)航控制器里面的某些控制器需要橫屏,只對(duì)某些控制器使用以上代碼是不生效的,必須在導(dǎo)航控制器中實(shí)現(xiàn)以上三個(gè)方法,返回當(dāng)前最頂層控制器的橫屏策略.
@implementation LandscapeNavVc
- (BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return self.topViewController.supportedInterfaceOrientations;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return self.topViewController.preferredInterfaceOrientationForPresentation ;
}
@end
9. 讓UIScrollView只沿著一個(gè)方向滑動(dòng)
- 打開地理位置時(shí),上下滑動(dòng) scrollView 的時(shí)候,左右回來回串動(dòng).
- 雖然給 pagingEnabled 屬性設(shè)置成了 YES,但是在 scrollView 水平滑到一半的時(shí)候(不松手),卻可以上下滑動(dòng).
- 本以為需要在 scrollViewDidScroll 等代理方法中來改 contentOffset 來取消滾動(dòng)的效果,結(jié)果查了 UIScrollView 的頭文件才發(fā)現(xiàn)確實(shí)有對(duì)應(yīng)的屬性 directionalLockEnabled 可以達(dá)到此目的,很方便.
10. block 中的UI操作無(wú)法實(shí)現(xiàn)
- block 代碼中無(wú)法實(shí)現(xiàn)控件的隱藏,插入斷點(diǎn),打印日志,都是可以運(yùn)行到該地的.
2.打印一下線程,發(fā)現(xiàn)是當(dāng)前線程的 id 是17,不是主線程,因此有可能操作失敗.
11. <NSIndexPath: 0xc000000001a00016> {length = 2, path = 0 - 13}
- NSIndexPath對(duì)象其實(shí)是一個(gè)包裝后的數(shù)組,length 是數(shù)組的個(gè)數(shù),path 是每個(gè)元素的內(nèi)容....
- tableview 的 length 默認(rèn)是2,path 中第一個(gè)元素是 row, 第二個(gè)元素是13.
12. YYLabel 只顯示一行
- 看層次結(jié)構(gòu), cell 的高度略高, 但是行高稍微有點(diǎn)兒低, 只顯示一行
- 感覺是高度的問題, 就把 tableview 的行高設(shè)置高一點(diǎn)兒, 結(jié)果是正確的.
- 在顯示YYLabel的時(shí)候, 使用
YYTextLayout *layout = [YYTextLayout layoutWithContainerSize:containerSize text:attr];
計(jì)算高度的時(shí)候, 要多加幾個(gè)點(diǎn)的高度.
12. YYLabel 只顯示一行
- YYLabel 在約束沒有寫全的情況下, 只會(huì)展示一行內(nèi)容 , 代碼如下:
YYLabel *infoLabel = [[YYLabel alloc] init];
[middleView addSubview:infoLabel];
_briefContentLabel = infoLabel;
[infoLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(seperateLine.mas_bottom).offset(cInfoViewTop);
make.left.right.mas_equalTo(seperateLine);
}];
- 注釋掉以上代碼 , 使用設(shè)置 frame 的方式代替自動(dòng)布局 , 可以顯示多行 , 說明是自動(dòng)布局出問題了.
- 把該 YYLabel 的底部約束添加上就沒這個(gè)問題了.
YYLabel *infoLabel = [[YYLabel alloc] init];
[middleView addSubview:infoLabel];
_briefContentLabel = infoLabel;
[infoLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(seperateLine.mas_bottom).offset(cInfoViewTop);
make.bottom.mas_equalTo(middleView.mas_bottom);
make.left.right.mas_equalTo(seperateLine);
}];
13. AFN 請(qǐng)求接口時(shí) , 斷言 請(qǐng)求的NSUrl對(duì)象為 nil .
- po 的時(shí)候 , url 是沒問題的.
- 考慮是 url 中包含了特殊字符 , 需要轉(zhuǎn)義一下 , 可以用以下代碼
url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
- 若請(qǐng)求中含有中文字符 , 可以使用以下代碼進(jìn)行轉(zhuǎn)義
string = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
14. 適配 iPhone X 的時(shí)候 , 屏幕高度始終為 667.
- 查看層次結(jié)構(gòu) , 高度是 667 , 即 iPhone 6 的高度 .
- 在 application:didFinishLaunchingWithOptions: 方法的最開始打印高度 , 也是667.
- 創(chuàng)建一個(gè)空的項(xiàng)目 , 在 iPhone X 上面跑 , 高度是812 , 正確的 .
- 參考了這篇文章 https://segmentfault.com/a/1190000011308923 ,
我開始懷疑是啟動(dòng)圖片的大小決定了當(dāng)前屏幕的高度 . - 然后將啟動(dòng)圖片 ( Images.xcassets --> LaunchImage ) 中的配置文件 Contents.json 的images 對(duì)應(yīng)的 value 值中 , 添加如下內(nèi)容 , 并添加圖片名為"2017-04-19-Ios-1125 X 2436@3x.png"的圖片到同級(jí)目錄下 .
{
"orientation" : "portrait",
"idiom" : "iphone",
"filename" : "2017-04-19-Ios-1125 X 2436@3x.png",
"extent" : "full-screen",
"minimum-system-version" : "11.0",
"subtype" : "2436h",
"scale" : "3x"
},
15. 紅色嘆號(hào)的invalid bitcode signature
- 在替換庫(kù)文件的時(shí)候 , 有時(shí)候編譯會(huì)出現(xiàn)下圖所示的錯(cuò)誤
嘗試了這里https://juejin.im/entry/5948c3b88d6d81cc72fd2c5e所說的前幾種辦法 , 沒什么好的效果.
接著嘗試 : 把紅色嘆號(hào)文字上面的灰色嘆號(hào)里面的日志拷貝到到記事本上面 , 多次看到了這幾個(gè)關(guān)鍵字 x86_64 DerivedData .
然后我開始著手刪掉 DerivedData 文件夾 , 問題就解決了. (快捷鍵 cmd + 粟关,打開設(shè)置框 , 并點(diǎn)擊頂部的 location 菜單 , 在該菜單下點(diǎn)擊進(jìn)入按鈕)
16. 解析字符串中的 json 串
- 先將字符串中包含的內(nèi)容轉(zhuǎn)換成 NSData 二進(jìn)制對(duì)象 , 接著把 NSData 二進(jìn)制對(duì)象作為 json 數(shù)據(jù)轉(zhuǎn)換成相應(yīng)的字典.
- 代碼如下:
NSData *data = [@"{\"aa\":\"bb\"}" dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
17. 將 debug安裝包 安裝到 xcode 模擬器中
- 終端 命令如下:
ios-sim launch /Users/liuzhu/Desktop/PandaTV-ios.app --devicetypeid iPhone-X
- 直接復(fù)制有可能會(huì)出現(xiàn)問題 , 建議直接輸入 , 可參考 http://www.reibang.com/p/cd4c816111db
18. "xx.app"已損壞疮胖,打不開。您應(yīng)該將它移到廢紙簍
當(dāng)出現(xiàn)"xx.app"已損壞闷板,打不開澎灸。您應(yīng)該將它移到廢紙簍提示的時(shí)候,則在“系統(tǒng)偏好設(shè)置”==>“安全性與隱私”==》“通用”==》“允許從以下位置加載的應(yīng)用”遮晚,選擇“任何來源”即可使用
macOs sierra版本系統(tǒng)可能沒有該選項(xiàng)性昭,需要在終端中輸入 sudo spctl --master-disable 命令來打開以上選項(xiàng)。如果想關(guān)閉則再次輸入命令就可以了县遣。
19. Embedded binary's bundle identifier is not prefixed with the parent app's bundle identifier.
- 詳細(xì)信息如下:
error: Embedded binary's bundle identifier is not prefixed with the parent app's bundle identifier.
Embedded Binary Bundle Identifier: $(PRODUCT_BUNDLE_IDENTIFIER)
Parent App Bundle Identifier: com.PandaTV.Live-iPhone
- 檢查一下 bundle id , 和以前一樣 , 沒什么問題.
- 使用一個(gè)神奇的快捷鍵 cmd + option + shift + k 清理一下緩存 ,就消除這個(gè)問題了 , 可能是合并代碼的時(shí)候產(chǎn)生的緩存沖突.
- 遇到類似錯(cuò)誤千萬(wàn)別緊張 , 往往是編譯器的 bug
20 . UILabel 在設(shè)置attributedText 的值時(shí) , numberOfLines屬性不生效
- 設(shè)置 attributedText 的值之后 , 需要同時(shí)設(shè)置 lineBreakMode 屬性 , 才能讓超出的文字顯示...
21. 取消 UITableView 的 cell 被選中的方法
1> 在創(chuàng)建一個(gè)繼承于 UITableViewCell 的類的時(shí)候 , 系統(tǒng)會(huì)自動(dòng)為我們添加以下代碼
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
注釋掉 [super setSelected:selected animated:animated];
這行代碼 , 就不會(huì)有選中的效果了.
2> 在 UITableViewCell 的子類中設(shè)置屬性self.selectionStyle = UITableViewCellSelectionStyleNone;
3> 對(duì)于想被短暫選中的效果 , 可以在 didselect 那個(gè)代理方法中取消選中
22. 繼承 UITableViewCell 時(shí) , 重寫 init 方法沒有被調(diào)用
1> 重寫 init 方法 , 沒有效果 , 插斷點(diǎn)沒有執(zhí)行 ; 繼續(xù)重寫 initWithFrame: 方法 , 斷點(diǎn)沒有執(zhí)行依舊沒有執(zhí)行 ; 在輸入- init 時(shí) , 系統(tǒng)提示initWithStyle:reuseIdentifier:方法 , 斷點(diǎn)卻執(zhí)行了.
2> 對(duì)于使用UITableView的initWithFrame:style:方法創(chuàng)建的 cell , 其 cell 需要使用 initWithStyle:reuseIdentifier: 方法來重載.
23. 觸發(fā)按鈕點(diǎn)擊事件的方法
可以通過給 UIButton控件調(diào)用sendActionsForControlEvents:方法 , 觸發(fā)按鈕點(diǎn)擊事件.
24. 子視圖的動(dòng)畫超出了父視圖
對(duì)于這種情況 , 可以有兩種方法.
1> 可以使用 UIView 控件的 clipToBounds 屬性 , 將其設(shè)置為 YES , 超出當(dāng)前控件的子視圖部分都會(huì)被裁剪.
2> 可以使用 UIView控件的 layer 屬性的 mask 屬性 , 對(duì)其賦值一個(gè) CALayer 屬性(矩形) 或 CAShapeLayer 屬性 (曲線) .
① 通過設(shè)置該 mask 屬性的 frame 或 path 和 backgroundColor , 來讓超出該 frame 或 path 區(qū)域的子控件 , 裁減掉超出部分 , 只顯示當(dāng)前區(qū)域的內(nèi)容.
② CAShapeLayer 是 CALayer 的子類 , 派生了幾個(gè)一些繪制方面的屬性 .
③ CALayer 對(duì)象的 backgroundColor 屬性是一定要設(shè)置的, 否則設(shè)置的 frame 會(huì)變成 CGRectZero.
CALayer *layer = [CALayer new];
// 此處顏色必須設(shè)置,不加就不顯示
layer.backgroundColor = [UIColor redColor].CGColor;
layer.frame = CGRectMake(-13, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
//設(shè)置圖形樣子
_giftAnimationViewContainer.layer.mask = layer;
/// 給已經(jīng)存在的 UIImageView 添加圓角
- (void)recreateImageViewShapeLayer:(CGSize)size radius:(NSInteger)r {
CGRect dstBounds = CGRectMake(0, 0, size.width, size.height);
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:dstBounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(r, r)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
//設(shè)置大小
maskLayer.frame = dstBounds;
//設(shè)置圖形樣子
maskLayer.path = maskPath.CGPath;
self.layer.mask = maskLayer;
}
25. 微信的選中效果
長(zhǎng)按微信的輸入框, 會(huì)選中所有的文字, 并彈出編輯工具條, "復(fù)制 轉(zhuǎn)發(fā) "等, 有兩種思路.
1> UITextView:
- UITextView 控件獲取焦點(diǎn)后, 默認(rèn)是會(huì)彈出輸入框的, 并且變成第一響應(yīng)者(FirstResponder).
- ① 目標(biāo)是不彈出輸入框, 就需要在UITextView的代理方法 textViewShouldBeginEditing: 中返回 NO, 禁止輸入框的彈出, 也同時(shí)移除了光標(biāo), 像一個(gè)可以上下滾動(dòng)的 UILabel.
- ② 目標(biāo)是彈出系統(tǒng)的工具欄. 可是將上述代理方法返回 NO 以后, 就不會(huì)彈出系統(tǒng)的編輯框了. 這時(shí)就需要把其 editable 屬性置為 NO, 就不會(huì)執(zhí)行它的代理方法了, 自動(dòng)彈出了系統(tǒng)工具欄.
26. 隱藏 iPhone X 全屏視頻時(shí)的虛擬按鍵
-
隱藏 : 可以通過重載UIViewController的UIHomeIndicatorAutoHidden分類的
prefersHomeIndicatorAutoHidden
方法, 通過將其返回 YES 來讓系統(tǒng)自動(dòng)隱藏虛擬按鍵, 返回 NO 來禁止隱藏. -
全屏的時(shí)候隱藏 : 在設(shè)置當(dāng)前是否是全屏的狀態(tài) _isfullscreen 以后, 可以讓
prefersHomeIndicatorAutoHidden
方法返回 _isfullscreen 的值, 然后通過調(diào)用setNeedsUpdateOfHomeIndicatorAutoHidden
方法來讓系統(tǒng)觸發(fā)prefersHomeIndicatorAutoHidden
方法, 進(jìn)而確定虛擬按鍵的顯示或隱藏. - 代碼如下 :
/**
適配 IPhoneX
*/
- (void)hideHomeIndicatorForIPhoneX
{
if (@available(iOS 11.0, *))
{
[self setNeedsUpdateOfHomeIndicatorAutoHidden];
}
}
- (BOOL)prefersHomeIndicatorAutoHidden
{
return _isfullscreen;
}
-
在主工程中, 系統(tǒng)方法沒有調(diào)用, 可是 demo 中卻可以調(diào)用 :
1> 查閱資料, 發(fā)現(xiàn)在有 UINavigationController 的控制器中隱藏虛擬按鍵, 需要在繼承它的類中重載childViewControllerForHomeIndicatorAutoHidden
方法, 返回self.topViewController
內(nèi)容, 沒有效果.
2> 以此內(nèi)推, 應(yīng)該把 UINavigationController 的底層控制器 UITabBarController 的childViewControllerForHomeIndicatorAutoHidden
方法也重載掉, 返回selectedViewController
內(nèi)容, 但是依舊沒有效果.
3> 從 main.storyboard 到 UITabBarController, 再到 UINavigationController, 已經(jīng)連通了, 卻依舊沒什么效果.
4> 同事建議從 AppDelegate.m 中查找線索, 因?yàn)?main.storyboard 也是從 AppDelegate.m 加載的, 有可能中間在創(chuàng)建的過程出現(xiàn)了點(diǎn)兒?jiǎn)栴}.
5> 在仔細(xì)查找 AppDelegate.m 的代碼中, 檢測(cè)到 appdelegate 的 window 的 rootViewController屬性是一個(gè)側(cè)邊欄控制器, 而不是 storyboard 中的初始控制器, 而且側(cè)邊欄的控制器中包含了添加storyboard 中的初始控制器的功能. 于是我就在側(cè)邊欄控制器中重載childViewControllerForHomeIndicatorAutoHidden
方法, 返回storyboard 中的初始控制器UITabBarController, 結(jié)果奇跡誕生了, 這條線順利地聯(lián)通了.
27. UpdatePublicKey: database is locked
- locked 一般是服務(wù)器卡死的原因
28. Command /usr/bin/codesign failed with exit code 1
- 用一個(gè)新的機(jī)器進(jìn)行真機(jī)調(diào)試, 結(jié)果在彈出 code sign 密碼驗(yàn)證時(shí), 誤點(diǎn)了 cancel, 接著就出現(xiàn)了一系列問題, 因開發(fā)者證書有誤而無(wú)法編譯.
- 參考這篇博客的方法http://blog.sina.com.cn/s/blog_85c1f6a50100zxz1.html, 打開鑰匙串, 刪除了名稱以 iPhone Develop 開頭的所有證書, 關(guān)閉鑰匙串, 并在 xcode 中使用 command + ,打開設(shè)置面板, 移除我的賬號(hào)并重新添加, 又提示了新的錯(cuò)誤 : "Your account already has a signing certificate for this machine but it is not present in your keychain. To create a new one, you must first revoke the existing certificate."
- 我刪了好幾次, 卻依然出現(xiàn)同樣的錯(cuò)誤, 碰巧看到大神的回答https://stackoverflow.com/questions/46881907/cant-run-xcode-project-on-device-due-to-certificate-issues,在這種情況下------點(diǎn)擊 Preferences -> Accounts -> Manage Certificates 依舊是證書 "Missing Private Key" ,可以通過重啟電腦的方式, 重新讓 xcode 調(diào)用 code sign 工具, 獲取 Mac 登錄密碼及權(quán)限, 結(jié)果就可以正常運(yùn)行了.
29. pod 導(dǎo)入的文件, file not find
- 切到一個(gè)分支時(shí), 在 #import 頭文件的地方, 提示文件查找失敗, 在 project navigator 中, 卻能找到這個(gè)文件, 而且是在 pod 中的.
- 重新更新了一下 pod, 并使用 command + shift + K 完全清理一下緩存, 還是出現(xiàn)這個(gè)問題.
- 重啟一下 xcode, 再使用 command + shift + K 完全清理一下緩存, 結(jié)果就可以正常運(yùn)行了, 看來是 xcode 的問題.
- 正確的 Podfile 文件如下:
use_frameworks!
platform :ios, ‘8.0‘
target "RACCommand" do
pod ‘ReactiveCocoa‘, ‘2.1.8‘
end
30.當(dāng)前時(shí)區(qū)的時(shí)間
[NSDate dateWithTimeIntervalSince1970:[ [NSDate date] timeIntervalSince1970]]
31. The file “CycleProgressBar” couldn’t be opened because you don’t have permission to view it.
重啟一下 xcode 或者 電腦 即可解決此問題.
33. 比較字符串的大小, 可以用字符串的 compare 方法.
// 比較兩個(gè)字符串,結(jié)果為result1:0,result2:1,result3:-1
-(void)ComparerTwoString
{
NSString *str1 = @"This is String1";
NSString *str2 = @"THIS is String2";
// 比較兩個(gè)字符串是否相等
BOOL result1 = [str1 isEqualToString:str2];
// 比較兩個(gè)字符串(comparer方法返回三種值:NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending)
NSComparisonResult result2 = [str1 compare:str2];
// 不考慮大小比較字符串
NSComparisonResult result3 = [str1 caseInsensitiveCompare:str2];
NSLog(@"result1:%d,result2:%ld,result3:%ld",result1,(long)result2,(long)result3);
}
34. UIScrollView無(wú)法滑動(dòng)
- 第一感覺像是某些按鈕遮住了 UIScrollView, 但不是它的子視圖...通過層次結(jié)構(gòu)圖, 發(fā)現(xiàn)這種猜想是錯(cuò)誤的.
- 想起了在 UIScrollView 中添加子視圖, 使用自動(dòng)布局時(shí), 要設(shè)置6個(gè)約束, 然后就設(shè)置了它的兩個(gè)直接子視圖六個(gè)約束, 依然不能滑動(dòng)...檢查 UIScrollView父視圖設(shè)置它約束的地方, 是4個(gè)約束, 沒有問題.
- 然后進(jìn)入 UIScrollView 頭文件, 發(fā)現(xiàn)了 contentsize, 默認(rèn)值是CGSizeZero, 于是設(shè)置成和屏幕一致大小CGSizeMake(SCREEN_WIDTH, SCREEN_HEIGHT), 無(wú)果.
- 看其他地方的寫法, 發(fā)現(xiàn)是 contentsize 的高度設(shè)置的太小了, 改大一點(diǎn)兒后, 依然不能滑動(dòng).
- 換個(gè)方式, 把當(dāng)前視圖從工程中抽出來, 單獨(dú)運(yùn)行在一個(gè)空項(xiàng)目中, 結(jié)果依舊無(wú)法滑動(dòng), 我在父視圖中, 把 UIScrollView 的高度改得特別小, 結(jié)果竟然可以滑動(dòng)了... 這就是 demo 的好處, 可以天馬星空得開拓自己的思維, 讓我離成功又近了一半距離...
- 我開始懷疑主工程的 contentsize 在其他地方被設(shè)置了, 于是我在任意一個(gè)按鈕事件中插入斷點(diǎn), 打印當(dāng)前UIScrollView, 結(jié)果 contentsize 的高度居然和 UIScrollView 的高度一樣, 這就證明了我的猜想是正確的.
- 我在調(diào)用 UIScrollView 的地方, 也就是懶加載的返回處始終加載設(shè)置 contentsize 那句話, 結(jié)果奇跡出現(xiàn)了, 順利地滑動(dòng)了.
- 但問題又來了, 為什么滑到最下面, 底部視圖的顏色明顯變小? 很容易猜想到是第二個(gè)子視圖在設(shè)置靠近 self.view底部的高度時(shí), 設(shè)置小了, 如下:
CGFloat headerHeight = fitIPHONE6Width(371);
CGFloat offset = fitIPHONE6Width(5);
CGFloat bottomHeight = SCREEN_HEIGHT - fitIPHONE6Width(371) - [PTVCarTeamThemeHeaderView viewHeight] - offset;
問題就出在了, 設(shè)置成了屏幕內(nèi)的高度, 而不是需要滑動(dòng)的高度.把bottomHeight 改成fitIPHONE6Width(370)就完美了, 顯然比 iPhone 6的屏幕高度667大, 可以正趁拥撸看到滑動(dòng)以外的區(qū)域.
- 小問題又出來了, UIScrollView 的 contentoffset 由自動(dòng)變成了(0,-20), 我又在每次調(diào)用 UIScrollView 的地方, 設(shè)置了 contentoffset 為(0,0), 結(jié)果一切正常了....看到20, 想起了狀態(tài)欄的高度, 發(fā)現(xiàn)自己的導(dǎo)航欄是隱藏的, 想起了自己曾經(jīng)的一篇博客, UIViewController 的 automaticallyAdjustsScrollViewInsets 屬性默認(rèn)是 yes, 也就是在導(dǎo)航欄隱藏的時(shí)候, 自動(dòng)設(shè)置 scrollview 的 contentinset, 設(shè)置成 NO 就解決了此問題.
- 總結(jié): 一定要化繁為簡(jiǎn)(demo), 一定要多使用斷點(diǎn) 來解決問題.
35. 最簡(jiǎn)單快速的動(dòng)畫代碼
// CGAffineTransformMakeTranslation的參數(shù)位置是相對(duì)于坐標(biāo)原點(diǎn)(0,0)的偏移, 即屏幕左上角.
- (void)showActionsViewWithAnimation{
self.actionsView.hidden = NO;
self.actionsView.transform = CGAffineTransformMakeTranslation(SCREEN_WIDTH, 0);
[UIView animateWithDuration:0.5 animations:^{
self.actionsView.transform = CGAffineTransformIdentity;
}];
}
- (void)hideCurrentViewWithAnimation:(void (^)())completion{
self.transform = CGAffineTransformIdentity;
[UIView animateWithDuration:0.5 animations:^{
self.transform = CGAffineTransformMakeTranslation(SCREEN_WIDTH, 0);
} completion:^(BOOL finished) {
self.hidden = YES;
if (completion) {
completion();
}
}];
}
- (void)showWithAnimation{
self.transform = CGAffineTransformMakeScale(0, 0);
[UIView animateWithDuration:0.25 animations:^{
self.transform = CGAffineTransformIdentity;
}];
}
// CGAffineTransformMakeScale的參數(shù)位置是原尺寸的倍數(shù), 設(shè)置成0, 0 會(huì)看不到動(dòng)畫, 因此同時(shí)添加了透明度的動(dòng)畫.
- (void)hideWithAnimation:(void (^)())completion{
self.transform = CGAffineTransformIdentity;
self.alpha = 0.5;
[UIView animateWithDuration:0.25 animations:^{
self.alpha = 0;
self.transform = CGAffineTransformMakeScale(0.1, 0.1);
} completion:^(BOOL finished) {
if (completion) {
completion();
}
}];
}
36. 最簡(jiǎn)單的讓 UICollectionView 或 UITableView 無(wú)限滑動(dòng)
- 思路: 很簡(jiǎn)單, 就是讓 UICollectionView 或 UITableView 的 cell 數(shù)目翻倍, 滑到最左邊或最右邊時(shí), 默默地在后臺(tái)切到正中間.
-
方法: 通過 contentoffset 來判斷是否滑到了最左邊
contentoffset <= 0
, 是否滑到了最右邊contentoffset >= contentsize - unitsize
- 調(diào)用: 在scrollViewDidScroll:方法和layoutSubviews:方法中調(diào)用, layoutSubviews:方法適用于 scrollview 中添加 uiview, uiview 又添加了 scrollview 的情況, 第一個(gè)默認(rèn)居中.
- 代碼如下
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
[self updatePager];
UICollectionView *collectionView = (UICollectionView *)scrollView;
if (self.offsetLength <= 0)
{
[collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:self.arrayData.count inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
}else{
if (self.offsetLength >= self.contentLength - self.unitLength) {
[collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:self.arrayData.count - 1 inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
}
}
}
- (void)layoutSubviews{
[super layoutSubviews];
[self scrollViewDidScroll:self.actionListView];
}
- (void)updatePager
{
UICollectionView *collectionView = (UICollectionView *)self.actionListView;
self.pageControl.currentPage = (NSInteger)(floorf(collectionView.contentOffset.x / collectionView.frame.size.width))% self.arrayData.count;
}
37. 視圖不顯示的幾種情況
- 背景顏色為白色或無(wú)色.
- 大小設(shè)置為0.
- 視圖被設(shè)置為 hidden, 此時(shí)層次結(jié)構(gòu)圖是看不到的.
38. 崩潰MASViewConstraint install
- 這種問題往往是由于父視圖為 nil 引起的.
- 定位到第328行的函數(shù)內(nèi)部, 會(huì)看到斷言"couldn't find a common superview".
- 在使用 masonry 布局的時(shí)候, 最好先確定父視圖是否存在, 如果不存在的話, 就不要?jiǎng)?chuàng)建視圖.
39. 讓 UIScrollView 中的視圖不跟著滑動(dòng)
- 在 UIScrollView 中添加位置不變的視圖, 可以更改子視圖的布局.
- 例如不讓子視圖向下滑動(dòng), 就讓子視圖的頂部相對(duì)于 UIScrollView 的父視圖添加約束, 代碼如下
UIView *keyWindow = [UIApplication sharedApplication].keyWindow;
[self.accountView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(keyWindow);
make.left.mas_equalTo(self.tableView);
make.size.mas_equalTo(CGSizeMake(self.tableView.frame.size.width, acountHei));
}];
- 對(duì)于讓 UIScrollView 禁止拖拽但可以自動(dòng)滑動(dòng), 類似跑馬燈的效果, 可以在 UIScrollView 的兄弟視圖上添加一個(gè)UIView, 遮蓋在它上面, 阻攔它的事件.
40. 程序設(shè)計(jì)常見問題
- 倒計(jì)時(shí) 結(jié)束后 按鈕 置灰顯示 , 注意 置灰后 再次抽到 新開啟的PK 按鈕要回復(fù)可點(diǎn)擊狀態(tài) .
- ① 連續(xù)點(diǎn)擊送禮物按鈕, 會(huì)影響倒計(jì)時(shí)的勻速變化, 很有可能是送禮的請(qǐng)求收到以后, 進(jìn)行了一些耗時(shí)操作.
② 第一感覺是, 送完禮物就是簡(jiǎn)單的請(qǐng)求禮物列表的操作嘛, 可是實(shí)際卻是, 請(qǐng)求完禮物, 會(huì)刪除舊的禮物列表, 重新建一個(gè)新的禮物列表.
41. 使用 hittest 時(shí), 需要考慮隱藏的視圖.
- 在循環(huán)創(chuàng)建視圖時(shí), 導(dǎo)致每個(gè)視圖中都調(diào)用了 hittest方法, 需求是這些視圖的位置都一樣, 顯示其中一個(gè), 隱藏其余的所有視圖.
- 點(diǎn)擊某個(gè)已經(jīng)顯示視圖的 hittest 時(shí), 有可能響應(yīng)已經(jīng)隱藏的視圖的 hittest, 進(jìn)而導(dǎo)致間歇性地觸發(fā)隱藏視圖的事件.... 因此要在 hittest 中判斷當(dāng)前視圖是否隱藏.
- 點(diǎn)擊視圖時(shí), 不會(huì)響應(yīng)當(dāng)前視圖, 也沒有觸發(fā)當(dāng)前視圖的 hittest 方法, 而是①響應(yīng)了下面的兄弟視圖....②意外發(fā)現(xiàn), 點(diǎn)擊當(dāng)前視圖的關(guān)閉按鈕竟可以響應(yīng), 也沒有觸發(fā)當(dāng)前視圖的 hittest 方法, 在其他地方肯定有設(shè)置…. ③全局查找這個(gè)視圖中的相應(yīng)按鈕, 才發(fā)現(xiàn)在第1部被響應(yīng)的視圖的 hittest方法, 有返回當(dāng)前視圖的關(guān)閉按鈕的返回值....④解決方案: 在當(dāng)前視圖不隱藏時(shí), 如果點(diǎn)擊區(qū)域也在當(dāng)前視圖中, 就在第1部被響應(yīng)的視圖的 hittest方法中, 返回當(dāng)前視圖.
42. iOS控制代碼段大小在60M 以內(nèi)
參考文章 http://www.iqiyi.com/common/20171130/d9534cf00c408f06.html.
44. UITableView 的底部有多余的下劃線
- 查看層次結(jié)構(gòu)圖, 發(fā)現(xiàn)系統(tǒng)創(chuàng)建了很多分割線視圖.
- 可以給 UITableView 的 tableFooterView 屬性設(shè)置為一個(gè)帶有背景顏色的視圖, 寬高只要大于0就行.
45. 使用 SourceTree push 代碼時(shí)彈出 password required
- 使用如下設(shè)置 "倉(cāng)庫(kù) --> 倉(cāng)庫(kù)設(shè)置 --> 遠(yuǎn)程倉(cāng)庫(kù) -->雙擊路徑下方表格的第一項(xiàng) --> 修改 url 路徑"
- 以上 url 路徑如下
https://用戶名:密碼@hostname.com/projectname.git
如:http://liuzhu:mima@clientgit3.***.com:3000/iOS/***.git
- "托管類型"后選擇"GitHub", 用戶名:"liuzhu"
- 點(diǎn)擊確定即可.
46. git 代碼提交錯(cuò)誤, 需要回退到某個(gè)提交
- $ git reflog 查看當(dāng)前的操作
1e9668c7ad (HEAD -> HeroNewSkill_new) HEAD@{0}: commit (merge): Merge branch 'CarteamOptimize' into HeroNewSkill_new
73be8bf1ec (origin/HeroNewSkill_new) HEAD@{1}: pull origin HeroNewSkill_new: Fast-forward
- $ git checkout -b hero_test 73be8bf1ec 在對(duì)的操作對(duì)應(yīng)的 id 處, 切到新的分支hero_test.
47.比較容易忽略的循環(huán)引用
以下代碼中, tableview 強(qiáng)引用 cell, cell 又會(huì)在 block 中強(qiáng)引用 tablview, 造成循環(huán)引用, 無(wú)法釋放內(nèi)存, 需要使用 weak 用一個(gè)局部變量解開強(qiáng)引用的環(huán).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = @"PTVShortVideoListCell";
PTVShortVideoItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
__weak UITableView *tableViewWeak = tableView;
cell.changeEnableScroll = ^(BOOL enable) {
tableViewWeak.scrollEnabled = enable;
};
}
48. 從系統(tǒng)瀏覽器通過 schema 打開 app , APP崩潰
- 檢查 schema, 是讓 app 打開系統(tǒng)瀏覽器的
- 使用排除法, 在 app 中打開該 schema, 不會(huì)崩潰, 而且很快就打開了系統(tǒng)瀏覽器.
- 在 app 已經(jīng)打開的時(shí)候, 從系統(tǒng)瀏覽器通過 schema 打開 app, APP 卻沒有崩潰.
- 于是我就加了一個(gè)判斷, 如果是從瀏覽器 openurl 打開的 app, 就延遲兩秒響應(yīng)打開系統(tǒng)瀏覽器操作, 結(jié)果屬實(shí)沒有崩潰, 推斷是啟動(dòng)時(shí)CPU 高負(fù)載造成的崩潰.
- 在一個(gè)簡(jiǎn)單 demo 程序里的didFinishLaunchingWithOptions:方法中使用 openurl 方法, 結(jié)果卡頓了幾秒后才繪制首頁(yè) UI, 響應(yīng) schema.
49. 提交代碼到錯(cuò)誤的分支上, 可以使用 git cherry-pick xx命令補(bǔ)救
- 代碼提錯(cuò)分支, 不要慌, 可以在錯(cuò)誤的分支輸入
git log
查看提交內(nèi)容上方相應(yīng)的 MD5值, 如 "bfa449aa32cd224f1bffcc5fa410c454d4ffd6ab". - 切到目標(biāo)分支, 執(zhí)行命令
git cherry-pick bfa449aa32cd224f1bffcc5fa410c454d4ffd6ab
在當(dāng)前分支添加以上 MD5值對(duì)應(yīng)的提交.
總結(jié): cherry-pick 只能檢出單個(gè)提交, 并無(wú)視錯(cuò)誤分支之前或之后的提交, 這點(diǎn)對(duì)提錯(cuò)代碼且同事有提交的情況, 非常有幫助.
50. 一個(gè)視圖, 在橫屏和豎屏都需要展示, 可以在切換屏幕時(shí)切換父視圖.
原理: removefromsuperview 只是移除了父視圖, 對(duì)于被父視圖強(qiáng)引用的子視圖來說, 不會(huì)立即釋放., 可以被 addsubview 到新的視圖上面, 而數(shù)據(jù)不變.
51. 有 UIScrollView 的視圖, 無(wú)法左滑退出
一行代碼搞定, 手勢(shì)有沖突的時(shí)候, UIScrollview 理所當(dāng)然地把手勢(shì)傳給導(dǎo)航控制器的手勢(shì).
[self.mainScrollView.panGestureRecognizer requireGestureRecognizerToFail:self.navigationController.interactivePopGestureRecognizer];
52. 運(yùn)行 Xcode 提示: You don't have permission to access
使用快捷鍵 cmd+option+shift+k, 清理緩存文件之后, 就沒問題了.
53. MJRefresh上拉刷新到最底部后, 下拉刷新只能刷新一頁(yè)
在使用分類屬性 mj_footer 的 endRefreshingWithNoMoreData方法時(shí), 一定要在下拉刷新成功時(shí), 用 mj_footer 的 resetNoMoreData 方法將無(wú)數(shù)據(jù)狀態(tài)重置, .
55. 響應(yīng)推送通知的系統(tǒng)方法, 有兩個(gè)
application:didReceiveRemoteNotification:fetchCompletionHandler:
userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler
60. git stash 暫存當(dāng)前的測(cè)試代碼到緩存棧.
切換分支或更新代碼時(shí), 可以臨時(shí)保存目前的提交到棧區(qū).
git stash
“‘儲(chǔ)藏”“可以獲取你工作目錄的中間狀態(tài)——也就是你修改過的被追蹤的文件和暫存的變更——并將它保存到一個(gè)未完結(jié)變更的堆棧中,隨時(shí)可以重新應(yīng)用git stash apply stash@{2}
, 并通過git stash list
查看列表萧求。
在 sourcetree 中可以點(diǎn)擊 "暫存" 來實(shí)現(xiàn), 并通過 stash 列表查看, 右擊對(duì)應(yīng)的項(xiàng)目來應(yīng)用或刪除貯藏.
61. 誤刪git遠(yuǎn)程分支
- 每次打開 sourcetree, 都會(huì)提示我有新的提交. 于是我決定刪掉遠(yuǎn)程分支, 把本地分支推到服務(wù)器端.
- 在刪除了遠(yuǎn)程服務(wù)器分支以后, 突然發(fā)現(xiàn)本地的對(duì)應(yīng)分支也沒了~~~(>_<)~~~
- 想起
git reflog
可以查看最近的操作記錄如下
ecdd7f7b69 (origin) HEAD@{8}: pull --rebase origin userHomePage: 更新共同關(guān)注的
人的列表
- 在其父分支, 使用
git reset --hard HEAD@{8}
命令, 便可以把剛剛分支提交的所有內(nèi)容都合并到當(dāng)前分支上.
(PS: git reset會(huì)忽略當(dāng)前提交后的所有提交, 不會(huì)有 commit; git revert 會(huì)在最新的提交后添加一個(gè)混滾的 commit) - 然后從當(dāng)前分支拉一個(gè)新分支, 即可恢復(fù).