你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS 開提問與答(39

iOS 開提問與答(39

編輯:IOS開發綜合

目錄

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;

iOS 開發問與答(39

辦法二.
1)、在項目的info.plist中添加一個Key:NSAppTransportSecurity,類型為字典類型。

2)、然後給它添加一個NSExceptionDomains,類型為字典類型;

3)、把需求的支持的域添加給NSExceptionDomains。其中域作為Key,類型為字典類型。

4)、每個域上面需求設置3個屬性:NSIncludesSubdomains、NSExceptionRequiresForwardSecrecy、NSExceptionAllowsInsecureHTTPLoads。

均為Boolean類型,值辨別為YES、NO、YES。

iOS 開發問與答(39

前往目錄

41.當收到推送告訴時, didReceiveRemoteNotification 辦法不調用

在完成推送告訴時,完成了 didReceiveRemoteNotification 和 didReceiveRemoteNotification:fetchCompletionHandler 辦法,但這些辦法只會在 App 從後台被喚醒時觸發。也就說當 Push 告訴抵達,用戶從告訴中心點擊音訊,零碎喚醒 App 後才會觸發這些辦法。

假如想在 App 處於後台時就調用這些辦法,需求運用“靜默的推送告訴”:

翻開後台運轉選項中的 Remote notifications:

iOS 開發問與答(39

在告訴載體中添加 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”,播放零碎默許的聲響。
前往目錄

44.如何在音訊載體中指定自定義的聲響?
{"aps":{"alert":"Hello from APNs Tester.","badge":1,"sound":"alarm"}}

其中 alarm 是聲響文件的文件名(不需求擴展名)。聲響文件必需位於 bundle 或許 Library/Sounds 目錄,文件類型必需是 aiff, wav, 或 caf。假如指定的文件不存在,零碎用默許聲響(default)替代。
前往目錄

45.如何讀取零碎聲響?

零碎聲響放在了 /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開端呈現。

iOS 開發問與答(39

處理這個問題,需求在 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. 如何運用 UISearchController

iOS 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];
前往目錄

52.當TableView 滾動後,直到 searBar 不可見,如何再次讓 searchBar 可見?

用辦法把 searchBar 滾動回來:

[_tableView setContentOffset:CGPointMake(0, 0) animated:YES];

或許(假如 ViewController 有導航欄顯示的話):

// 64 = 形態欄高度+導航欄高度
[_tableView setContentOffset:CGPointMake(0, -64) animated:YES];

留意,千萬不能用

 [searchBar becomeFirstResponder];

或許 :

_searchController.active = YES;

這樣會招致 searchBar 消逝不見!
前往目錄

53. 如何以動畫方式改動UISearchBar 的 barTintColor?

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 下方細線如下圖所示:

iOS 開發問與答(39

運用如下代碼去除它:

 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】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved