聲明:文章內(nèi)容中所有涉及的東西桶现,有一些是在網(wǎng)上查找的,有一些是個人在開發(fā)中摸索出來的喊巍,如果部分內(nèi)容涉及到了侵權問題屠缭,請及時聯(lián)系我,我會將其注明引用或刪除崭参。
1呵曹、Why doesn't UIScrollView/UITableview respond to taps on the status bar, and scroll to the top?
StackOverflow
This can occur when there are multiple instances of UIScrollView (or a subclass of UIScrollView, such as UITableView) with the scrollsToTop property set to YES on the same view, such as when a UIScrollView is added as a subview to a UIScrollView. Make sure that the scrollsToTop property of only one scroll view is set to YES. The correct UIScrollView should respond to tap events on the status bar after.
當你把一個 UIScrollView 或者 它的子類的對象(UITableView,UITextView, UICollectionView),作為子視圖添加到一個 UIScrollView 中時何暮,必須將其 scrollsToTop 設置為 NO奄喂,只保留父視圖 scrollView 的 scrollsToTop屬性為 YES,這樣才能在點擊 statusBar 時海洼,scrollView 能夠響應跨新。
2、獲取圖片類型
If you have NSData for the image file, then you can guess at the content type by looking at the first byte:
OC版本:
+ (NSString *)contentTypeForImageData:(NSData *)data {
uint8_t c;
[data getBytes:&c length:1];
switch (c) {
case 0xFF:
return @"image/jpeg";
case 0x89:
return @"image/png";
case 0x47:
return @"image/gif";
case 0x49:
case 0x4D:
return @"image/tiff";
}
return nil;
}
Swift版本:
/**
根據(jù) imageData 獲取圖片的格式
*/
fileprivate func imageType(_ imageData: Data) -> String {
var c: UInt8 = 0x00
(imageData as NSData).getBytes(&c, length: 1)
switch c {
case 0xFF:
return "image/jpeg"
case 0x89:
return "image/png"
case 0x47:
return "image/gif"
case 0x49,0x4D:
return "image/tiff"
default: return ""
}
}
3坏逢、給 TableView 添加系統(tǒng)自帶的 UIRefreshControl
let tableView = UITableView(frame:UIScreen.mainScreen().bounds)
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(refresh),forControlEvents: .ValueChanged)
tableView.addSubview(refreshControl)
view.addSubview(tableView)
**iOS 10 ** 中域帐,UIScrollView 自帶一個 refreshControl 屬性赘被,可直接使用
4、Xcode中使用 #ifdef
(1) 首先在 Xcode 中配置宏
(2) 在代碼中使用
// 如上圖肖揣,創(chuàng)建了三個 target帘腹,就可以分別在各自的 target 里面,定義一個宏许饿,用來標識自已阳欲,
// 在代碼中使用的時候,能過判斷宏來取對應的數(shù)據(jù)或賦值
// 比如上面三個 target 的名字分別為 Test_Prod, Test_UAT, Test_Dev
// 其實是一個項目陋率,創(chuàng)建了多個 target球化,分別對應了 生產(chǎn)、測試和開發(fā)三個環(huán)境
// 在各自的 target 里面定義 TEST_PROD, TEST_UAT, TEST_DEV
#ifdef TEST_PROD
plistPath = [[NSBundle mainBundle] pathForResource:@"One_Config" ofType:@"plist"];
#elif defined TEST_UAT
plistPath = [[NSBundle mainBundle] pathForResource:@"Two_Config" ofType:@"plist"];
#elif defined TEST_DEV
plistPath = [[NSBundle mainBundle] pathForResource:@"Three_Config" ofType:@"plist"];
#else
plistPath = [[NSBundle mainBundle] pathForResource:@"Four_Config" ofType:@"plist"];
#endif
如何創(chuàng)建多個 target 瓦糟,在 第11條 可以找到
5筒愚、CALayer 中 position 和 anchorPoint 的關系
func test() {
// position 坐標是 anchorPoint 在父 layer 上的位置
// anchorPoint (0,0) 代表左上角,(1,1) 代表右下角菩浙,默認是 (0.5,0.5) (iOS 和 Mac OS 系統(tǒng)中原點位置是不一樣的巢掺,下面有解釋)
// position 默認是 (layer.width * 0.5,layer.height * 0.5)
let redView = UIView(frame: CGRect(x: 50, y: 50, width: 200, height: 200))
redView.backgroundColor = UIColor.red
let yellowLayer = CALayer()
yellowLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
yellowLayer.backgroundColor = UIColor.yellow.cgColor
print("before position = \(yellowLayer.position)")
print("before anchorPoint = \(yellowLayer.anchorPoint)")
redView.layer.addSublayer(yellowLayer)
// anchorPoint 不變,position 變
yellowLayer.position = CGPoint(x: 0, y: 0)
// anchorPoint 變劲蜻,position 不變
//yellowLayer.anchorPoint = CGPoint(x: 0, y: 0)
yellowLayer.anchorPoint = CGPoint(x: 0, y: 0)
print("after position = \(yellowLayer.position)")
print("after anchorPoint = \(yellowLayer.anchorPoint)")
view.addSubview(redView);
}
在 iOS 系統(tǒng)中陆淀,Layer 的 anchorPoint 所在的坐標系的原點為左上角,在 OS 系統(tǒng)中先嬉,原點是左下角轧苫,可在 CoreAnimationGuide 中查看
Unit Coordinate Systems.png
Snip20180604_2.png
6、隱藏導航欄返回按鈕上的文字疫蔓,只保留箭頭含懊;自定義返回箭頭圖片
方法一:(親測有效)
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-60,-60) forBarMetrics:UIBarMetricsDefault];
方法二:
Try
self.navigationItem.backBarButtonItem.hidden = YES;
or
self.navigationItem.backBarButtonItem = nil;
or
self.navigationItem.hidesBackButton = YES;
Place one of these either in viewWillAppear:, viewWillLoad or viewDidAppear: of the class you want to get rid of the back button in.
設置返回箭頭圖片
// 設置返回 icon
UIImage *backButtonIcon = [UIImage imageNamed:@"BackItem"];
self.navigationController.navigationBar.backIndicatorImage = backButtonIcon;
self.navigationController.navigationBar.backIndicatorTransitionMaskImage = backButtonIcon;
7、URL編碼內(nèi)容衅胀、還原內(nèi)容
在進行網(wǎng)絡請求時岔乔,如果 URL 里面有中文,就需要進行編碼滚躯,然后再去使用
編碼時注意選擇對應的 NSCharacterSet 雏门,否則編碼出來的東西可能會出現(xiàn)不一致的情況
// 使用這個編碼時注意要用 URLQueryAllowedCharacterSet ,否則出來的內(nèi)容哀九,與接收到的有一些不一致
NSString *encodedContents2 = [contents stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSLog(@"encodedContents2 = %@",encodedContents2);
// 使用這個方法剿配,編碼出來的內(nèi)容和接收到的一致,但是這個 API 已經(jīng)被 deprecated
NSString *encodedContents3 = [contents stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"encodedContents3 = %@",encodedContents3);
如果接收到的 URL 里面是編碼過的內(nèi)容阅束,可以通過 string 的屬性直接獲取原始內(nèi)容
NSString *contents = originalContents.stringByRemovingPercentEncoding;
8呼胚、UITableView 在 Group style 下設置 header/footer 高度
(1)如果要去掉第一個cell 上面的空白的話,需要給 tableView 設置一個 tableHeaderView息裸,把這個 view 的高度調(diào)成一個非常小的數(shù)
self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, SCREEN_WIDTH, 10.0f)];
(2)設置 header/footer 的高度
有兩種方法:
方法一:直接設置 tableView 的屬性
self.tableView.sectionFooterHeight = 10;
self.tableView.sectionHeaderHeight = 0;
方法二:在代理里面設置
這個時候需要注意蝇更,如果要設置 0 的話沪编,直接 return 0 是沒有效果的,也是需要返回一個很小的數(shù)年扩,這種方法也可以去除第一個 cell 上面的空白
注意: 如果只要 header 的高度的話蚁廓,一定要把 footer 設置成 0.000001 ,以免誤以為設置的 header 的高度沒起作用
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 10.0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 0.01;
}
9厨幻、自定義了 leftBarButtonItem 之后相嵌,邊緣手勢失效
self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;
10、如何讓邊緣手勢失效
在iOS7以后况脆,如果是用NavgationController推出來的界面饭宾,這個界面都有邊緣手勢側滑效果,想讓界面不響應這個邊緣手勢只需要一行代碼:(一但調(diào)用格了,所有地方都會失效)
//關閉邊緣手勢,這個值默認是YES
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
11看铆、在一個項目里面創(chuàng)建多個 Target
(1) 在原來的 Target 上面右鍵,Duplicate
(2) Xcode 會創(chuàng)建一個新的 Target 以及與它相對應的 xxx-info.plist 文件
(3)修改新的 Target 的名字和它對應 info.plist 文件的名字
(4)在新的 Target 的 BuildSetting 中配置對應的 info.plist文件路徑盛末,可以寫完整路徑:$(SRCROOT)/TargetTest-Two-Info.plist
$(SRCROOT): 定位到工程所在的目錄弹惦,與 TargetTest.xcodeproj 同一等級的目錄下
12、關于導航欄半透明的設置
extendedLayoutIncludesOpaqueBars:這個屬性表示悄但,是否將 controller 的 rootView(即 self.view) 擴展到不透明的 bar 下面棠隐,默認為 NO;
navigationBar 默認是半透明的(translucent = YES)算墨,
self.edgesForExtendedLayout 默認是 UIRectEdgeAll
所以默認情況下宵荒,controller
的 rootView
會被擴展到半透明的 navigationBar
下面,即 self.view
的大小和屏幕大小一樣;
當我們將 navigationBar.translucent
設置為 NO 時(不透明)净嘀,由于 extendedLayoutIncludesOpaqueBars
默認為 NO,不擴展到不透明的 bar 下面侠讯,所以這個時候挖藏,controller 的 rootView 頂部是從 navigationBar 的底部開始的;
如果將 extendedLayoutIncludesOpaqueBars
設置為 YES厢漩,那么 rootView
還是會被擴展膜眠,大小與屏幕大小一樣