目錄
39. 定制 cell 的 Edit View
40. IOS 9 中添加 http 懇求白名單
41.當收到推送告訴時, didReceiveRemoteNotification 辦法不調用
42.接納到推送告訴時,如何更新 Badge 數?
43.為什麼收到推送告訴時,不會播放聲響?
44.如何在音訊載體中指定自定義的聲響?
45.如何讀取零碎聲響?
46. 如何將中文轉換為拼音?
47. UITextView 在 IOS 7 上文字不能頂部對齊。
48.在數組中刪除對象時出錯:“Collection was mutated while being enumerated”
49. 當我修正 cell 背風光時,AccessoryView 的背風光依然是原來的。如何讓 AccessoryView 的背風光也做異樣改動?
50. 如何運用 UISearchController
51.如何修正 SearchBar 的背風光?
52.當TableView 滾動後,直到 searBar 不可見,如何再次讓 searchBar 可見?
53. 如何以動畫方式改動UISearchBar 的 barTintColor?
54. 如何去掉 UISearchBar 下方的細線?
55. 如何傳遞參數給一個 Container View Controller?
39. 定制 cell 的 Edit View 完成數據源辦法 canEditRowAtIndexPath ,並依據 IndexPath 前往一個 Bool 值——YES 表示支持滑動操作,NO 表示不支持。 完成數據源辦法 commitEditingStyle 。空完成,不需求編寫任何代碼。 完成委托辦法 editActionsForRowAtIndexPath:-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *editAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"Clona" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
//insert your editAction here
}];
editAction.backgroundColor = [UIColor blueColor];
UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
//insert your deleteAction here
}];
deleteAction.backgroundColor = [UIColor redColor];
return @[deleteAction,editAction];
}
前往目錄
40. IOS 9 中添加 http 懇求白名單iOS 9 下,默許不再支持 http 類型的網絡懇求(強迫要求 https),假如在代碼中收回 http 懇求,iOS 會報如下錯誤:
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app’s Info.plist file.
我們需求讓 iOS 9 支持 http 協議懇求,或許將要訪問的 http 網址添加到 “白名單” 中。
辦法一. 在項目的info.plist中添加一個Key:NSAppTransportSecurity,類型為字典類型。
然後給它添加一個Key:NSAllowsArbitraryLoads,類型為Boolean類型,值為YES;
辦法二.
1)、在項目的info.plist中添加一個Key:NSAppTransportSecurity,類型為字典類型。
2)、然後給它添加一個NSExceptionDomains,類型為字典類型;
3)、把需求的支持的域添加給NSExceptionDomains。其中域作為Key,類型為字典類型。
4)、每個域上面需求設置3個屬性:NSIncludesSubdomains、NSExceptionRequiresForwardSecrecy、NSExceptionAllowsInsecureHTTPLoads。
均為Boolean類型,值辨別為YES、NO、YES。
前往目錄
41.當收到推送告訴時, didReceiveRemoteNotification 辦法不調用在完成推送告訴時,完成了 didReceiveRemoteNotification 和 didReceiveRemoteNotification:fetchCompletionHandler 辦法,但這些辦法只會在 App 從後台被喚醒時觸發。也就說當 Push 告訴抵達,用戶從告訴中心點擊音訊,零碎喚醒 App 後才會觸發這些辦法。
假如想在 App 處於後台時就調用這些辦法,需求運用“靜默的推送告訴”:
翻開後台運轉選項中的 Remote notifications:
在告訴載體中添加 content-available 鍵:
{
aps = {
"content-available" : 1,
sound : ""
};
}
前往目錄
42.接納到推送告訴時,如何更新 Badge 數?普通狀況下,告訴未讀數由服務端維護。當服務器發送一個近程告訴到某台設備時,同時會在載體中附加 badge 數。當設備收到告訴後,App 假如處於後台或加入形態,OS 會自動更新 App 圖標上的 badge 數。一旦 App 再次處於運轉形態,就可以經過 application:didReceiveRemoteNotification: 辦法獲取讀取近程告訴,並從 userInfo 參數中取得 bdge 數。這時你可以更新 badge 數。
if (userInfo) {
NSLog(@"%@",userInfo);
if ([userInfo objectForKey:@"aps"]) {
if([[userInfo objectForKey:@"aps"] objectForKey:@"badgecount"]) {
[UIApplication sharedApplication].applicationIconBadgeNumber = [[[userInfo objectForKey:@"aps"] objectForKey: @"badgecount"] intValue];
}
}
}
留意,在音訊載體中 badge 字段要用數字而不是字符串。例如:
{“aps”:{“alert”:”Hello from APNs Tester.”,”badge”:1}}
前往目錄
43.為什麼收到推送告訴時,不會播放聲響?要在音訊載體中指定 sound 字段。例如:
{"aps":{"alert":"Hello from APNs Tester.","badge":1,sound:"default"}}
“sound”:”default”,播放零碎默許的聲響。
前往目錄
{"aps":{"alert":"Hello from APNs Tester.","badge":1,"sound":"alarm"}}
其中 alarm 是聲響文件的文件名(不需求擴展名)。聲響文件必需位於 bundle 或許 Library/Sounds 目錄,文件類型必需是 aiff, wav, 或 caf。假如指定的文件不存在,零碎用默許聲響(default)替代。
前往目錄
零碎聲響放在了 /System/Library/Audio/UISounds 目錄,你可以將零碎聲響拷貝到 App 的 Library/Sounds 目錄:
NSArray* loadAudioList(){
NSMutableArray *audioFileList = [[NSMutableArray alloc] init];
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSURL *directoryURL = [NSURL URLWithString:@"/System/Library/Audio/UISounds"];
NSArray *keys = [NSArray arrayWithObject:NSURLIsDirectoryKey];
NSDirectoryEnumerator *enumerator = [fileManager
enumeratorAtURL:directoryURL
includingPropertiesForKeys:keys
options:0
errorHandler:^(NSURL *url, NSError *error) {
// Handle the error.
// Return YES if the enumeration should continue after the error.
return YES;
}];
for (NSURL *url in enumerator) {
NSError *error;
NSNumber *isDirectory = nil;
if (! [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error]) {
// handle error
}
else if (! [isDirectory boolValue]) {
[audioFileList addObject:url];
if (![fileManager fileExistsAtPath:LIBRARY_SOUNDS_DIR]) {
[fileManager createDirectoryAtPath:LIBRARY_SOUNDS_DIR
withIntermediateDirectories:NO
attributes:nil error:nil];
}
NSString* toDir = [LIBRARY_SOUNDS_DIR stringByAppendingPathComponent:url.lastPathComponent];
NSURL* toUrl=[NSURL fileURLWithPath:toDir];
if (![fileManager fileExistsAtPath:toDir]) {
[fileManager copyItemAtURL:url toURL:toUrl error:&error];
if (error!=nil) {
NSLog(@"復制文件錯誤:%@",error.localizedDescription);
}
}
}
}
return audioFileList;
}
這樣你就可以在推送告訴載體中運用零碎聲響了:
{"aps":{"alert":"Hello from APNs Tester.","badge":"1","sound":"sms-received3.caf"}}
留意 :實測中發現(版本 iOS 8.1.3),把聲響文件放在 Library/Sounds 目錄是有效的(完好途徑是:/var/mobile/Containers/Data/Application/65B983BC-2400-4759-9EE2-247B234597F0/Library/Sounds),iOS 在收到告訴後完全無法找到,它依然播放零碎默許的 default 聲響。但是將聲響文件拷貝到 App Bundle 中是可行的。因而,我們可以從 Library/Sounds 中將聲響文件再次拷貝到項目目錄中(運用 iExplorer 工具),並確保 Copy Bundle Resouces 中一定要包括這些文件。
前往目錄
46. 如何將中文轉換為拼音?以下代碼可獲取每個漢字拼音的首字母:
+(NSString *) getFirstLetter:(NSString *) strInput{
if ([strInput length]) {
NSMutableString *ms = [[NSMutableString alloc] initWithString:strInput];
// 1. kCFStringTransformMandarinLatin 表示中文轉拉丁字母,NULL 表示轉換范圍為整個字符串
CFStringTransform((__bridge CFMutableStringRef)ms, NULL, kCFStringTransformMandarinLatin, NO);
// 2. kCFStringTransformStripDiacritics,去掉音調
CFStringTransform((__bridge CFMutableStringRef)ms, 0, kCFStringTransformStripDiacritics, NO);
// 3. 轉換後果是按將個漢字的拼音以空格分隔的,我們將每個漢字的拼音按空格切開放到數組中
NSArray *pyArray = [ms componentsSeparatedByString:@" "];
if(pyArray && pyArray.count > 0){
ms = [[NSMutableString alloc] init];
// 4. 只取每個漢字的首字母
for (NSString *strTemp in pyArray) {
[ms appendString:[strTemp substringToIndex:1]];
}
return [ms uppercaseString];
}
ms = nil;
}
return nil;
}
前往目錄
47. UITextView 在 iOS 7 上文字不能頂部對齊。iOS7上UITextView在UINavigationController中垂直顯示存在問題,原本文字在textview中應該垂直頂端對齊確實好象變成底端對齊了,頂端會空出一塊。這個問題從ios7開端呈現。
處理這個問題,需求在 ViewDidLoad 辦法加上了如下代碼:
if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0){
self.automaticallyAdjustsScrollVieWinsets = NO; // Avoid the top UITextView space, iOS7 (~bug?)
}
前往目錄
48.在數組中刪除對象時出錯:“Collection was mutated while being enumerated”不能在遍歷一個 MutableArray 的進程中修正數組(包括添加、刪除、交換),以刪除為例:
for (APContact* contact in _selectedPeople) {
if (contact.recordID == person.recordID) {
[_selectedPeople removeObject:contact];
}
}
而該當修正成:
id foundObj = nil;
for (APContact* contact in _selectedPeople) {
if (contact.recordID == person.recordID) {
foundObj = contact;
}
}
if (foundObj != nil){
[_selectedPeople removeObject:foundObj];
}
或許在刪除之後立刻 break(假如一次只刪除一個對象的話):
for (APContact* contact in _selectedPeople) {
if (contact.recordID == person.recordID) {
[_selectedPeople removeObject:contact];
break;
}
}
前往目錄
49. 當我修正 cell 背風光時,AccessoryView 的背風光依然是原來的。如何讓 AccessoryView 的背風光也做異樣改動?用 cell.backgroundColor 而不是 cell.contentView.backgroundColor:
cell.backgroundColor = [UIColor colorWithWhite:0.75 alpha:0.5];
前往目錄
50. 如何運用 UISearchControlleriOS 8 中新增了 UISearchController,比 UISearchBar 的運用更復雜,更容易與 UITableView 一同運用。其運用步驟如下:
添加 UISearchController 到 ViewController 中: // Search Bar things
// self.searchController 定義是一個 UISearchController 屬性
_searchController = [[UISearchController alloc]initWithSearchResultsController:nil];// 我們預備在本 VC 中顯示搜索後果,不必在另外的 VC 中顯示後果,因而 searchResultsController 設為 nil
_searchController.searchBar.delegate = self;
_searchController.searchResultsUpdater = self;
_searchController.hidesNavigationBarDuringPresentation = YES;// 激活 searchController 時隱藏導航欄
_searchController.dimsBackgroundDuringPresentation = false;// 由於我們運用以後視圖顯示搜索後果,因而沒必要在顯示後果時將 view 調暗。
self.definesPresentationContext = true;//當用戶導航至其他 VC 且 UISearchController 為 active 時,不需求顯示 search bar。
[_searchController.searchBar sizeToFit];// 否則 searchBar 不顯示。此句需放在下一句前,否則會遮掉表格第一行
_tableView.tableHeaderView = _searchController.searchBar;// search bar 置於表頭
完成 UISearchResultsUpdating 協議
首先聲明 ViewController 完成 UISearchResultsUpdating 協議和 UISearchBarDelegate 協議
。然後完成如下辦法:
#pragma mark - UISearchResultsUpdating
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController{
NSString* searchText = searchController.searchBar.text;
if (searchText == nil) {
// If empty the search results are the same as the original data
_searchResult = _contacts;
} else {
[_searchResult removeAllObjects];
for (APContact *contact in _contacts) {
NSString* name = contact.name.compositeName;
NSString* number = contact.phones[0].number;
if ([number containsString:searchText] || [[name lowercaseString] containsString:[searchText lowercaseString]]) {
[_searchResult addObject:contact];
}
}
}
[_tableView reloadData];
}
#pragma mark - UISearchBarDelegate
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
searchBar.text = nil;
[searchBar resignFirstResponder];
[_tableView reloadData];
}
修正 numberOfRowsInSection 辦法:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (_searchController.active && !isEmpty(_searchController.searchBar.text)) {
return _searchResult.count;
}
return self.contacts.count;
}
其中,contacts 是完好列表,定義為 NSMutableArray 屬性。searchResult 是搜索後果列表,定義為 NSArray 屬性。
修正 cellForRowAtIndexPath 辦法:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"ContactCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2
reuseIdentifier:CellIdentifier];
}
APContact* person=nil;
if(_searchController.active && !isEmpty(_searchController.searchBar.text)) {
person = self.searchResult[indexPath.row];
} else {
person = self.contacts[indexPath.row];
}
cell.textLabel.text = person.name.compositeName;
cell.detailTextLabel.text = person.phones[0].number;
if ([self peopleIsSelected:person]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
假如有必要,還需求完成 didSelectRowAtIndexPath 辦法:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:NO];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
APContact* person=nil;
if(_searchController.active && !isEmpty(_searchController.searchBar.text)) {
person = self.searchResult[indexPath.row];
} else {
person = self.contacts[indexPath.row];
}
if ([self peopleIsSelected:person]) {
cell.accessoryType = UITableViewCellAccessoryNone;
[self removeSelectedPeople:person];
}else{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.selectedPeople addObject:person];
}
}
前往目錄
51.如何修正 SearchBar 的背風光?searchBar.barTintColor = [UIColor redColor];
前往目錄
用辦法把 searchBar 滾動回來:
[_tableView setContentOffset:CGPointMake(0, 0) animated:YES];
或許(假如 ViewController 有導航欄顯示的話):
// 64 = 形態欄高度+導航欄高度
[_tableView setContentOffset:CGPointMake(0, -64) animated:YES];
留意,千萬不能用
[searchBar becomeFirstResponder];
或許 :
_searchController.active = YES;
這樣會招致 searchBar 消逝不見!
前往目錄
barTintColor 是一個比擬特殊的屬性,無法以 UIView 動畫或 CA 動畫的方式使其改動。我們只能用一個循環自己計算 barTintColor 在一定時間內每個突變顏色值,並在一定時間內循環使用這些顏色值來構成動畫:
void blinkSearchBar(UISearchBar* searchBar ,UIColor* distinctColor,NSTimeInterval seconds){
UIColor* oldColor = searchBar.barTintColor == nil ? [UIColor colorWithHex:0xbdbdc3 alpha:1] : searchBar.barTintColor;
// 去除下方細線
searchBar.layer.borderWidth = 1;
searchBar.layer.borderColor = [[UIColor lightGrayColor] CGColor];
double rate = 20;
for (int i=0; i<rate; i++) {
if(i == rate-1){// 最後一次過渡
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(i*(1/rate)*seconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
searchBar.barTintColor = oldColor;
});
}else{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(i*(1/rate)*seconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 依據 alpha 交融 distinctColor 和 oldColor,oldColor 所占比例會逐步增大直至 1,distinctColor 所占比例逐步增加直至 0
UIColor* blendColor = [distinctColor alphaBlendWithColor:oldColor alpha:i*(1/rate)];
searchBar.barTintColor = blendColor;
});
}
}
}
其中,alphaBlendWithColor 辦法用於計算突變色(經過按 alpha 比例逐漸增加初值、添加終值來交融新顏色),它的定義如下:
@implementation UIColor (AlphaBlend)
- (UIColor *)alphaBlendWithColor:(UIColor *)blendColor alpha:(CGFloat)alpha
{
CGFloat redComponent;
CGFloat greenComponent;
CGFloat blueComponent;
[self getRed:&redComponent green:&greenComponent blue:&blueComponent alpha:nil];
CGFloat blendColorRedComponent;
CGFloat blendColorGreenComponent;
CGFloat blendColorBlueComponent;
[blendColor getRed:&blendColorRedComponent green:&blendColorGreenComponent blue:&blendColorBlueComponent alpha:nil];
CGFloat blendedRedComponent = ((blendColorRedComponent - redComponent) * alpha + redComponent);
CGFloat blendedGreenComponent = ((blendColorGreenComponent - greenComponent) * alpha + greenComponent);
CGFloat blendedBlueComponent = ((blendColorBlueComponent - blueComponent) * alpha + blueComponent);
return [UIColor colorWithRed:blendedRedComponent green:blendedGreenComponent blue:blendedBlueComponent alpha:1.0f];
}
@end
前往目錄
54. 如何去掉 UISearchBar 下方的細線?UISearchBar 下方細線如下圖所示:
運用如下代碼去除它:
sBar.layer.borderWidth = 1;
sBar.layer.borderColor = [[UIColor lightGrayColor] CGColor];
前往目錄
55. 如何傳遞參數給一個 Container View Controller?首先,在故事板中,將 Container View 和子 View Controller 之間的 segue 指定一個 Identifier,比方 “embed_controller”。然後在這個 View Controller(父 VC)中完成 prepareForSegue 辦法:
if segue.identifier == "emded_controller"{
let vc = segue.destinationViewController as! SafetyVerificationEmbedController
vc.phoneCode = phoneCode // 將 phoneCode 傳遞給子 View Controller
}
前往目錄
【iOS 開提問與答(39】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!